From 7b739920a24aadfcf60bcec56e95a853fa812aa1 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 17 Dec 2020 13:18:40 +0100 Subject: [PATCH 01/28] NEW : Workstations management --- htdocs/admin/workstation.php | 513 ++++++++ htdocs/core/modules/modWorkstation.class.php | 522 ++++++++ .../workstation/mod_workstation_advanced.php | 150 +++ .../workstation/mod_workstation_standard.php | 151 +++ .../workstation/modules_workstation.php | 150 +++ htdocs/core/tpl/commonfields_add.tpl.php | 1 + htdocs/core/tpl/commonfields_edit.tpl.php | 1 + .../install/mysql/migration/13.0.0-14.0.0.sql | 40 + .../llx_workstation_workstation.key.sql | 27 + .../tables/llx_workstation_workstation.sql | 36 + .../llx_workstation_workstation_resource.sql | 22 + ...llx_workstation_workstation_user_group.sql | 22 + htdocs/langs/en_US/mrp.lang | 26 +- .../class/html.formresource.class.php | 8 +- .../workstation/class/workstation.class.php | 1054 +++++++++++++++++ .../class/workstation.class.php.back | 1052 ++++++++++++++++ .../class/workstationresource.class.php | 82 ++ .../class/workstationusergroup.class.php | 82 ++ htdocs/workstation/lib/workstation.lib.php | 65 + .../lib/workstation_workstation.lib.php | 85 ++ htdocs/workstation/workstation_agenda.php | 276 +++++ htdocs/workstation/workstation_card.php | 511 ++++++++ htdocs/workstation/workstation_document.php | 228 ++++ htdocs/workstation/workstation_list.php | 601 ++++++++++ htdocs/workstation/workstation_note.php | 183 +++ 25 files changed, 5884 insertions(+), 4 deletions(-) create mode 100755 htdocs/admin/workstation.php create mode 100755 htdocs/core/modules/modWorkstation.class.php create mode 100755 htdocs/core/modules/workstation/mod_workstation_advanced.php create mode 100755 htdocs/core/modules/workstation/mod_workstation_standard.php create mode 100755 htdocs/core/modules/workstation/modules_workstation.php create mode 100644 htdocs/install/mysql/migration/13.0.0-14.0.0.sql create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation.key.sql create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation.sql create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql create mode 100755 htdocs/workstation/class/workstation.class.php create mode 100755 htdocs/workstation/class/workstation.class.php.back create mode 100644 htdocs/workstation/class/workstationresource.class.php create mode 100644 htdocs/workstation/class/workstationusergroup.class.php create mode 100755 htdocs/workstation/lib/workstation.lib.php create mode 100755 htdocs/workstation/lib/workstation_workstation.lib.php create mode 100755 htdocs/workstation/workstation_agenda.php create mode 100755 htdocs/workstation/workstation_card.php create mode 100755 htdocs/workstation/workstation_document.php create mode 100755 htdocs/workstation/workstation_list.php create mode 100755 htdocs/workstation/workstation_note.php diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php new file mode 100755 index 00000000000..8f9ee369d4f --- /dev/null +++ b/htdocs/admin/workstation.php @@ -0,0 +1,513 @@ + + * Copyright (C) 2020 SuperAdmin + * + * 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 workstation/admin/setup.php + * \ingroup workstation + * \brief Workstation setup page. + */ + +// Load Dolibarr environment +require "../main.inc.php"; + +// Libraries +require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php"; +require_once DOL_DOCUMENT_ROOT . '/workstation/lib/workstation.lib.php'; +//require_once "../class/myclass.class.php"; + +// Translations +$langs->loadLangs(array("admin", "workstation@workstation")); + +// Access control +if (!$user->admin) accessforbidden(); + +// Parameters +$action = GETPOST('action', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$value = GETPOST('value', 'alpha'); + +/*$arrayofparameters = array( + 'WORKSTATION_MYPARAM1'=>array('css'=>'minwidth200', 'enabled'=>1), + 'WORKSTATION_MYPARAM2'=>array('css'=>'minwidth500', 'enabled'=>1) +);*/ + +$error = 0; +$setupnotempty = 0; + + +/* + * Actions + */ + +if ((float) DOL_VERSION >= 6) +{ + include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +} + +if ($action == 'updateMask') +{ + $maskconstorder = GETPOST('maskconstWorkstation', 'alpha'); + $maskorder = GETPOST('maskWorkstation', 'alpha'); + + if ($maskconstorder) $res = dolibarr_set_const($db, $maskconstorder, $maskorder, 'chaine', 0, '', $conf->entity); + + if (!$res > 0) $error++; + + if (!$error) + { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} elseif ($action == 'specimen') +{ + $modele = GETPOST('module', 'alpha'); + $tmpobjectkey = GETPOST('object'); + + $tmpobject = new $tmpobjectkey($db); + $tmpobject->initAsSpecimen(); + + // Search template files + $file = ''; $classname = ''; $filefound = 0; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $file = dol_buildpath($reldir."core/modules/workstation/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0); + if (file_exists($file)) + { + $filefound = 1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) + { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($tmpobject, $langs) > 0) + { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); + return; + } else { + setEventMessages($module->error, null, 'errors'); + dol_syslog($module->error, LOG_ERR); + } + } else { + setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} + +// Activate a model +elseif ($action == 'set') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); +} elseif ($action == 'del') +{ + $tmpobjectkey = GETPOST('object'); + + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; + if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity); + } +} + +// Set default model +elseif ($action == 'setdoc') +{ + $tmpobjectkey = GETPOST('object'); + $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; + if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) + { + // The constant that was read before the new set + // We therefore requires a variable to have a coherent view + $conf->global->$constforval = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } +} elseif ($action == 'setmod') +{ + // TODO Check if numbering module chosen can be activated + // by calling method canBeActivated + $tmpobjectkey = GETPOST('object'); + $constforval = 'WORKSTATION_'.strtoupper($tmpobjectkey)."_ADDON"; + dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity); +} + + + +/* + * View + */ + +$form = new Form($db); + +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + +$page_name = "WorkstationSetup"; +llxHeader('', $langs->trans($page_name)); + +// Subheader +$linkback = ''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans($page_name), $linkback, 'object_workstation@workstation'); + +// Configuration header +$head = workstationAdminPrepareHead(); +print dol_get_fiche_head($head, 'settings', '', -1, "workstation@workstation"); + +// Setup page goes here +//echo ''.$langs->trans("WorkstationSetupPage").'

'; + + +if ($action == 'edit') +{ + print '
'; + print ''; + print ''; + + print ''; + print ''; + + foreach ($arrayofparameters as $key => $val) + { + print ''; + } + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print '
'; + + print '
'; + print ''; + print '
'; + + print '
'; + print '
'; +} else { + if (!empty($arrayofparameters)) + { + print ''; + print ''; + + foreach ($arrayofparameters as $key => $val) + { + $setupnotempty++; + + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print ''.$conf->global->$key.'
'; + + print '
'; + print ''.$langs->trans("Modify").''; + print '
'; + }/* else { + print '
'.$langs->trans("NothingToSetup"); + }*/ +} + + +$moduledir = 'workstation'; +$myTmpObjects = array(); +$myTmpObjects['workstation'] = array('includerefgeneration'=>1, 'includedocgeneration'=>0); + + +foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { + if ($myTmpObjectKey == 'MyObject') continue; + if ($myTmpObjectArray['includerefgeneration']) { + /* + * Orders Numbering model + */ + $setupnotempty++; + + print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', ''); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/".$moduledir); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle)) !== false) + { + if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') + { + $file = substr($file, 0, dol_strlen($file) - 4); + + require_once $dir.'/'.$file.'.php'; + + $module = new $file($db); + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + if ($module->isEnabled()) + { + dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php'); + + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $mytmpinstance = new $myTmpObjectKey($db); + $mytmpinstance->initAsSpecimen(); + + // Info + $htmltooltip = ''; + $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; + + $nextval = $module->getNextValue($mytmpinstance); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip .= ''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip .= $nextval.'
'; + } else { + $htmltooltip .= $langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } + } + print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + print ''; + $tmp = $module->getExample(); + if (preg_match('/^Error/', $tmp)) { + $langs->load("errors"); + print '
'.$langs->trans($tmp).'
'; + } elseif ($tmp == 'NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON'; + if ($conf->global->$constforvar == $file) + { + print img_picto($langs->trans("Activated"), 'switch_on'); + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print '

\n"; + } + + if ($myTmpObjectArray['includedocgeneration']) { + /* + * Document templates generators + */ + $setupnotempty++; + $type = strtolower($myTmpObjectKey); + + print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', ''); + + // Load array def with activated templates + $def = array(); + $sql = "SELECT nom"; + $sql .= " FROM ".MAIN_DB_PREFIX."document_model"; + $sql .= " WHERE type = '".$db->escape($type)."'"; + $sql .= " AND entity = ".$conf->entity; + $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($def, $array[0]); + $i++; + } + } else { + dol_print_error($db); + } + + print "\n"; + print "\n"; + print ''; + print ''; + print '\n"; + print '\n"; + print ''; + print ''; + print "\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) + { + foreach (array('', '/doc') as $valdir) + { + $realpath = $reldir."core/modules/".$moduledir.$valdir; + $dir = dol_buildpath($realpath); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle)) !== false) + { + $filelist[] = $file; + } + closedir($handle); + arsort($filelist); + + foreach ($filelist as $file) + { + if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) + { + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) - 16); + $classname = substr($file, 0, dol_strlen($file) - 12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified = 1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified = 0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0; + + if ($modulequalified) + { + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } else { + print '"; + } + + // Default + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip .= '
'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file; + + $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); + $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } + } + + print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name) ? $name : $module->name); + print "\n"; + if (method_exists($module, 'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"), 'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print "'; + $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON'; + if ($conf->global->$constforvar == $name) + { + print img_picto($langs->trans("Default"), 'on'); + } else { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"), 'generic').''; + } else { + print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + } + print '
'; + } +} + +/*if (empty($setupnotempty)) { + print '
'.$langs->trans("NothingToSetup"); +}*/ + +// Page end +print dol_get_fiche_end(); + +llxFooter(); +$db->close(); diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php new file mode 100755 index 00000000000..216d591670a --- /dev/null +++ b/htdocs/core/modules/modWorkstation.class.php @@ -0,0 +1,522 @@ + + * Copyright (C) 2018-2019 Nicolas ZABOURI + * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2020 SuperAdmin + * + * 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 . + */ + +/** + * \defgroup workstation Module Workstation + * \brief Workstation module descriptor. + * + * \file htdocs/workstation/core/modules/modWorkstation.class.php + * \ingroup workstation + * \brief Description and activation file for module Workstation + */ +include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; + +/** + * Description and activation class for module Workstation + */ +class modWorkstation extends DolibarrModules +{ + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $langs, $conf; + $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 = 500000; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve an id number for your module + // Key text used to identify module (for permissions, menus, etc...) + $this->rights_class = 'workstation'; + // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...' + // It is used to group modules by family in module setup page + $this->family = "other"; + // Module position in the family on 2 digits ('01', '10', '20', ...) + $this->module_position = '90'; + // Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this) + //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily"))); + // Module label (no space allowed), used if translation string 'ModuleWorkstationName' not found (Workstation is name of module). + $this->name = preg_replace('/^mod/i', '', get_class($this)); + // Module description, used if translation string 'ModuleWorkstationDesc' not found (Workstation is name of module). + $this->description = "WorkstationsDescription"; + // Used only if file README.md and README-LL.md not found. + $this->descriptionlong = "Workstation description (Long)"; + $this->editor_name = 'Editor name'; + $this->editor_url = 'https://www.example.com'; + // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' + $this->version = '1.0'; + // Url to the file with your last numberversion of this module + //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; + + // Key used in llx_const table to save module status enabled/disabled (where WORKSTATION is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Name of image file used for this module. + // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' + // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' + $this->picto = 'mrp'; + // Define some features supported by module (triggers, login, substitutions, menus, css, etc...) + $this->module_parts = array( + // Set this to 1 if module has its own trigger directory (core/triggers) + 'triggers' => 0, + // Set this to 1 if module has its own login method file (core/login) + 'login' => 0, + // Set this to 1 if module has its own substitution function file (core/substitutions) + 'substitutions' => 0, + // Set this to 1 if module has its own menus handler directory (core/menus) + 'menus' => 0, + // Set this to 1 if module overwrite template dir (core/tpl) + 'tpl' => 0, + // Set this to 1 if module has its own barcode directory (core/modules/barcode) + 'barcode' => 0, + // Set this to 1 if module has its own models directory (core/modules/xxx) + 'models' => 1, + // Set this to 1 if module has its own printing directory (core/modules/printing) + 'printing' => 0, + // Set this to 1 if module has its own theme directory (theme) + 'theme' => 0, + // Set this to relative path of css file if module has its own css file + 'css' => array( + // '/workstation/css/workstation.css.php', + ), + // Set this to relative path of js file if module must load a js on all pages + 'js' => array( + // '/workstation/js/workstation.js.php', + ), + // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context to 'all' + 'hooks' => array( + // 'data' => array( + // 'hookcontext1', + // 'hookcontext2', + // ), + // 'entity' => '0', + ), + // Set this to 1 if features of module are opened to external users + 'moduleforexternal' => 0, + ); + // Data directories to create when module is enabled. + // Example: this->dirs = array("/workstation/temp","/workstation/subdir"); + $this->dirs = array("/workstation/temp"); + // Config pages. Put here list of php page, stored into workstation/admin directory, to use to setup module. + $this->config_page_url = array("workstation.php"); + // Dependencies + // A condition to hide module + $this->hidden = false; + // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + $this->depends = array(); + $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) + $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) + $this->langfiles = array("mrp"); + $this->phpmin = array(5, 5); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(11, -3); // Minimum version of Dolibarr required by module + $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...) + $this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...) + //$this->automatic_activation = array('FR'=>'WorkstationWasAutomaticallyActivatedBecauseOfYourCountryChoice'); + //$this->always_enabled = true; // If true, can't be disabled + + // Constants + // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive) + // Example: $this->const=array(1 => array('WORKSTATION_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1), + // 2 => array('WORKSTATION_MYNEWCONST2', 'chaine', 'myvalue', 'This is another constant to add', 0, 'current', 1) + // ); + $this->const = array(); + + // Some keys to add into the overwriting translation tables + /*$this->overwrite_translation = array( + 'en_US:ParentCompany'=>'Parent company or reseller', + 'fr_FR:ParentCompany'=>'Maison mère ou revendeur' + )*/ + + if (!isset($conf->workstation) || !isset($conf->workstation->enabled)) { + $conf->workstation = new stdClass(); + $conf->workstation->enabled = 0; + } + + // Array to add new pages in new tabs + $this->tabs = array(); + // Example: + // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@workstation:$user->rights->workstation->read:/workstation/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1 + // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@workstation:$user->rights->othermodule->read:/workstation/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key. + // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname + // + // Where objecttype can be + // 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member) + // 'contact' to add a tab in contact view + // 'contract' to add a tab in contract view + // 'group' to add a tab in group view + // 'intervention' to add a tab in intervention view + // 'invoice' to add a tab in customer invoice view + // 'invoice_supplier' to add a tab in supplier invoice view + // 'member' to add a tab in fundation member view + // 'opensurveypoll' to add a tab in opensurvey poll view + // 'order' to add a tab in customer order view + // 'order_supplier' to add a tab in supplier order view + // 'payment' to add a tab in payment view + // 'payment_supplier' to add a tab in supplier payment view + // 'product' to add a tab in product view + // 'propal' to add a tab in propal view + // 'project' to add a tab in project view + // 'stock' to add a tab in stock view + // 'thirdparty' to add a tab in third party view + // 'user' to add a tab in user view + + // Dictionaries + $this->dictionaries = array(); + /* Example: + $this->dictionaries=array( + 'langs'=>'workstation@workstation', + // List of tables we want to see into dictonnary editor + 'tabname'=>array(MAIN_DB_PREFIX."table1", MAIN_DB_PREFIX."table2", MAIN_DB_PREFIX."table3"), + // Label of tables + 'tablib'=>array("Table1", "Table2", "Table3"), + // Request to select fields + 'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'), + // Sort order + 'tabsqlsort'=>array("label ASC", "label ASC", "label ASC"), + // List of fields (result of select to show dictionary) + 'tabfield'=>array("code,label", "code,label", "code,label"), + // List of fields (list of fields to edit a record) + 'tabfieldvalue'=>array("code,label", "code,label", "code,label"), + // List of fields (list of fields for insert) + 'tabfieldinsert'=>array("code,label", "code,label", "code,label"), + // Name of columns with primary key (try to always name it 'rowid') + 'tabrowid'=>array("rowid", "rowid", "rowid"), + // Condition to show each dictionary + 'tabcond'=>array($conf->workstation->enabled, $conf->workstation->enabled, $conf->workstation->enabled) + ); + */ + + // Boxes/Widgets + // Add here list of php file(s) stored in workstation/core/boxes that contains a class to show a widget. + $this->boxes = array( + // 0 => array( + // 'file' => 'workstationwidget1.php@workstation', + // 'note' => 'Widget provided by Workstation', + // 'enabledbydefaulton' => 'Home', + // ), + // ... + ); + + // Cronjobs (List of cron jobs entries to add when module is enabled) + // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week + $this->cronjobs = array( + // 0 => array( + // 'label' => 'MyJob label', + // 'jobtype' => 'method', + // 'class' => '/workstation/class/workstation.class.php', + // 'objectname' => 'Workstation', + // 'method' => 'doScheduledJob', + // 'parameters' => '', + // 'comment' => 'Comment', + // 'frequency' => 2, + // 'unitfrequency' => 3600, + // 'status' => 0, + // 'test' => '$conf->workstation->enabled', + // 'priority' => 50, + // ), + ); + // Example: $this->cronjobs=array( + // 0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->workstation->enabled', 'priority'=>50), + // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->workstation->enabled', 'priority'=>50) + // ); + + // Permissions provided by this module + $this->rights = array(); + $r = 0; + // Add here entries to declare new permissions + /* BEGIN MODULEBUILDER PERMISSIONS */ + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Read objects of Workstation'; // Permission label + $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2) + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2) + $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Create/Update objects of Workstation'; // Permission label + $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2) + $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2) + $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Delete objects of Workstation'; // Permission label + $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2) + $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2) + $r++; + /* END MODULEBUILDER PERMISSIONS */ + + // Main menu entries to add + $this->menu = array(); + $r = 0; + // Add here entries to declare new menus + /* BEGIN MODULEBUILDER TOPMENU */ + /*$this->menu[$r++] = array( + 'fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'top', // This is a Top menu entry + 'titre'=>$langs->trans('GPAO'), + 'mainmenu'=>'gpao', + 'leftmenu'=>'', + 'url'=>'/workstation/workstationindex.php', + 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000 + $r, + 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->workstation->workstation->read' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both + );*/ + /* END MODULEBUILDER TOPMENU */ + /* BEGIN MODULEBUILDER LEFTMENU WORKSTATION + $this->menu[$r++]=array( + 'fk_menu'=>'fk_mainmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', // This is a Top menu entry + 'titre'=>'Workstation', + 'mainmenu'=>'workstation', + 'leftmenu'=>'workstation', + 'url'=>'/workstation/workstationindex.php', + 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000+$r, + 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. + 'perms'=>'$user->rights->workstation->workstation->read', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both + ); + $this->menu[$r++]=array( + 'fk_menu'=>'fk_mainmenu=workstation,fk_leftmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', // This is a Left menu entry + 'titre'=>'List_Workstation', + 'mainmenu'=>'workstation', + 'leftmenu'=>'workstation_workstation_list', + 'url'=>'/workstation/workstation_list.php', + 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000+$r, + 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'$user->rights->workstation->workstation->read', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both + ); + $this->menu[$r++]=array( + 'fk_menu'=>'fk_mainmenu=workstation,fk_leftmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', // This is a Left menu entry + 'titre'=>'New_Workstation', + 'mainmenu'=>'workstation', + 'leftmenu'=>'workstation_workstation_new', + 'url'=>'/workstation/workstation_card.php?action=create', + 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000+$r, + 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'$user->rights->workstation->workstation->write', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both + ); + */ + + $this->menu[$r++]=array( + // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'fk_menu'=>'fk_mainmenu=mrp', + // This is a Left menu entry + 'type'=>'left', + 'titre'=>$langs->trans('Workstations'), + 'mainmenu'=>'mrp', + 'leftmenu'=>'workstation_workstation', + 'url'=>'', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'mrp', + 'position'=>1100+$r, + // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->workstation->enabled', + // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules + 'perms'=>'$user->rights->workstation->workstation->read', + 'target'=>'', + // 0=Menu for internal users, 1=external users, 2=both + 'user'=>2, + ); + $this->menu[$r++]=array( + // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'fk_menu'=>'fk_mainmenu=mrp,fk_leftmenu=workstation_workstation', + // This is a Left menu entry + 'type'=>'left', + 'titre'=>$langs->trans('WorkstationCreate'), + 'mainmenu'=>'mrp', + 'leftmenu'=>'workstation_workstation_left_create', + 'url'=>'/workstation/workstation_card.php?action=create', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'mrp', + 'position'=>1100+$r, + // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->workstation->enabled', + // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules + 'perms'=>'$user->rights->workstation->workstation->write', + 'target'=>'', + // 0=Menu for internal users, 1=external users, 2=both + 'user'=>2 + ); + $this->menu[$r++]=array( + // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'fk_menu'=>'fk_mainmenu=mrp,fk_leftmenu=workstation_workstation', + // This is a Left menu entry + 'type'=>'left', + 'titre'=>$langs->trans('List'), + 'mainmenu'=>'mrp', + 'leftmenu'=>'workstation_workstation_left_list', + 'url'=>'/workstation/workstation_list.php', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'mrp', + 'position'=>1101+$r, + // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->workstation->enabled', + // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules + 'perms'=>'$user->rights->workstation->workstation->read', + 'target'=>'', + // 0=Menu for internal users, 1=external users, 2=both + 'user'=>2 + ); + + /* END MODULEBUILDER LEFTMENU WORKSTATION */ + // Exports profiles provided by this module + $r = 1; + /* BEGIN MODULEBUILDER EXPORT WORKSTATION */ + /* + $langs->load("workstation@workstation"); + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]='WorkstationLines'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r]='workstation@workstation'; + // Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array + $keyforclass = 'Workstation'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstation@workstation'; + include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + //$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text'; + //unset($this->export_fields_array[$r]['t.fieldtoremove']); + //$keyforclass = 'WorkstationLine'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstationline@workstation'; $keyforalias='tl'; + //include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + $keyforselect='workstation'; $keyforaliasextra='extra'; $keyforelement='workstation@workstation'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$keyforselect='workstationline'; $keyforaliasextra='extraline'; $keyforelement='workstationline@workstation'; + //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$this->export_dependencies_array[$r] = array('workstationline'=>array('tl.rowid','tl.ref')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) + //$this->export_special_array[$r] = array('t.field'=>'...'); + //$this->export_examplevalues_array[$r] = array('t.field'=>'Example'); + //$this->export_help_array[$r] = array('t.field'=>'FieldDescHelp'); + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'workstation as t'; + //$this->export_sql_end[$r] =' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_line as tl ON tl.fk_workstation = t.rowid'; + $this->export_sql_end[$r] .=' WHERE 1 = 1'; + $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('workstation').')'; + $r++; */ + /* END MODULEBUILDER EXPORT WORKSTATION */ + + // Imports profiles provided by this module + $r = 1; + /* BEGIN MODULEBUILDER IMPORT WORKSTATION */ + /* + $langs->load("workstation@workstation"); + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]='WorkstationLines'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r]='workstation@workstation'; + $keyforclass = 'Workstation'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstation@workstation'; + include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + $keyforselect='workstation'; $keyforaliasextra='extra'; $keyforelement='workstation@workstation'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'workstation as t'; + $this->export_sql_end[$r] .=' WHERE 1 = 1'; + $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('workstation').')'; + $r++; */ + /* END MODULEBUILDER IMPORT WORKSTATION */ + } + + /** + * 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 ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + public function init($options = '') + { + global $conf, $langs; + + $result = $this->_load_tables('/workstation/sql/'); + if ($result < 0) return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') + + // Create extrafields during init + //include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + //$extrafields = new ExtraFields($this->db); + //$result1=$extrafields->addExtraField('workstation_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled'); + //$result2=$extrafields->addExtraField('workstation_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled'); + //$result3=$extrafields->addExtraField('workstation_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled'); + //$result4=$extrafields->addExtraField('workstation_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled'); + //$result5=$extrafields->addExtraField('workstation_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled'); + + // Permissions + $this->remove($options); + + $sql = array(); + + // Document templates + $moduledir = 'workstation'; + $myTmpObjects = array(); + $myTmpObjects['Workstation'] = array('includerefgeneration'=>0, 'includedocgeneration'=>0); + + foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { + if ($myTmpObjectKey == 'Workstation') continue; + if ($myTmpObjectArray['includerefgeneration']) { + $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/workstation/template_workstations.odt'; + $dirodt = DOL_DATA_ROOT.'/doctemplates/workstation'; + $dest = $dirodt.'/template_workstations.odt'; + + if (file_exists($src) && !file_exists($dest)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + dol_mkdir($dirodt); + $result = dol_copy($src, $dest, 0, 0); + if ($result < 0) + { + $langs->load("errors"); + $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest); + return 0; + } + } + + $sql = array_merge($sql, array( + "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'standard_".strtolower($myTmpObjectKey)."' AND type = '".strtolower($myTmpObjectKey)."' AND entity = ".$conf->entity, + "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('standard_".strtolower($myTmpObjectKey)."','".strtolower($myTmpObjectKey)."',".$conf->entity.")", + "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'generic_".strtolower($myTmpObjectKey)."_odt' AND type = '".strtolower($myTmpObjectKey)."' AND entity = ".$conf->entity, + "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('generic_".strtolower($myTmpObjectKey)."_odt', '".strtolower($myTmpObjectKey)."', ".$conf->entity.")" + )); + } + } + + 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 + */ + public function remove($options = '') + { + $sql = array(); + return $this->_remove($sql, $options); + } +} diff --git a/htdocs/core/modules/workstation/mod_workstation_advanced.php b/htdocs/core/modules/workstation/mod_workstation_advanced.php new file mode 100755 index 00000000000..d9133b4063c --- /dev/null +++ b/htdocs/core/modules/workstation/mod_workstation_advanced.php @@ -0,0 +1,150 @@ + + * Copyright (C) 2004-2007 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2019 Frédéric France + * + * 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 https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/workstation/mod_workstation_advanced.php + * \ingroup workstation + * \brief File containing class for advanced numbering model of Workstation + */ + +require_once DOL_DOCUMENT_ROOT . '/core/modules/workstation/modules_workstation.php'; + + +/** + * Class to manage customer Bom numbering rules advanced + */ +class mod_workstation_advanced extends ModeleNumRefWorkstation +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + /** + * @var string Error message + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'advanced'; + + + /** + * Returns the description of the numbering model + * + * @return string Texte descripif + */ + public function info() + { + global $conf, $langs, $db; + + $langs->load("bills"); + + $form = new Form($db); + + $texte = $langs->trans('GenericNumRefModelDesc')."
\n"; + $texte .= '
'; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= ''; + + $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Workstation"), $langs->transnoentities("Workstation")); + $tooltip .= $langs->trans("GenericMaskCodes2"); + $tooltip .= $langs->trans("GenericMaskCodes3"); + $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("Workstation"), $langs->transnoentities("Workstation")); + $tooltip .= $langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte .= ''; + $texte .= ''; + + $texte .= ''; + + $texte .= ''; + + $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).' 
'; + $texte .= '
'; + + return $texte; + } + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $conf, $db, $langs, $mysoc; + + $object = new Workstation($db); + $object->initAsSpecimen(); + + /*$old_code_client = $mysoc->code_client; + $old_code_type = $mysoc->typent_code; + $mysoc->code_client = 'CCCCCCCCCC'; + $mysoc->typent_code = 'TTTTTTTTTT';*/ + + $numExample = $this->getNextValue($object); + + /*$mysoc->code_client = $old_code_client; + $mysoc->typent_code = $old_code_type;*/ + + if (!$numExample) + { + $numExample = $langs->trans('NotConfigured'); + } + return $numExample; + } + + /** + * Return next free value + * + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($object) + { + global $db, $conf; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + + // We get cursor rule + $mask = $conf->global->WORKSTATION_WORKSTATION_ADVANCED_MASK; + + if (!$mask) + { + $this->error = 'NotConfigured'; + return 0; + } + + $date = $object->date; + + $numFinal = get_next_value($db, $mask, 'workstation_workstation', 'ref', '', null, $date); + + return $numFinal; + } +} diff --git a/htdocs/core/modules/workstation/mod_workstation_standard.php b/htdocs/core/modules/workstation/mod_workstation_standard.php new file mode 100755 index 00000000000..87e94233c88 --- /dev/null +++ b/htdocs/core/modules/workstation/mod_workstation_standard.php @@ -0,0 +1,151 @@ + + * Copyright (C) 2005-2009 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 https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/workstation/mod_workstation_standard.php + * \ingroup workstation + * \brief File of class to manage Workstation numbering rules standard + */ +require_once DOL_DOCUMENT_ROOT . '/core/modules/workstation/modules_workstation.php'; + +/** + * Class to manage customer order numbering rules standard + */ +class mod_workstation_standard extends ModeleNumRefWorkstation +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + public $prefix = 'WORKSTATION'; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'standard'; + + + /** + * Return description of numbering module + * + * @return string Text with description + */ + public function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc", $this->prefix); + } + + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @param Object $object Object we need next value for + * @return boolean false if conflict, true if ok + */ + public function canBeActivated($object) + { + global $conf, $langs, $db; + + $coyymm = ''; $max = ''; + + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."workstation_workstation"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + if ($object->ismultientitymanaged == 1) { + $sql .= " AND entity = ".$conf->entity; + } elseif ($object->ismultientitymanaged == 2) { + // TODO + } + + $resql = $db->query($sql); + if ($resql) + { + $row = $db->fetch_row($resql); + if ($row) { $coyymm = substr($row[0], 0, 6); $max = $row[0]; } + } + if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm)) + { + $langs->load("errors"); + $this->error = $langs->trans('ErrorNumRefModel', $max); + return false; + } + + return true; + } + + /** + * Return next free value + * + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($object) + { + global $db, $conf; + + // First we get the max value + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."workstation_workstation"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + //$sql .= " AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + if ($obj) $max = intval($obj->max); + else $max = 0; + } else { + dol_syslog("mod_workstation_standard::getNextValue", LOG_DEBUG); + return -1; + } + + //$date=time(); + $date = dol_now(); + $yymm = strftime("%y%m", $date); + + if ($max >= (pow(10, 4) - 1)) $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is + else $num = sprintf("%04s", $max + 1); + + dol_syslog("mod_workstation_standard::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } +} diff --git a/htdocs/core/modules/workstation/modules_workstation.php b/htdocs/core/modules/workstation/modules_workstation.php new file mode 100755 index 00000000000..bfd0f6c95ea --- /dev/null +++ b/htdocs/core/modules/workstation/modules_workstation.php @@ -0,0 +1,150 @@ + + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2014 Marcos García + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/workstation/modules_workstation.php + * \ingroup workstation + * \brief File that contains parent class for workstations document models and parent class for workstations numbering models + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // required for use by classes that inherit + + +/** + * Parent class for documents models + */ +abstract class ModelePDFWorkstation extends CommonDocGenerator +{ + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + public static function liste_modeles($db, $maxfilenamelength = 0) + { + // phpcs:enable + global $conf; + + $type = 'workstation'; + $list = array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $list = getListOfModels($db, $type, $maxfilenamelength); + + return $list; + } +} + + + +/** + * Parent class to manage numbering of Workstation + */ +abstract class ModeleNumRefWorkstation +{ + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * Return if a module can be used or not + * + * @return boolean true if module can be used + */ + public function isEnabled() + { + return true; + } + + /** + * Returns the default description of the numbering template + * + * @return string Texte descripif + */ + public function info() + { + global $langs; + $langs->load("workstation@workstation"); + return $langs->trans("NoDescription"); + } + + /** + * Returns an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $langs; + $langs->load("workstation@workstation"); + return $langs->trans("NoExample"); + } + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @param Object $object Object we need next value for + * @return boolean false if conflict, true if ok + */ + public function canBeActivated($object) + { + return true; + } + + /** + * Returns next assigned value + * + * @param Object $object Object we need next value for + * @return string Valeur + */ + public function getNextValue($object) + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * Returns version of numbering module + * + * @return string Valeur + */ + public function getVersion() + { + global $langs; + $langs->load("admin"); + + if ($this->version == 'development') return $langs->trans("VersionDevelopment"); + if ($this->version == 'experimental') return $langs->trans("VersionExperimental"); + if ($this->version == 'dolibarr') return DOL_VERSION; + if ($this->version) return $this->version; + return $langs->trans("NotAvailable"); + } +} diff --git a/htdocs/core/tpl/commonfields_add.tpl.php b/htdocs/core/tpl/commonfields_add.tpl.php index c7069b3d2aa..a0b0ce7a6e2 100644 --- a/htdocs/core/tpl/commonfields_add.tpl.php +++ b/htdocs/core/tpl/commonfields_add.tpl.php @@ -55,6 +55,7 @@ foreach ($object->fields as $key => $val) print ''; if (!empty($val['picto'])) { print img_picto('', $val['picto']); } if (in_array($val['type'], array('int', 'integer'))) $value = GETPOST($key, 'int'); + elseif ($val['type'] == 'double') $value = price2num(GETPOST($key, 'alphanohtml')); elseif ($val['type'] == 'text' || $val['type'] == 'html') $value = GETPOST($key, 'restricthtml'); else $value = GETPOST($key, 'alpha'); if ($val['noteditable']) print $object->showOutputField($val, $key, $value, '', '', '', 0); diff --git a/htdocs/core/tpl/commonfields_edit.tpl.php b/htdocs/core/tpl/commonfields_edit.tpl.php index 946d8c0b504..76a9fafe417 100644 --- a/htdocs/core/tpl/commonfields_edit.tpl.php +++ b/htdocs/core/tpl/commonfields_edit.tpl.php @@ -53,6 +53,7 @@ foreach ($object->fields as $key => $val) print ''; if (!empty($val['picto'])) { print img_picto('', $val['picto']); } if (in_array($val['type'], array('int', 'integer'))) $value = GETPOSTISSET($key) ?GETPOST($key, 'int') : $object->$key; + elseif ($val['type'] == 'double') $value = GETPOSTISSET($key) ? price2num(GETPOST($key, 'alphanohtml')) : $object->$key; elseif (preg_match('/^(text|html)/', $val['type'])) { $tmparray = explode(':', $val['type']); if (!empty($tmparray[1])) { diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql new file mode 100644 index 00000000000..a75de31a905 --- /dev/null +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -0,0 +1,40 @@ +CREATE TABLE llx_workstation_workstation( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + type varchar(7), + note_public text, + entity int DEFAULT 1, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + status smallint NOT NULL, + nb_operators_required integer, + thm_operator_estimated double, + thm_machine_estimated double + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_rowid (rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_ref (ref); +ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_status (status); + +CREATE TABLE llx_workstation_workstation_resource( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_resource integer, + fk_workstation integer +) ENGINE=innodb; + +CREATE TABLE llx_workstation_workstation_usergroup( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_usergroup integer, + fk_workstation integer +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql new file mode 100755 index 00000000000..2e013ee0128 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql @@ -0,0 +1,27 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- 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 https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_rowid (rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_ref (ref); +ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_status (status); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_workstation_workstation ADD UNIQUE INDEX uk_workstation_workstation_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_field FOREIGN KEY (fk_field) REFERENCES llx_workstation_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.sql new file mode 100755 index 00000000000..5c141ed59df --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation.sql @@ -0,0 +1,36 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_workstation_workstation( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + type varchar(7), + note_public text, + entity int DEFAULT 1, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + status smallint NOT NULL, + nb_operators_required integer, + thm_operator_estimated double, + thm_machine_estimated double + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql new file mode 100755 index 00000000000..1ab019f4385 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql @@ -0,0 +1,22 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_workstation_workstation_resource( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_resource integer, + fk_workstation integer +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql new file mode 100755 index 00000000000..9bffb4f30c9 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql @@ -0,0 +1,22 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_workstation_workstation_usergroup( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_usergroup integer, + fk_workstation integer +) ENGINE=innodb; diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index 902f167d819..ec999a473a4 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -77,4 +77,28 @@ UnitCost=Unit cost TotalCost=Total cost BOMTotalCost=The cost to produce this BOM based on cost of each quantity and product to consume (use Cost price if defined, else Average Weighted Price if defined, else the Best purchase price) GoOnTabProductionToProduceFirst=You must first have started the production to close a Manufacturing Order (See tab '%s'). But you can Cancel it. -ErrorAVirtualProductCantBeUsedIntoABomOrMo=A kit can't be used into a BOM or a MO \ No newline at end of file +ErrorAVirtualProductCantBeUsedIntoABomOrMo=A kit can't be used into a BOM or a MO +Workstation=Workstation +Workstations=Workstations +WorkstationsDescription=Workstations management +WorkstationSetup = Workstations setup +WorkstationSetupPage = Workstations setup page +WorkstationAbout = About Workstation +WorkstationAboutPage = Workstations about page +WorkstationList=Workstation list +WorkstationCreate=Add new workstation +ConfirmEnableWorkstation=Are you sure you want to enable workstation %s ? +EnableAWorkstation=Enable a workstation +ConfirmDisableWorkstation=Are you sure you want to disable workstation %s ? +DisableAWorkstation=Disable a workstation +DeleteWorkstation=Supprimer +NbOperatorsRequired=Number of operators required +THMOperatorEstimated=Estimated operator THM +THMMachineEstimated=Estimated machine THM +WorkstationType=Workstation type +Human=Human +Machine=Machine +HumanMachine=Human / Machine +WorkstationArea=Workstation area +Machines=Machines +THMEstimatedHelp=This rate makes it possible to define a forecast cost of the item diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php index 0b6239b01e4..46085c126e0 100644 --- a/htdocs/resource/class/html.formresource.class.php +++ b/htdocs/resource/class/html.formresource.class.php @@ -77,7 +77,7 @@ class FormResource * @param string $morecss More css * @return string HTML string with */ - public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '') + public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '', $multiple=false) { // phpcs:enable global $conf, $user, $langs; @@ -89,6 +89,8 @@ class FormResource $resources_used = $resourcestat->fetch_all('ASC', 't.rowid', $limit, 0, $filter); + if (!is_array($selected)) $selected = array($selected); + if ($outputmode != 2) { $out = '
'; @@ -106,7 +108,7 @@ class FormResource } // Construct $out and $outarray - $out .= ''."\n"; if ($showempty) $out .= ''."\n"; $num = 0; @@ -123,7 +125,7 @@ class FormResource $label = $resourcestat->lines[$i]->ref ? $resourcestat->lines[$i]->ref : ''.$resourcestat->lines[$i]->label; if ($resourceclass != 'Dolresource') $label .= ' ('.$langs->trans($resourceclass).')'; - if ($selected > 0 && $selected == $resourcestat->lines[$i]->id) + if ((is_object($selected[0]) && $selected[0]->id == $resourcestat->lines[$i]->id) || (!is_object($selected[0]) && in_array($resourcestat->lines[$i]->id, $selected))) { $out .= ''; } else { diff --git a/htdocs/workstation/class/workstation.class.php b/htdocs/workstation/class/workstation.class.php new file mode 100755 index 00000000000..acedb6759d9 --- /dev/null +++ b/htdocs/workstation/class/workstation.class.php @@ -0,0 +1,1054 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 class/workstation.class.php + * \ingroup workstation + * \brief This file is a CRUD class file for Workstation (Create/Read/Update/Delete) + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for Workstation + */ +class Workstation extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'workstation'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'workstation'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'workstation_workstation'; + + /** + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + */ + public $ismultientitymanaged = 0; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 0; + + /** + * @var string String with name of icon for workstation. Must be the part after the 'object_' into object_workstation.png + */ + public $picto = 'mrp'; + + + const STATUS_DISABLED = 0; + const STATUS_ENABLED = 1; + + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'maxwidth200', 'wordbreak', 'tdoverflowmax200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'picto'=>'mrp', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>1, 'noteditable'=>'0', 'default'=>'', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'showoncombobox'=>'1',), + 'type' => array('type'=>'select', 'label'=>'Type', 'enabled'=>'1', 'position'=>32, 'default'=>1, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('HUMAN'=>'Human', 'MACHINE'=>'Machine', 'BOTH'=>'HumanMachine'),), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>512, 'notnull'=>-1, 'visible'=>-2,), + 'nb_operators_required' => array('type'=>'integer', 'label'=>'NbOperatorsRequired', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), + 'thm_operator_estimated' => array('type'=>'double', 'help'=>'THMEstimatedHelp','label'=>'THMOperatorEstimated', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), + 'thm_machine_estimated' => array('type'=>'double', 'help'=>'THMEstimatedHelp', 'label'=>'THMMachineEstimated', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'default'=>1, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Disabled', '1'=>'Enabled'),), + ); + public $rowid; + public $ref; + public $label; + public $note_public; + public $note_private; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $import_key; + public $status; + public $nb_operators_required; + public $thm_operator_estimated; + public $thm_machine_estimated; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var int Name of subtable line + */ + //public $table_element_line = 'workstation_workstationline'; + + /** + * @var int Field with ID of parent key if this object has a parent + */ + //public $fk_element = 'fk_workstation'; + + /** + * @var int Name of subtable class that manage subtable lines + */ + //public $class_element_line = 'Workstationline'; + + /** + * @var array List of child tables. To test if we can delete object. + */ + //protected $childtables = array(); + + /** + * @var array List of child tables. To know object to delete on cascade. + * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + */ + //protected $childtablesoncascade = array('workstation_workstationdet'); + + /** + * @var WorkstationLine[] Array of subtable lines + */ + //public $lines = array(); + + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $conf, $langs; + + dol_include_once('/workstation/class/workstationusergroup.class.php'); + dol_include_once('/workstation/class/workstationresource.class.php'); + + $this->db = $db; + + $this->fields['ref']['default'] = $this->getNextNumRef(); + + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0; + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0; + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->workstation->workstation->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 0; + }*/ + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) + { + if (isset($val['enabled']) && empty($val['enabled'])) + { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) + { + foreach ($this->fields as $key => $val) + { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) + { + foreach ($val['arrayofkeyval'] as $key2 => $val2) + { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + global $db; + + $id = $this->createCommon($user, $notrigger); + + // Usergroups + $groups = GETPOST('groups'); + if(empty($groups)) $groups = $this->usergroups; // createFromClone + if(!empty($groups)) { + foreach ($groups as $id_group) { + $ws_usergroup = new WorkstationUserGroup($db); + $ws_usergroup->fk_workstation = $id; + $ws_usergroup->fk_usergroup = $id_group; + $ws_usergroup->createCommon($user); + $this->usergroups[] = $id_group; + } + } + + // Resources + $resources = GETPOST('resources'); + if(empty($resources)) $resources = $this->resources; // createFromClone + if(!empty($resources)) { + foreach ($resources as $id_resource) { + $ws_resource = new WorkstationResource($db); + $ws_resource->fk_workstation = $id; + $ws_resource->fk_resource = $id_resource; + $ws_resource->createCommon($user); + $this->resources[] = $id_resource; + } + } + + return $id; + } + + /** + * Clone an object into another one + * + * @param User $user User that creates + * @param int $fromid Id of object to clone + * @return mixed New object created, <0 if KO + */ + public function createFromClone(User $user, $fromid) + { + global $langs, $extrafields; + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $object = new self($this->db); + + $this->db->begin(); + + // Load source object + $result = $object->fetch($fromid); + if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines(); + + // get lines so they will be clone + //foreach($this->lines as $line) + // $line->fetch_optionals(); + + // Reset some properties + unset($object->id); + unset($object->fk_user_creat); + unset($object->import_key); + + // Clear fields + if (property_exists($object, 'ref')) $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; + if (property_exists($object, 'label')) $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + if (property_exists($object, 'status')) { $object->status = self::STATUS_DISABLED; } + if (property_exists($object, 'date_creation')) { $object->date_creation = dol_now(); } + if (property_exists($object, 'date_modification')) { $object->date_modification = null; } + // ... + // Clear extrafields that are unique + if (is_array($object->array_options) && count($object->array_options) > 0) + { + $extrafields->fetch_name_optionals_label($this->table_element); + foreach ($object->array_options as $key => $option) + { + $shortkey = preg_replace('/options_/', '', $key); + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) + { + //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + unset($object->array_options[$key]); + } + } + } + + // Create clone + $object->context['createfromclone'] = 'createfromclone'; + $result = $object->create($user); + if ($result < 0) { + $error++; + $this->error = $object->error; + $this->errors = $object->errors; + } + + if (!$error) + { + // copy internal contacts + if ($this->copy_linked_contact($object, 'internal') < 0) + { + $error++; + } + } + + if (!$error) + { + // copy external contacts if same company + if (property_exists($this, 'socid') && $this->socid == $object->socid) + { + if ($this->copy_linked_contact($object, 'external') < 0) + $error++; + } + } + + unset($object->context['createfromclone']); + + // End + if (!$error) { + $this->db->commit(); + return $object; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + $result = $this->fetchCommon($id, $ref); + + $this->usergroups = WorkstationUserGroup::getAllGroupsOfWorkstation($this->id); + $this->resources = WorkstationResource::getAllResourcesOfWorkstation($this->id); + + if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines(); + return $result; + } + + /** + * Load object lines in memory from the database + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetchLines() + { + $this->lines = array(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = 'SELECT '; + $sql .= $this->getFieldList(); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')'; + else $sql .= ' WHERE 1 = 1'; + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key.'='.$value; + } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) { + $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } elseif (strpos($value, '%') === false) { + $sqlwhere[] = $key.' IN ('.$this->db->sanitize($this->db->escape($value)).')'; + } else { + $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= ' '.$this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) + { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + + // Usergroups + $groups = GETPOST('groups'); + WorkstationUserGroup::deleteAllGroupsOfWorkstation($this->id); + $this->usergroups=array(); + + foreach ($groups as $id_group) { + $ws_usergroup = new WorkstationUserGroup($this->db); + $ws_usergroup->fk_workstation = $this->id; + $ws_usergroup->fk_usergroup = $id_group; + $ws_usergroup->createCommon($user); + $this->usergroups[] = $id_group; + } + + // Resources + $resources = GETPOST('resources'); + WorkstationResource::deleteAllResourcesOfWorkstation($this->id); + $this->resources=array(); + if(!empty($resources)) { + foreach ($resources as $id_resource) { + $ws_resource = new WorkstationResource($this->db); + $ws_resource->fk_workstation = $this->id; + $ws_resource->fk_resource = $id_resource; + $ws_resource->createCommon($user); + $this->resources[] = $id_resource; + } + } + + return $this->updateCommon($user, $notrigger); + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) + { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * Validate object + * + * @param User $user User making status change + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <=0 if OK, 0=Nothing done, >0 if KO + */ + public function validate($user, $notrigger = 0) + { + global $conf, $langs; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) + { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation->workstation_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " status = ".self::STATUS_VALIDATED; + if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."'"; + if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".$user->id; + $sql .= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::validate()", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + dol_print_error($this->db); + $this->error = $this->db->lasterror(); + $error++; + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('WORKSTATION_VALIDATE', $user); + if ($result < 0) $error++; + // End call triggers + } + } + + if (!$error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'workstation/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'workstation/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { $error++; $this->error = $this->db->lasterror(); } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->workstation->dir_output.'/workstation/'.$oldref; + $dirdest = $conf->workstation->dir_output.'/workstation/'.$newref; + if (!$error && file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->workstation->dir_output.'/workstation/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) + { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) + { + $this->ref = $num; + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) + { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setStatus($status, $notrigger = 0) + { + global $user; + + $this->status = $status; + + if(empty($status)) $this->setDisabled($user, $notrigger); + else $this->setEnabled($user, $notrigger); + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setEnabled($user, $notrigger = 0) + { + return $this->setStatusCommon($user, self::STATUS_ENABLED, $notrigger, 'WORKSTATION_ENABLED'); + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setDisabled($user, $notrigger = 0) + { + return $this->setStatusCommon($user, self::STATUS_DISABLED, $notrigger, 'WORKSTATION_DISABLED'); + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + { + global $conf, $langs, $hookmanager; + + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips + + $result = ''; + + $label = img_picto('', $this->picto).' '.$langs->trans("Workstation").''; + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + $url = dol_buildpath('/workstation/workstation_card.php', 1).'?id='.$this->id; + + if ($option != 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; + if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + } + + $linkclose = ''; + if (empty($notooltip)) + { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label = $langs->trans("ShowWorkstation"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + + $linkstart = ''; + $linkend = ''; + + $result .= $linkstart; + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'mrp'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
No photo
'; + } else { + $result .= '
No photo
'; + } + + $result .= ''; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'mrp'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } + } + + if ($withpicto != 2) $result .= $this->ref; + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('workstationdao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $result = $hookmanager->resPrint; + else $result .= $hookmanager->resPrint; + + return $result; + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLibStatut($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function LibStatut($status, $mode = 0) + { + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) + { + global $langs; + //$langs->load("workstation@workstation"); + $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Disabled'); + $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + //if ($status == self::STATUS_CANCELED) $statusType = 'status6'; + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); + } + + /** + * Load the info information in the object + * + * @param int $id Id of object + * @return void + */ + public function info($id) + { + $sql = 'SELECT rowid, date_creation as datec, tms as datem,'; + $sql .= ' fk_user_creat, fk_user_modif'; + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + $sql .= ' WHERE t.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; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) + { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); + } + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->initAsSpecimenCommon(); + } + + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + $objectline = new WorkstationLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_workstation = '.$this->id)); + + if (is_numeric($result)) + { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("workstation@workstation"); + + if (empty($conf->global->WORKSTATION_WORKSTATION_ADDON)) { + $conf->global->WORKSTATION_WORKSTATION_ADDON = 'mod_workstation_standard'; + } + + if (!empty($conf->global->WORKSTATION_WORKSTATION_ADDON)) + { + $mybool = false; + + $file = $conf->global->WORKSTATION_WORKSTATION_ADDON.".php"; + $classname = $conf->global->WORKSTATION_WORKSTATION_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/workstation/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) + { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') + { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + { + global $conf, $langs; + + $result = 0; + $includedocgeneration = 0; + + $langs->load("workstation@workstation"); + + if (!dol_strlen($modele)) { + $modele = 'standard_workstation'; + + if ($this->model_pdf) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->WORKSTATION_ADDON_PDF)) { + $modele = $conf->global->WORKSTATION_ADDON_PDF; + } + } + + $modelpath = "core/modules/workstation/doc/"; + + if ($includedocgeneration) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * Action executed by scheduler + * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' + * Use public function doScheduledJob($param1, $param2, ...) to get parameters + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function doScheduledJob() + { + global $conf, $langs; + + //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; + + $error = 0; + $this->output = ''; + $this->error = ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $now = dol_now(); + + $this->db->begin(); + + // ... + + $this->db->commit(); + + return $error; + } +} diff --git a/htdocs/workstation/class/workstation.class.php.back b/htdocs/workstation/class/workstation.class.php.back new file mode 100755 index 00000000000..f4666c352ce --- /dev/null +++ b/htdocs/workstation/class/workstation.class.php.back @@ -0,0 +1,1052 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 class/workstation.class.php + * \ingroup workstation + * \brief This file is a CRUD class file for Workstation (Create/Read/Update/Delete) + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for Workstation + */ +class Workstation extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'workstation'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'workstation'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'workstation_workstation'; + + /** + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + */ + public $ismultientitymanaged = 0; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for workstation. Must be the part after the 'object_' into object_workstation.png + */ + public $picto = 'workstation@workstation'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'maxwidth200', 'wordbreak', 'tdoverflowmax200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'help'=>"Help text", 'showoncombobox'=>'1',), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Brouillon', '1'=>'Validé', '9'=>'Annulé'),), + 'nb_operators_required' => array('type'=>'integer', 'label'=>'NbOperatorsRequired', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), + 'thm_operator_estimated' => array('type'=>'double', 'label'=>'THMOperatorEstimated', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), + 'thm_machine_estimated' => array('type'=>'double', 'label'=>'THMMachineEstimated', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), + ); + public $rowid; + public $ref; + public $label; + public $description; + public $note_public; + public $note_private; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $import_key; + public $status; + public $nb_operators_required; + public $thm_operator_estimated; + public $thm_machine_estimated; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var int Name of subtable line + */ + //public $table_element_line = 'workstation_workstationline'; + + /** + * @var int Field with ID of parent key if this object has a parent + */ + //public $fk_element = 'fk_workstation'; + + /** + * @var int Name of subtable class that manage subtable lines + */ + //public $class_element_line = 'Workstationline'; + + /** + * @var array List of child tables. To test if we can delete object. + */ + //protected $childtables = array(); + + /** + * @var array List of child tables. To know object to delete on cascade. + * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + */ + //protected $childtablesoncascade = array('workstation_workstationdet'); + + /** + * @var WorkstationLine[] Array of subtable lines + */ + //public $lines = array(); + + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $conf, $langs; + + $this->db = $db; + + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0; + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0; + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->workstation->workstation->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 0; + }*/ + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) + { + if (isset($val['enabled']) && empty($val['enabled'])) + { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) + { + foreach ($this->fields as $key => $val) + { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) + { + foreach ($val['arrayofkeyval'] as $key2 => $val2) + { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + return $this->createCommon($user, $notrigger); + } + + /** + * Clone an object into another one + * + * @param User $user User that creates + * @param int $fromid Id of object to clone + * @return mixed New object created, <0 if KO + */ + public function createFromClone(User $user, $fromid) + { + global $langs, $extrafields; + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $object = new self($this->db); + + $this->db->begin(); + + // Load source object + $result = $object->fetchCommon($fromid); + if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines(); + + // get lines so they will be clone + //foreach($this->lines as $line) + // $line->fetch_optionals(); + + // Reset some properties + unset($object->id); + unset($object->fk_user_creat); + unset($object->import_key); + + // Clear fields + if (property_exists($object, 'ref')) $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; + if (property_exists($object, 'label')) $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + if (property_exists($object, 'status')) { $object->status = self::STATUS_DRAFT; } + if (property_exists($object, 'date_creation')) { $object->date_creation = dol_now(); } + if (property_exists($object, 'date_modification')) { $object->date_modification = null; } + // ... + // Clear extrafields that are unique + if (is_array($object->array_options) && count($object->array_options) > 0) + { + $extrafields->fetch_name_optionals_label($this->table_element); + foreach ($object->array_options as $key => $option) + { + $shortkey = preg_replace('/options_/', '', $key); + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) + { + //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + unset($object->array_options[$key]); + } + } + } + + // Create clone + $object->context['createfromclone'] = 'createfromclone'; + $result = $object->createCommon($user); + if ($result < 0) { + $error++; + $this->error = $object->error; + $this->errors = $object->errors; + } + + if (!$error) + { + // copy internal contacts + if ($this->copy_linked_contact($object, 'internal') < 0) + { + $error++; + } + } + + if (!$error) + { + // copy external contacts if same company + if (property_exists($this, 'socid') && $this->socid == $object->socid) + { + if ($this->copy_linked_contact($object, 'external') < 0) + $error++; + } + } + + unset($object->context['createfromclone']); + + // End + if (!$error) { + $this->db->commit(); + return $object; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + $result = $this->fetchCommon($id, $ref); + if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines(); + return $result; + } + + /** + * Load object lines in memory from the database + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetchLines() + { + $this->lines = array(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = 'SELECT '; + $sql .= $this->getFieldList(); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')'; + else $sql .= ' WHERE 1 = 1'; + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key.'='.$value; + } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) { + $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } elseif (strpos($value, '%') === false) { + $sqlwhere[] = $key.' IN ('.$this->db->sanitize($this->db->escape($value)).')'; + } else { + $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= ' '.$this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) + { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + return $this->updateCommon($user, $notrigger); + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) + { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * Validate object + * + * @param User $user User making status change + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <=0 if OK, 0=Nothing done, >0 if KO + */ + public function validate($user, $notrigger = 0) + { + global $conf, $langs; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) + { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation->workstation_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " status = ".self::STATUS_VALIDATED; + if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."'"; + if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".$user->id; + $sql .= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::validate()", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + dol_print_error($this->db); + $this->error = $this->db->lasterror(); + $error++; + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('WORKSTATION_VALIDATE', $user); + if ($result < 0) $error++; + // End call triggers + } + } + + if (!$error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'workstation/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'workstation/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { $error++; $this->error = $this->db->lasterror(); } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->workstation->dir_output.'/workstation/'.$oldref; + $dirdest = $conf->workstation->dir_output.'/workstation/'.$newref; + if (!$error && file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->workstation->dir_output.'/workstation/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) + { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) + { + $this->ref = $num; + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) + { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setDraft($user, $notrigger = 0) + { + // Protection + if ($this->status <= self::STATUS_DRAFT) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'WORKSTATION_UNVALIDATE'); + } + + /** + * Set cancel status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function cancel($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_VALIDATED) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'WORKSTATION_CLOSE'); + } + + /** + * Set back to validated status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function reopen($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_CANCELED) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'WORKSTATION_REOPEN'); + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + { + global $conf, $langs, $hookmanager; + + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips + + $result = ''; + + $label = img_picto('', $this->picto).' '.$langs->trans("Workstation").''; + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + $url = dol_buildpath('/workstation/workstation_card.php', 1).'?id='.$this->id; + + if ($option != 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; + if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + } + + $linkclose = ''; + if (empty($notooltip)) + { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label = $langs->trans("ShowWorkstation"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + + $linkstart = ''; + $linkend = ''; + + $result .= $linkstart; + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
No photo
'; + } else { + $result .= '
No photo
'; + } + + $result .= ''; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } + } + + if ($withpicto != 2) $result .= $this->ref; + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('workstationdao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $result = $hookmanager->resPrint; + else $result .= $hookmanager->resPrint; + + return $result; + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLibStatut($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function LibStatut($status, $mode = 0) + { + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) + { + global $langs; + //$langs->load("workstation@workstation"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + if ($status == self::STATUS_CANCELED) $statusType = 'status6'; + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); + } + + /** + * Load the info information in the object + * + * @param int $id Id of object + * @return void + */ + public function info($id) + { + $sql = 'SELECT rowid, date_creation as datec, tms as datem,'; + $sql .= ' fk_user_creat, fk_user_modif'; + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + $sql .= ' WHERE t.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; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) + { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); + } + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->initAsSpecimenCommon(); + } + + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + $objectline = new WorkstationLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_workstation = '.$this->id)); + + if (is_numeric($result)) + { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("workstation@workstation"); + + if (empty($conf->global->WORKSTATION_WORKSTATION_ADDON)) { + $conf->global->WORKSTATION_WORKSTATION_ADDON = 'mod_workstation_standard'; + } + + if (!empty($conf->global->WORKSTATION_WORKSTATION_ADDON)) + { + $mybool = false; + + $file = $conf->global->WORKSTATION_WORKSTATION_ADDON.".php"; + $classname = $conf->global->WORKSTATION_WORKSTATION_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/workstation/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) + { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') + { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + { + global $conf, $langs; + + $result = 0; + $includedocgeneration = 0; + + $langs->load("workstation@workstation"); + + if (!dol_strlen($modele)) { + $modele = 'standard_workstation'; + + if ($this->model_pdf) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->WORKSTATION_ADDON_PDF)) { + $modele = $conf->global->WORKSTATION_ADDON_PDF; + } + } + + $modelpath = "core/modules/workstation/doc/"; + + if ($includedocgeneration) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * Action executed by scheduler + * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' + * Use public function doScheduledJob($param1, $param2, ...) to get parameters + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function doScheduledJob() + { + global $conf, $langs; + + //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; + + $error = 0; + $this->output = ''; + $this->error = ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $now = dol_now(); + + $this->db->begin(); + + // ... + + $this->db->commit(); + + return $error; + } +} + + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; + +/** + * Class WorkstationLine. You can also remove this and generate a CRUD class for lines objects. + */ +class WorkstationLine extends CommonObjectLine +{ + // To complete with content of an object WorkstationLine + // We should have a field rowid, fk_workstation and position + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 0; + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } +} diff --git a/htdocs/workstation/class/workstationresource.class.php b/htdocs/workstation/class/workstationresource.class.php new file mode 100644 index 00000000000..2cae732377a --- /dev/null +++ b/htdocs/workstation/class/workstationresource.class.php @@ -0,0 +1,82 @@ + array ('type' => 'integer'), + 'fk_resource' => array ('type' => 'integer') + ); + + /** + * WorkstationResource constructor. + * @param DoliDB $db Database connector + */ + public function __construct($db) + { + $this->db = $db; + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) + { + if (isset($val['enabled']) && empty($val['enabled'])) + { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) + { + foreach ($this->fields as $key => $val) + { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) + { + foreach ($val['arrayofkeyval'] as $key2 => $val2) + { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + static public function getAllResourcesOfWorkstation($fk_workstation) { + + global $db; + + $obj = new self($db); + $sql = 'SELECT fk_resource FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; + $resql = $db->query($sql); + + $TRes = array(); + if(!empty($resql)) { + while($res = $db->fetch_object($resql)) { + $TRes[] = $res->fk_resource; + } + } + + return $TRes; + + } + + static public function deleteAllResourcesOfWorkstation($fk_workstation) { + + global $db; + + $obj = new self($db); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; + $resql = $db->query($sql); + + if(empty($resql)) return 0; + + return 1; + + } + +} diff --git a/htdocs/workstation/class/workstationusergroup.class.php b/htdocs/workstation/class/workstationusergroup.class.php new file mode 100644 index 00000000000..af643a6d28e --- /dev/null +++ b/htdocs/workstation/class/workstationusergroup.class.php @@ -0,0 +1,82 @@ + array ('type' => 'integer'), + 'fk_usergroup' => array ('type' => 'integer') + ); + + /** + * WorkstationUserGroup constructor. + * @param DoliDB $db Database connector + */ + public function __construct($db) + { + $this->db = $db; + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) + { + if (isset($val['enabled']) && empty($val['enabled'])) + { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) + { + foreach ($this->fields as $key => $val) + { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) + { + foreach ($val['arrayofkeyval'] as $key2 => $val2) + { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + static public function getAllGroupsOfWorkstation($fk_workstation) { + + global $db; + + $obj = new self($db); + $sql = 'SELECT fk_usergroup FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; + $resql = $db->query($sql); + + $TRes = array(); + if(!empty($resql)) { + while($res = $db->fetch_object($resql)) { + $TRes[] = $res->fk_usergroup; + } + } + + return $TRes; + + } + + static public function deleteAllGroupsOfWorkstation($fk_workstation) { + + global $db; + + $obj = new self($db); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; + $resql = $db->query($sql); + + if(empty($resql)) return 0; + + return 1; + + } + +} diff --git a/htdocs/workstation/lib/workstation.lib.php b/htdocs/workstation/lib/workstation.lib.php new file mode 100755 index 00000000000..526323ec45d --- /dev/null +++ b/htdocs/workstation/lib/workstation.lib.php @@ -0,0 +1,65 @@ +. + */ + +/** + * \file workstation/lib/workstation.lib.php + * \ingroup workstation + * \brief Library files with common functions for Workstation + */ + +/** + * Prepare admin pages header + * + * @return array + */ +function workstationAdminPrepareHead() +{ + global $langs, $conf; + + $langs->load("workstation@workstation"); + + $h = 0; + $head = array(); + $head[$h][0] = DOL_URL_ROOT . "/admin/workstation.php"; + $head[$h][1] = $langs->trans("Settings"); + $head[$h][2] = 'settings'; + $h++; + + /* + $head[$h][0] = dol_buildpath("/workstation/admin/myobject_extrafields.php", 1); + $head[$h][1] = $langs->trans("ExtraFields"); + $head[$h][2] = 'myobject_extrafields'; + $h++; + */ + + /*$head[$h][0] = require_once "/admin/about.php"; + $head[$h][1] = $langs->trans("About"); + $head[$h][2] = 'about'; + $h++;*/ + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@workstation:/workstation/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@workstation:/workstation/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, null, $head, $h, 'workstation'); + + return $head; +} diff --git a/htdocs/workstation/lib/workstation_workstation.lib.php b/htdocs/workstation/lib/workstation_workstation.lib.php new file mode 100755 index 00000000000..1c6b7492f0c --- /dev/null +++ b/htdocs/workstation/lib/workstation_workstation.lib.php @@ -0,0 +1,85 @@ +. + */ + +/** + * \file lib/workstation_workstation.lib.php + * \ingroup workstation + * \brief Library files with common functions for Workstation + */ + +/** + * Prepare array of tabs for Workstation + * + * @param Workstation $object Workstation + * @return array Array of tabs + */ +function workstationPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("workstation@workstation"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/workstation/workstation_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $h++; + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) + { + $nbNote = 0; + if (!empty($object->note_private)) $nbNote++; + if (!empty($object->note_public)) $nbNote++; + $head[$h][0] = dol_buildpath('/workstation/workstation_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->workstation->dir_output."/workstation/".dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = dol_buildpath("/workstation/workstation_document.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = dol_buildpath("/workstation/workstation_agenda.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@workstation:/workstation/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@workstation:/workstation/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'workstation@workstation'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'workstation@workstation', 'remove'); + + return $head; +} diff --git a/htdocs/workstation/workstation_agenda.php b/htdocs/workstation/workstation_agenda.php new file mode 100755 index 00000000000..132acc02bee --- /dev/null +++ b/htdocs/workstation/workstation_agenda.php @@ -0,0 +1,276 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 workstation_agenda.php + * \ingroup workstation + * \brief Tab of events on Workstation + */ + +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies +//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +// Try main.inc.php using relative path +if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; +if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; +if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; +if (!$res) die("Include of main fails"); + +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +dol_include_once('/workstation/class/workstation.class.php'); +dol_include_once('/workstation/lib/workstation_workstation.lib.php'); + + +// Load translation files required by the page +$langs->loadLangs(array("workstation@workstation", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +if (GETPOST('actioncode', 'array')) { + $actioncode = GETPOST('actioncode', 'array', 3); + if (!count($actioncode)) $actioncode = '0'; +} else { + $actioncode = GETPOST("actioncode", "alpha", 3) ?GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); +} +$search_agenda_label = GETPOST('search_agenda_label'); + +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortfield) $sortfield = 'a.datep,a.id'; +if (!$sortorder) $sortorder = 'DESC,DESC'; + +// Initialize technical objects +$object = new Workstation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('workstationagenda', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) $upload_dir = $conf->workstation->multidir_output[$object->entity]."/".$object->id; + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$result = restrictedArea($user, 'workstation', $object->id); + +$permissiontoadd = $user->rights->workstation->workstation->write; // Used by the include of actions_addupdatedelete.inc.php + + +/* + * Actions + */ + +$parameters = array('id'=>$id); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + // Cancel + if (GETPOST('cancel', 'alpha') && !empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + + // Purge search criteria + 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 + { + $actioncode = ''; + $search_agenda_label = ''; + } +} + + + +/* + * View + */ + +$form = new Form($db); + +if ($object->id > 0) +{ + $title = $langs->trans("Agenda"); + //if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title; + $help_url = ''; + llxHeader('', $title, $help_url); + + if (!empty($conf->notification->enabled)) $langs->load("mails"); + $head = workstationPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Workstation"), -1, 'mrp'); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
'; + /* + // Ref customer + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
'.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + if ($action != 'classify') + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + $morehtmlref.=' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.=''; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
'; + print '
'; + + $object->info($object->id); + dol_print_object_info($object, 1); + + print '
'; + + print dol_get_fiche_end(); + + + + // Actions buttons + + $objthirdparty = $object; + $objcon = new stdClass(); + + $out = '&origin='.urlencode($object->element.'@'.$object->module).'&originid='.urlencode($object->id); + $urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id; + $out .= '&backtopage='.urlencode($urlbacktopage); + $permok = $user->rights->agenda->myactions->create; + if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) + { + //$out.='trans("AddAnAction"),'filenew'); + //$out.=""; + } + + + print '
'; + + if (!empty($conf->agenda->enabled)) + { + if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) + { + print ''.$langs->trans("AddAction").''; + } else { + print ''.$langs->trans("AddAction").''; + } + } + + print '
'; + + if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) + { + $param = '&id='.$object->id.'&socid='.$socid; + if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); + if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); + + + //print load_fiche_titre($langs->trans("ActionsOnWorkstation"), '', ''); + + // List of all actions + $filters = array(); + $filters['search_agenda_label'] = $search_agenda_label; + + // TODO Replace this with same code than into list.php + show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module); + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/workstation/workstation_card.php b/htdocs/workstation/workstation_card.php new file mode 100755 index 00000000000..5ec3a1f6842 --- /dev/null +++ b/htdocs/workstation/workstation_card.php @@ -0,0 +1,511 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 workstation_card.php + * \ingroup workstation + * \brief Page to create/edit/view workstation + */ + +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies +//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +// Try main.inc.php using relative path +if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; +if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; +if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; +if (!$res) die("Include of main fails"); + +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; +dol_include_once('/workstation/class/workstation.class.php'); +dol_include_once('/workstation/lib/workstation_workstation.lib.php'); +dol_include_once('/workstation/class/workstationusergroup.class.php'); + +// Load translation files required by the page +$langs->loadLangs(array("workstation@workstation", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'workstationcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +$groups = GETPOST('groups'); +$resources = GETPOST('resources'); +//$lineid = GETPOST('lineid', 'int'); + +// Initialize technical objects +$object = new Workstation($db); +//$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('workstationcard', 'globalcard')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +//$extrafields->fetch_name_optionals_label($object->table_element); + +//$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Initialize array of search criterias +$search_all = GETPOST("search_all", 'alpha'); +$search = array(); +foreach ($object->fields as $key => $val) +{ + if (GETPOST('search_'.$key, 'alpha')) $search[$key] = GETPOST('search_'.$key, 'alpha'); +} + +if (empty($action) && empty($id) && empty($ref)) $action = 'view'; + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$permissiontoread = $user->rights->workstation->workstation->read; +$permissiontoadd = $user->rights->workstation->workstation->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->workstation->workstation->delete; +$permissionnote = $user->rights->workstation->workstation->write; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $user->rights->workstation->workstation->write; // Used by the include of actions_dellink.inc.php +$upload_dir = $conf->workstation->multidir_output[isset($object->entity) ? $object->entity : 1]; + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$isdraft = (($object->statut == $object::STATUS_DRAFT) ? 1 : 0); +//$result = restrictedArea($user, 'workstation', $object->id, '', '', 'fk_soc', 'rowid', $isdraft); + +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + $error = 0; + + $backurlforlist = dol_buildpath('/workstation/workstation_list.php', 1); + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) $backtopage = $backurlforlist; + else $backtopage = dol_buildpath('/workstation/workstation_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + } + } + + $triggermodname = 'WORKSTATION_WORKSTATION_MODIFY'; // Name of trigger action code to execute when we modify record + + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen + include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; + + // Actions when linking object each other + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + + // Action to move up and down lines of object + //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; + + // Action to build doc + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + + if ($action == 'confirm_enable' && $confirm == "yes" && $permissiontoadd) { + + if(!empty($object->id)) $object->setStatus(1); + + } elseif ($action == 'confirm_disable' && $confirm == "yes" && $permissiontoadd) { + + if(!empty($object->id)) $object->setStatus(0); + + } + +} + + + + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formresource = new FormResource($db); + +$title = $langs->trans("Workstation"); +$help_url = ''; +llxHeader('', $title, $help_url); + +// Example : Adding jquery code +?> + +trans("NewObject", $langs->transnoentitiesnoconv("Workstation")), '', 'object_'.$object->picto); + + print '
'; + print ''; + print ''; + if ($backtopage) print ''; + if ($backtopageforcancel) print ''; + + print dol_get_fiche_head(array(), ''); + + // Set some default values + //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; + + print ''."\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; + + print ''; + print ''; + + print ''; + print ''; + + // Other attributes + //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; + + print '
'; + print $langs->trans('Groups'); + print ''; + print img_picto('', 'group'); + print $form->select_dolgroups($groups, 'groups', 1, '', 0, '', '', $object->entity, true); + print '
'; + print $langs->trans('Machines'); + print ''; + print img_picto('', 'resource'); + print $formresource->select_resource_list($resources, 'resources', '', '', 0, '', '', $object->entity, true, 0, '', true); + print '
'."\n"; + + print dol_get_fiche_end(); + + print '
'; + print ''; + print '  '; + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
'; + + print '
'; + + //dol_set_focus('input[name="ref"]'); +} + +// Part to edit record +if (($id || $ref) && $action == 'edit') +{ + print load_fiche_titre($langs->trans("Workstation"), '', 'object_'.$object->picto); + + print '
'; + print ''; + print ''; + print ''; + if ($backtopage) print ''; + if ($backtopageforcancel) print ''; + + print dol_get_fiche_head(); + + print ''."\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; + + print ''; + print ''; + + print ''; + print ''; + + // Other attributes + //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; + + print '
'; + print $langs->trans('Groups'); + print ''; + print img_picto('', 'group'); + print $form->select_dolgroups(empty($groups) ? $object->usergroups : $groups, 'groups', 1, '', 0, '', '', $object->entity, true); + print '
'; + print $langs->trans('Machines'); + print ''; + print img_picto('', 'resource'); + print $formresource->select_resource_list(empty($resources) ? $object->resources : $resources, 'resources', '', '', 0, '', '', $object->entity, true, 0, '', true); + print '
'; + + print dol_get_fiche_end(); + + print '
'; + print '   '; + print '
'; + + print '
'; +} + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) +{ + $res = $object->fetch_optionals(); + + $head = workstationPrepareHead($object); + print dol_get_fiche_head($head, 'card', $langs->trans("Workstation"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteWorkstation'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } + // Clone confirmation + if ($action == 'clone') { + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } + + // Confirmation of action xxxx + if ($action == 'enable') + { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('EnableAWorkstation'), $langs->trans("ConfirmEnableWorkstation", $object->ref), 'confirm_enable', $formquestion, 0, 1, 220); + } elseif ($action == 'disable') + { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DisableAWorkstation'), $langs->trans("ConfirmDisableWorkstation", $object->ref), 'confirm_disable', $formquestion, 0, 1, 220); + } + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; + elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
'; + /* + // Ref customer + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref .= '
'.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; + $morehtmlref .= ' : '; + if ($action == 'classify') { + //$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
'; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + print '
'; + print ''."\n"; + + // Common attributes + //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field + //unset($object->fields['fk_project']); // Hide field already shown in banner + //unset($object->fields['fk_soc']); // Hide field already shown in banner + if($object->type === 'MACHINE') $object->fields['nb_operators_required']['visible'] = 0; + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + // Groups + if($object->type !== 'MACHINE') { + $toprint = array(); + foreach ($object->usergroups as $id_group) { + $g = new UserGroup($db); + $g->fetch($id_group); + $toprint[] = '
  • ' . $g->getNomUrl(1) . '
  • '; + } + print ''; + } + + // Resources + if($object->type !== 'HUMAN') { + $toprint = array(); + foreach ($object->resources as $id_resource) { + $r = new Dolresource($db); + $r->fetch($id_resource); + $toprint[] = '
  • ' . $r->getNomUrl(1) . '
  • '; + } + print ''; + } + + // Other attributes. Fields from hook formObjectOptions and Extrafields. + //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + + print '
    ' . $langs->trans('Groups') . ''; + print '
      ' . implode(' ', $toprint) . '
    '; + print '
    ' . $langs->trans('Machines') . ''; + print '
      ' . implode(' ', $toprint) . '
    '; + print '
    '; + print '
    '; + print '
    '; + + print '
    '; + + print dol_get_fiche_end(); + + + // Buttons for actions + + if ($action != 'presend' && $action != 'editline') { + print '
    '."\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + if (empty($reshook)) + { + + // Modify + if ($permissiontoadd) { + print ''.$langs->trans("Modify").''."\n"; + } else { + print ''.$langs->trans('Modify').''."\n"; + } + + // Clone + if ($permissiontoadd) { + print ''.$langs->trans("ToClone").''."\n"; + } + + + if ($permissiontoadd) + { + if ($object->status == $object::STATUS_ENABLED) { + print ''.$langs->trans("Disable").''."\n"; + } else { + print ''.$langs->trans("Enable").''."\n"; + } + } + + + // Delete (need delete permission, or if draft, just need create/modify permission) + if ($permissiontodelete) + { + print ''.$langs->trans('Delete').''."\n"; + } else { + print ''.$langs->trans('Delete').''."\n"; + } + } + print '
    '."\n"; + } + +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/workstation/workstation_document.php b/htdocs/workstation/workstation_document.php new file mode 100755 index 00000000000..104ea93c4db --- /dev/null +++ b/htdocs/workstation/workstation_document.php @@ -0,0 +1,228 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 workstation_document.php + * \ingroup workstation + * \brief Tab for documents linked to Workstation + */ + +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies +//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +// Try main.inc.php using relative path +if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; +if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; +if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; +if (!$res) die("Include of main fails"); + +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +dol_include_once('/workstation/class/workstation.class.php'); +dol_include_once('/workstation/lib/workstation_workstation.lib.php'); + +// Load translation files required by the page +$langs->loadLangs(array("workstation@workstation", "companies", "other", "mails")); + + +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm'); +$id = (GETPOST('socid', 'int') ? GETPOST('socid', 'int') : GETPOST('id', 'int')); +$ref = GETPOST('ref', 'alpha'); + +// Get parameters +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortorder) $sortorder = "ASC"; +if (!$sortfield) $sortfield = "name"; +//if (! $sortfield) $sortfield="position_name"; + +// Initialize technical objects +$object = new Workstation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('workstationdocument', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals + +if ($id > 0 || !empty($ref)) $upload_dir = $conf->workstation->multidir_output[$object->entity ? $object->entity : $conf->entity]."/workstation/".get_exdir(0, 0, 0, 1, $object); + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$result = restrictedArea($user, 'workstation', $object->id); + +$permissiontoadd = $user->rights->workstation->workstation->write; // Used by the include of actions_addupdatedelete.inc.php + + + +/* + * Actions + */ + +include_once DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("Workstation").' - '.$langs->trans("Files"); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +if ($object->id) +{ + /* + * Show tabs + */ + $head = workstationPrepareHead($object); + + print dol_get_fiche_head($head, 'document', $langs->trans("Workstation"), -1, $object->picto); + + + // Build file list + $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1); + $totalsize = 0; + foreach ($filearray as $key => $file) + { + $totalsize += $file['size']; + } + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + /* + // Ref customer + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
    '.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + if ($action != 'classify') + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + $morehtmlref.=' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='
    '; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.='
    '; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + + print '
    '; + print ''; + + // Number of files + print ''; + + // Total size + print ''; + + print '
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    '; + + print '
    '; + + print dol_get_fiche_end(); + + $modulepart = 'workstation'; + //$permission = $user->rights->workstation->workstation->write; + $permission = 1; + //$permtoedit = $user->rights->workstation->workstation->write; + $permtoedit = 1; + $param = '&id='.$object->id; + + //$relativepathwithnofile='workstation/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = 'workstation/'.dol_sanitizeFileName($object->ref).'/'; + + include_once DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; +} else { + accessforbidden('', 0, 1); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php new file mode 100755 index 00000000000..c9aa575fad2 --- /dev/null +++ b/htdocs/workstation/workstation_list.php @@ -0,0 +1,601 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 workstation_list.php + * \ingroup workstation + * \brief List page for workstation + */ + +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies +//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +// Try main.inc.php using relative path +if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; +if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; +if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; +if (!$res) die("Include of main fails"); + +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + +// load workstation libraries +require_once __DIR__.'/class/workstation.class.php'; + +// for other modules +//dol_include_once('/othermodule/class/otherobject.class.php'); + +// Load translation files required by the page +$langs->loadLangs(array("workstation@workstation", "other")); + +$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? +$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'workstationlist'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') + +$id = GETPOST('id', 'int'); + +// Load variable for pagination +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST('sortfield', 'aZ09comma'); +$sortorder = GETPOST('sortorder', 'aZ09comma'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical objects +$object = new Workstation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('workstationlist')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); +//$extrafields->fetch_name_optionals_label($object->table_element_line); + +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Default sort order (if not yet defined by previous GETPOST) +if (!$sortfield) $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. +if (!$sortorder) $sortorder = "ASC"; + +// Initialize array of search criterias +$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'); +$search = array(); + +foreach ($object->fields as $key => $val) +{ + if (GETPOST('search_'.$key, 'alpha') !== '') $search[$key] = GETPOST('search_'.$key, 'alpha'); + if(in_array($key, array('type', 'status')) && GETPOST('search_'.$key, 'alpha') == -1) $search[$key] = ''; +} + +// List of fields to search into when doing a "search in all" +$fieldstosearchall = array(); +foreach ($object->fields as $key => $val) +{ + if ($val['searchall']) $fieldstosearchall['t.'.$key] = $val['label']; +} + +// Definition of array of fields for columns +$arrayfields = array(); +foreach ($object->fields as $key => $val) +{ + // If $val['visible']==0, then we never show the field + if (!empty($val['visible'])) { + $visible = dol_eval($val['visible'], 1); + $arrayfields['t.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=>$val['help'] + ); + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; + +$object->fields = dol_sort_array($object->fields, 'position'); +$arrayfields = dol_sort_array($arrayfields, 'position'); + +$permissiontoread = $user->rights->workstation->workstation->read; +$permissiontoadd = $user->rights->workstation->workstation->write; +$permissiontodelete = $user->rights->workstation->workstation->delete; + +// Security check +if (empty($conf->workstation->enabled)) accessforbidden('Module not enabled'); +$socid = 0; +if ($user->socid > 0) // Protection if external user +{ + //$socid = $user->socid; + accessforbidden(); +} +//$result = restrictedArea($user, 'workstation', $id, ''); +//if (!$permissiontoread) accessforbidden(); + + + +/* + * Actions + */ + +if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // Purge search criteria + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) // All tests are required to be compatible with all browsers + { + foreach ($object->fields as $key => $val) + { + $search[$key] = ''; + } + $toselect = ''; + $search_array_options = array(); + } + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') + || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) + { + $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation + } + + // Mass actions + $objectclass = 'Workstation'; + $objectlabel = 'Workstation'; + $uploaddir = $conf->workstation->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +//$help_url="EN:Module_Workstation|FR:Module_Workstation_FR|ES:Módulo_Workstation"; +$help_url = ''; +$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("Workstations")); + + +// Build and execute select +// -------------------------------------------------------------------- +$sql = 'SELECT '; +foreach ($object->fields as $key => $val) +{ + $sql .= 't.'.$key.', '; +} +// Add fields from extrafields +if (!empty($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.' as options_'.$key.', ' : ''); +} +// Add fields from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= preg_replace('/^,/', '', $hookmanager->resPrint); +$sql = preg_replace('/,\s*$/', '', $sql); +$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; +if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +if ($object->ismultientitymanaged == 1) $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; +else $sql .= " WHERE 1 = 1"; +foreach ($search as $key => $val) +{ + if ($key == 'status' && $search[$key] == -1) continue; + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if (strpos($object->fields[$key]['type'], 'integer:') === 0) { + if ($search[$key] == '-1') $search[$key] = ''; + $mode_search = 2; + } + if ($search[$key] != '') $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); +} +if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); +//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear); +// Add where from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; + +/* If a group by is required +$sql.= " GROUP BY "; +foreach($object->fields as $key => $val) +{ + $sql.='t.'.$key.', '; +} +// Add fields from extrafields +if (! empty($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); +} +// Add where from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters, $object); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +$sql=preg_replace('/,\s*$/','', $sql); +*/ + +$sql .= $db->order($sortfield, $sortorder); + +// Count total nb of records +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); + if (($page * $limit) > $nbtotalofrecords) // if total of record found is smaller than page * limit, goto and load page 0 + { + $page = 0; + $offset = 0; + } +} +// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set. +if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) +{ + $num = $nbtotalofrecords; +} else { + if ($limit) $sql .= $db->plimit($limit + 1, $offset); + + $resql = $db->query($sql); + if (!$resql) + { + dol_print_error($db); + exit; + } + + $num = $db->num_rows($resql); +} + +// Direct jump if only one record found +if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) +{ + $obj = $db->fetch_object($resql); + $id = $obj->rowid; + header("Location: ".dol_buildpath('/workstation/workstation_card.php', 1).'?id='.$id); + exit; +} + + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url); + +// Example : Adding jquery code +print ''; + +$arrayofselected = is_array($toselect) ? $toselect : array(); + +$param = ''; +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); +if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); +foreach ($search as $key => $val) +{ + if (is_array($search[$key]) && count($search[$key])) foreach ($search[$key] as $skey) $param .= '&search_'.$key.'[]='.urlencode($skey); + else $param .= '&search_'.$key.'='.urlencode($search[$key]); +} +if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss); +// Add $param from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; + +// List of mass actions available +$arrayofmassactions = array( + //'validate'=>$langs->trans("Validate"), + //'generate_doc'=>$langs->trans("ReGeneratePDF"), + //'builddoc'=>$langs->trans("PDFMerge"), + //'presend'=>$langs->trans("SendByMail"), +); +if ($permissiontodelete) $arrayofmassactions['predelete'] = ''.$langs->trans("Delete"); +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) $arrayofmassactions = array(); +$massactionbutton = $form->selectMassAction('', $arrayofmassactions); + +print '
    '."\n"; +if ($optioncss != '') print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/workstation/workstation_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); + +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); + +// Add code for pre mass action (confirmation or email presend form) +$topicmail = "SendWorkstationRef"; +$modelmail = "workstation"; +$objecttmp = new Workstation($db); +$trackid = 'xxxx'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + +if ($search_all) +{ + foreach ($fieldstosearchall as $key => $val) $fieldstosearchall[$key] = $langs->trans($val); + print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '; +} + +$moreforfilter = ''; +/*$moreforfilter.='
    '; +$moreforfilter.= $langs->trans('MyFilter') . ': '; +$moreforfilter.= '
    ';*/ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; +else $moreforfilter = $hookmanager->resPrint; + +if (!empty($moreforfilter)) +{ + print '
    '; + print $moreforfilter; + print '
    '; +} + +$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); + +print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table +print ''."\n"; + + +// Fields title search +// -------------------------------------------------------------------- +print ''; +foreach ($object->fields as $key => $val) +{ + $cssforfield = (empty($val['css']) ? '' : $val['css']); + if ($key == 'status') $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield .= ($cssforfield ? ' ' : '').'right'; + if (!empty($arrayfields['t.'.$key]['checked'])) + { + print ''; + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + +// Fields from hook +$parameters = array('arrayfields'=>$arrayfields); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +// Action column +print ''; +print ''."\n"; + + +// Fields title label +// -------------------------------------------------------------------- +print ''; +foreach ($object->fields as $key => $val) +{ + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if ($key == 'status') $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield .= ($cssforfield ? ' ' : '').'right'; + if (!empty($arrayfields['t.'.$key]['checked'])) + { + print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; +// Hook fields +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +// Action column +print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +print ''."\n"; + + +// Detect if we need a fetch on each output line +$needToFetchEachLine = 0; +if (is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) +{ + foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) + { + if (preg_match('/\$object/', $val)) $needToFetchEachLine++; // There is at least one compute field that use $object + } +} + + +// Loop on record +// -------------------------------------------------------------------- +$i = 0; +$totalarray = array(); +while ($i < ($limit ? min($num, $limit) : $num)) +{ + $obj = $db->fetch_object($resql); + if (empty($obj)) break; // Should not happen + + // Store properties in $object + $object->setVarsFromFetchObj($obj); + + // Show here line of result + print ''; + foreach ($object->fields as $key => $val) + { + $cssforfield = (empty($val['css']) ? '' : $val['css']); + if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif ($key == 'status') $cssforfield .= ($cssforfield ? ' ' : '').'center'; + + if (in_array($val['type'], array('timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + elseif ($key == 'ref') $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status'))) $cssforfield .= ($cssforfield ? ' ' : '').'right'; + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; + + if (!empty($arrayfields['t.'.$key]['checked'])) + { + print ''; + if ($key == 'status') print $object->getLibStatut(5); + else print $object->showOutputField($val, $key, $object->$key, ''); + print ''; + if (!$i) $totalarray['nbfield']++; + if (!empty($val['isameasure'])) + { + if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + $totalarray['val']['t.'.$key] += $object->$key; + } + } + } + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column + print ''; + if (!$i) $totalarray['nbfield']++; + + print ''."\n"; + + $i++; +} + +// Show total line +include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + +// If no record found +if ($num == 0) +{ + $colspan = 1; + foreach ($arrayfields as $key => $val) { if (!empty($val['checked'])) $colspan++; } + print ''; +} + + +$db->free($resql); + +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print '
    '; + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + elseif (strpos($val['type'], 'integer:') === 0) { + print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth125', 1); + } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) print ''; + print ''; +$searchpicto = $form->showFilterButtons(); +print $searchpicto; +print '
    '; + if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected = 0; + if (in_array($object->id, $arrayofselected)) $selected = 1; + print ''; + } + print '
    '.$langs->trans("NoRecordFound").'
    '."\n"; +print '
    '."\n"; + +print '
    '."\n"; + +if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) +{ + $hidegeneratedfilelistifempty = 1; + if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) $hidegeneratedfilelistifempty = 0; + + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; + $formfile = new FormFile($db); + + // Show list of available documents + $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; + $urlsource .= str_replace('&', '&', $param); + + $filedir = $diroutputmassaction; + $genallowed = $permissiontoread; + $delallowed = $permissiontoadd; + + print $formfile->showdocuments('massfilesarea_workstation', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/workstation/workstation_note.php b/htdocs/workstation/workstation_note.php new file mode 100755 index 00000000000..b8e85ddaf6f --- /dev/null +++ b/htdocs/workstation/workstation_note.php @@ -0,0 +1,183 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 workstation_note.php + * \ingroup workstation + * \brief Tab for notes on Workstation + */ + +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies +//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +// Try main.inc.php using relative path +if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; +if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; +if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; +if (!$res) die("Include of main fails"); + +dol_include_once('/workstation/class/workstation.class.php'); +dol_include_once('/workstation/lib/workstation_workstation.lib.php'); + +// Load translation files required by the page +$langs->loadLangs(array("workstation@workstation", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Workstation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('workstationnote', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$result = restrictedArea($user, 'workstation', $id); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) $upload_dir = $conf->workstation->multidir_output[$object->entity]."/".$object->id; + +$permissionnote = $user->rights->workstation->workstation->write; // Used by the include of actions_setnotes.inc.php +$permissiontoadd = $user->rights->workstation->workstation->write; // Used by the include of actions_addupdatedelete.inc.php + + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once + + +/* + * View + */ + +$form = new Form($db); + +//$help_url='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; +$help_url = ''; +llxHeader('', $langs->trans('Workstation'), $help_url); + +if ($id > 0 || !empty($ref)) +{ + $object->fetch_thirdparty(); + + $head = workstationPrepareHead($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("Workstation"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + /* + // Ref customer + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
    '.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + if ($action != 'classify') + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + $morehtmlref.=' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='
    '; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.='
    '; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
    '; + print '
    '; + + + $cssclass = "titlefield"; + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + print '
    '; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); From da9defe0ce2c120f35b6b170ae42b81279959166 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 21 Dec 2020 11:34:51 +0000 Subject: [PATCH 02/28] Fixing style errors. --- .../resource/class/html.formresource.class.php | 2 +- htdocs/workstation/class/workstation.class.php | 12 ++++++------ .../class/workstationresource.class.php | 15 +++++++-------- .../class/workstationusergroup.class.php | 15 +++++++-------- htdocs/workstation/workstation_card.php | 17 +++++------------ htdocs/workstation/workstation_list.php | 2 +- 6 files changed, 27 insertions(+), 36 deletions(-) diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php index 46085c126e0..4a9b467c32c 100644 --- a/htdocs/resource/class/html.formresource.class.php +++ b/htdocs/resource/class/html.formresource.class.php @@ -77,7 +77,7 @@ class FormResource * @param string $morecss More css * @return string HTML string with */ - public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '', $multiple=false) + public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '', $multiple = false) { // phpcs:enable global $conf, $user, $langs; diff --git a/htdocs/workstation/class/workstation.class.php b/htdocs/workstation/class/workstation.class.php index acedb6759d9..42533c4100f 100755 --- a/htdocs/workstation/class/workstation.class.php +++ b/htdocs/workstation/class/workstation.class.php @@ -233,8 +233,8 @@ class Workstation extends CommonObject // Usergroups $groups = GETPOST('groups'); - if(empty($groups)) $groups = $this->usergroups; // createFromClone - if(!empty($groups)) { + if (empty($groups)) $groups = $this->usergroups; // createFromClone + if (!empty($groups)) { foreach ($groups as $id_group) { $ws_usergroup = new WorkstationUserGroup($db); $ws_usergroup->fk_workstation = $id; @@ -246,8 +246,8 @@ class Workstation extends CommonObject // Resources $resources = GETPOST('resources'); - if(empty($resources)) $resources = $this->resources; // createFromClone - if(!empty($resources)) { + if (empty($resources)) $resources = $this->resources; // createFromClone + if (!empty($resources)) { foreach ($resources as $id_resource) { $ws_resource = new WorkstationResource($db); $ws_resource->fk_workstation = $id; @@ -490,7 +490,7 @@ class Workstation extends CommonObject $resources = GETPOST('resources'); WorkstationResource::deleteAllResourcesOfWorkstation($this->id); $this->resources=array(); - if(!empty($resources)) { + if (!empty($resources)) { foreach ($resources as $id_resource) { $ws_resource = new WorkstationResource($this->db); $ws_resource->fk_workstation = $this->id; @@ -677,7 +677,7 @@ class Workstation extends CommonObject $this->status = $status; - if(empty($status)) $this->setDisabled($user, $notrigger); + if (empty($status)) $this->setDisabled($user, $notrigger); else $this->setEnabled($user, $notrigger); } diff --git a/htdocs/workstation/class/workstationresource.class.php b/htdocs/workstation/class/workstationresource.class.php index 2cae732377a..b9897b6f541 100644 --- a/htdocs/workstation/class/workstationresource.class.php +++ b/htdocs/workstation/class/workstationresource.class.php @@ -46,7 +46,8 @@ class WorkstationResource extends CommonObject } } - static public function getAllResourcesOfWorkstation($fk_workstation) { + static public function getAllResourcesOfWorkstation($fk_workstation) + { global $db; @@ -55,17 +56,17 @@ class WorkstationResource extends CommonObject $resql = $db->query($sql); $TRes = array(); - if(!empty($resql)) { - while($res = $db->fetch_object($resql)) { + if (!empty($resql)) { + while ($res = $db->fetch_object($resql)) { $TRes[] = $res->fk_resource; } } return $TRes; - } - static public function deleteAllResourcesOfWorkstation($fk_workstation) { + static public function deleteAllResourcesOfWorkstation($fk_workstation) + { global $db; @@ -73,10 +74,8 @@ class WorkstationResource extends CommonObject $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; $resql = $db->query($sql); - if(empty($resql)) return 0; + if (empty($resql)) return 0; return 1; - } - } diff --git a/htdocs/workstation/class/workstationusergroup.class.php b/htdocs/workstation/class/workstationusergroup.class.php index af643a6d28e..1221476203c 100644 --- a/htdocs/workstation/class/workstationusergroup.class.php +++ b/htdocs/workstation/class/workstationusergroup.class.php @@ -46,7 +46,8 @@ class WorkstationUserGroup extends CommonObject } } - static public function getAllGroupsOfWorkstation($fk_workstation) { + static public function getAllGroupsOfWorkstation($fk_workstation) + { global $db; @@ -55,17 +56,17 @@ class WorkstationUserGroup extends CommonObject $resql = $db->query($sql); $TRes = array(); - if(!empty($resql)) { - while($res = $db->fetch_object($resql)) { + if (!empty($resql)) { + while ($res = $db->fetch_object($resql)) { $TRes[] = $res->fk_usergroup; } } return $TRes; - } - static public function deleteAllGroupsOfWorkstation($fk_workstation) { + static public function deleteAllGroupsOfWorkstation($fk_workstation) + { global $db; @@ -73,10 +74,8 @@ class WorkstationUserGroup extends CommonObject $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; $resql = $db->query($sql); - if(empty($resql)) return 0; + if (empty($resql)) return 0; return 1; - } - } diff --git a/htdocs/workstation/workstation_card.php b/htdocs/workstation/workstation_card.php index 5ec3a1f6842..d28aecce67d 100755 --- a/htdocs/workstation/workstation_card.php +++ b/htdocs/workstation/workstation_card.php @@ -161,15 +161,10 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; if ($action == 'confirm_enable' && $confirm == "yes" && $permissiontoadd) { - - if(!empty($object->id)) $object->setStatus(1); - + if (!empty($object->id)) $object->setStatus(1); } elseif ($action == 'confirm_disable' && $confirm == "yes" && $permissiontoadd) { - - if(!empty($object->id)) $object->setStatus(0); - + if (!empty($object->id)) $object->setStatus(0); } - } @@ -418,11 +413,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field //unset($object->fields['fk_project']); // Hide field already shown in banner //unset($object->fields['fk_soc']); // Hide field already shown in banner - if($object->type === 'MACHINE') $object->fields['nb_operators_required']['visible'] = 0; + if ($object->type === 'MACHINE') $object->fields['nb_operators_required']['visible'] = 0; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; // Groups - if($object->type !== 'MACHINE') { + if ($object->type !== 'MACHINE') { $toprint = array(); foreach ($object->usergroups as $id_group) { $g = new UserGroup($db); @@ -435,7 +430,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Resources - if($object->type !== 'HUMAN') { + if ($object->type !== 'HUMAN') { $toprint = array(); foreach ($object->resources as $id_resource) { $r = new Dolresource($db); @@ -469,7 +464,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (empty($reshook)) { - // Modify if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; @@ -503,7 +497,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print ''."\n"; } - } // End of page diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php index c9aa575fad2..c544446aabb 100755 --- a/htdocs/workstation/workstation_list.php +++ b/htdocs/workstation/workstation_list.php @@ -116,7 +116,7 @@ $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') $search[$key] = GETPOST('search_'.$key, 'alpha'); - if(in_array($key, array('type', 'status')) && GETPOST('search_'.$key, 'alpha') == -1) $search[$key] = ''; + if (in_array($key, array('type', 'status')) && GETPOST('search_'.$key, 'alpha') == -1) $search[$key] = ''; } // List of fields to search into when doing a "search in all" From 5d23ab19828cd62d19f7b73caecec8c6150612dc Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 21 Dec 2020 12:38:13 +0100 Subject: [PATCH 03/28] FIX : file .back --- .../class/workstation.class.php.back | 1052 ----------------- 1 file changed, 1052 deletions(-) delete mode 100755 htdocs/workstation/class/workstation.class.php.back diff --git a/htdocs/workstation/class/workstation.class.php.back b/htdocs/workstation/class/workstation.class.php.back deleted file mode 100755 index f4666c352ce..00000000000 --- a/htdocs/workstation/class/workstation.class.php.back +++ /dev/null @@ -1,1052 +0,0 @@ - - * Copyright (C) ---Put here your own copyright and developer email--- - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 class/workstation.class.php - * \ingroup workstation - * \brief This file is a CRUD class file for Workstation (Create/Read/Update/Delete) - */ - -// Put here all includes required by your class file -require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; -//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; -//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; - -/** - * Class for Workstation - */ -class Workstation extends CommonObject -{ - /** - * @var string ID of module. - */ - public $module = 'workstation'; - - /** - * @var string ID to identify managed object. - */ - public $element = 'workstation'; - - /** - * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. - */ - public $table_element = 'workstation_workstation'; - - /** - * @var int Does this object support multicompany module ? - * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table - */ - public $ismultientitymanaged = 0; - - /** - * @var int Does object support extrafields ? 0=No, 1=Yes - */ - public $isextrafieldmanaged = 1; - - /** - * @var string String with name of icon for workstation. Must be the part after the 'object_' into object_workstation.png - */ - public $picto = 'workstation@workstation'; - - - const STATUS_DRAFT = 0; - const STATUS_VALIDATED = 1; - const STATUS_CANCELED = 9; - - - /** - * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') - * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" - * 'label' the translation key. - * 'picto' is code of a picto to show before value in forms - * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) - * 'position' is the sort order of field. - * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). - * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) - * 'noteditable' says if field is not editable (1 or 0) - * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. - * 'index' if we want an index in database. - * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). - * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. - * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). - * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'maxwidth200', 'wordbreak', 'tdoverflowmax200' - * 'help' is a string visible as a tooltip on field - * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record - * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. - * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") - * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. - * 'comment' is not used. You can store here any text of your choice. It is not used by application. - * - * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. - */ - - // BEGIN MODULEBUILDER PROPERTIES - /** - * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. - */ - public $fields=array( - 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), - 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'help'=>"Help text", 'showoncombobox'=>'1',), - 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), - 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), - 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), - 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), - 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), - 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), - 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), - 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), - 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Brouillon', '1'=>'Validé', '9'=>'Annulé'),), - 'nb_operators_required' => array('type'=>'integer', 'label'=>'NbOperatorsRequired', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), - 'thm_operator_estimated' => array('type'=>'double', 'label'=>'THMOperatorEstimated', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), - 'thm_machine_estimated' => array('type'=>'double', 'label'=>'THMMachineEstimated', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), - ); - public $rowid; - public $ref; - public $label; - public $description; - public $note_public; - public $note_private; - public $date_creation; - public $tms; - public $fk_user_creat; - public $fk_user_modif; - public $import_key; - public $status; - public $nb_operators_required; - public $thm_operator_estimated; - public $thm_machine_estimated; - // END MODULEBUILDER PROPERTIES - - - // If this object has a subtable with lines - - /** - * @var int Name of subtable line - */ - //public $table_element_line = 'workstation_workstationline'; - - /** - * @var int Field with ID of parent key if this object has a parent - */ - //public $fk_element = 'fk_workstation'; - - /** - * @var int Name of subtable class that manage subtable lines - */ - //public $class_element_line = 'Workstationline'; - - /** - * @var array List of child tables. To test if we can delete object. - */ - //protected $childtables = array(); - - /** - * @var array List of child tables. To know object to delete on cascade. - * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will - * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object - */ - //protected $childtablesoncascade = array('workstation_workstationdet'); - - /** - * @var WorkstationLine[] Array of subtable lines - */ - //public $lines = array(); - - - - /** - * Constructor - * - * @param DoliDb $db Database handler - */ - public function __construct(DoliDB $db) - { - global $conf, $langs; - - $this->db = $db; - - if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0; - if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0; - - // Example to show how to set values of fields definition dynamically - /*if ($user->rights->workstation->workstation->read) { - $this->fields['myfield']['visible'] = 1; - $this->fields['myfield']['noteditable'] = 0; - }*/ - - // Unset fields that are disabled - foreach ($this->fields as $key => $val) - { - if (isset($val['enabled']) && empty($val['enabled'])) - { - unset($this->fields[$key]); - } - } - - // Translate some data of arrayofkeyval - if (is_object($langs)) - { - foreach ($this->fields as $key => $val) - { - if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) - { - foreach ($val['arrayofkeyval'] as $key2 => $val2) - { - $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); - } - } - } - } - } - - /** - * Create object into database - * - * @param User $user User that creates - * @param bool $notrigger false=launch triggers after, true=disable triggers - * @return int <0 if KO, Id of created object if OK - */ - public function create(User $user, $notrigger = false) - { - return $this->createCommon($user, $notrigger); - } - - /** - * Clone an object into another one - * - * @param User $user User that creates - * @param int $fromid Id of object to clone - * @return mixed New object created, <0 if KO - */ - public function createFromClone(User $user, $fromid) - { - global $langs, $extrafields; - $error = 0; - - dol_syslog(__METHOD__, LOG_DEBUG); - - $object = new self($this->db); - - $this->db->begin(); - - // Load source object - $result = $object->fetchCommon($fromid); - if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines(); - - // get lines so they will be clone - //foreach($this->lines as $line) - // $line->fetch_optionals(); - - // Reset some properties - unset($object->id); - unset($object->fk_user_creat); - unset($object->import_key); - - // Clear fields - if (property_exists($object, 'ref')) $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; - if (property_exists($object, 'label')) $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; - if (property_exists($object, 'status')) { $object->status = self::STATUS_DRAFT; } - if (property_exists($object, 'date_creation')) { $object->date_creation = dol_now(); } - if (property_exists($object, 'date_modification')) { $object->date_modification = null; } - // ... - // Clear extrafields that are unique - if (is_array($object->array_options) && count($object->array_options) > 0) - { - $extrafields->fetch_name_optionals_label($this->table_element); - foreach ($object->array_options as $key => $option) - { - $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) - { - //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; - unset($object->array_options[$key]); - } - } - } - - // Create clone - $object->context['createfromclone'] = 'createfromclone'; - $result = $object->createCommon($user); - if ($result < 0) { - $error++; - $this->error = $object->error; - $this->errors = $object->errors; - } - - if (!$error) - { - // copy internal contacts - if ($this->copy_linked_contact($object, 'internal') < 0) - { - $error++; - } - } - - if (!$error) - { - // copy external contacts if same company - if (property_exists($this, 'socid') && $this->socid == $object->socid) - { - if ($this->copy_linked_contact($object, 'external') < 0) - $error++; - } - } - - unset($object->context['createfromclone']); - - // End - if (!$error) { - $this->db->commit(); - return $object; - } else { - $this->db->rollback(); - return -1; - } - } - - /** - * Load object in memory from the database - * - * @param int $id Id object - * @param string $ref Ref - * @return int <0 if KO, 0 if not found, >0 if OK - */ - public function fetch($id, $ref = null) - { - $result = $this->fetchCommon($id, $ref); - if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines(); - return $result; - } - - /** - * Load object lines in memory from the database - * - * @return int <0 if KO, 0 if not found, >0 if OK - */ - public function fetchLines() - { - $this->lines = array(); - - $result = $this->fetchLinesCommon(); - return $result; - } - - - /** - * Load list of objects in memory from the database. - * - * @param string $sortorder Sort Order - * @param string $sortfield Sort field - * @param int $limit limit - * @param int $offset Offset - * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) - * @param string $filtermode Filter mode (AND or OR) - * @return array|int int <0 if KO, array of pages if OK - */ - public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') - { - global $conf; - - dol_syslog(__METHOD__, LOG_DEBUG); - - $records = array(); - - $sql = 'SELECT '; - $sql .= $this->getFieldList(); - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')'; - else $sql .= ' WHERE 1 = 1'; - // Manage filter - $sqlwhere = array(); - if (count($filter) > 0) { - foreach ($filter as $key => $value) { - if ($key == 't.rowid') { - $sqlwhere[] = $key.'='.$value; - } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) { - $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; - } elseif ($key == 'customsql') { - $sqlwhere[] = $value; - } elseif (strpos($value, '%') === false) { - $sqlwhere[] = $key.' IN ('.$this->db->sanitize($this->db->escape($value)).')'; - } else { - $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; - } - } - } - if (count($sqlwhere) > 0) { - $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; - } - - if (!empty($sortfield)) { - $sql .= $this->db->order($sortfield, $sortorder); - } - if (!empty($limit)) { - $sql .= ' '.$this->db->plimit($limit, $offset); - } - - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < ($limit ? min($limit, $num) : $num)) - { - $obj = $this->db->fetch_object($resql); - - $record = new self($this->db); - $record->setVarsFromFetchObj($obj); - - $records[$record->id] = $record; - - $i++; - } - $this->db->free($resql); - - return $records; - } else { - $this->errors[] = 'Error '.$this->db->lasterror(); - dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); - - return -1; - } - } - - /** - * Update object into database - * - * @param User $user User that modifies - * @param bool $notrigger false=launch triggers after, true=disable triggers - * @return int <0 if KO, >0 if OK - */ - public function update(User $user, $notrigger = false) - { - return $this->updateCommon($user, $notrigger); - } - - /** - * Delete object in database - * - * @param User $user User that deletes - * @param bool $notrigger false=launch triggers after, true=disable triggers - * @return int <0 if KO, >0 if OK - */ - public function delete(User $user, $notrigger = false) - { - return $this->deleteCommon($user, $notrigger); - //return $this->deleteCommon($user, $notrigger, 1); - } - - /** - * Delete a line of object in database - * - * @param User $user User that delete - * @param int $idline Id of line to delete - * @param bool $notrigger false=launch triggers after, true=disable triggers - * @return int >0 if OK, <0 if KO - */ - public function deleteLine(User $user, $idline, $notrigger = false) - { - if ($this->status < 0) - { - $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; - return -2; - } - - return $this->deleteLineCommon($user, $idline, $notrigger); - } - - - /** - * Validate object - * - * @param User $user User making status change - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <=0 if OK, 0=Nothing done, >0 if KO - */ - public function validate($user, $notrigger = 0) - { - global $conf, $langs; - - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $error = 0; - - // Protection - if ($this->status == self::STATUS_VALIDATED) - { - dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); - return 0; - } - - /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation->write)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation->workstation_advance->validate)))) - { - $this->error='NotEnoughPermissions'; - dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); - return -1; - }*/ - - $now = dol_now(); - - $this->db->begin(); - - // Define new ref - if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life - { - $num = $this->getNextNumRef(); - } else { - $num = $this->ref; - } - $this->newref = $num; - - if (!empty($num)) { - // Validate - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET ref = '".$this->db->escape($num)."',"; - $sql .= " status = ".self::STATUS_VALIDATED; - if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."'"; - if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".$user->id; - $sql .= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::validate()", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) - { - dol_print_error($this->db); - $this->error = $this->db->lasterror(); - $error++; - } - - if (!$error && !$notrigger) - { - // Call trigger - $result = $this->call_trigger('WORKSTATION_VALIDATE', $user); - if ($result < 0) $error++; - // End call triggers - } - } - - if (!$error) - { - $this->oldref = $this->ref; - - // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - // Now we rename also files into index - $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'workstation/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'workstation/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; - $resql = $this->db->query($sql); - if (!$resql) { $error++; $this->error = $this->db->lasterror(); } - - // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments - $oldref = dol_sanitizeFileName($this->ref); - $newref = dol_sanitizeFileName($num); - $dirsource = $conf->workstation->dir_output.'/workstation/'.$oldref; - $dirdest = $conf->workstation->dir_output.'/workstation/'.$newref; - if (!$error && file_exists($dirsource)) - { - dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); - - if (@rename($dirsource, $dirdest)) - { - dol_syslog("Rename ok"); - // Rename docs starting with $oldref with $newref - $listoffiles = dol_dir_list($conf->workstation->dir_output.'/workstation/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); - foreach ($listoffiles as $fileentry) - { - $dirsource = $fileentry['name']; - $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); - $dirsource = $fileentry['path'].'/'.$dirsource; - $dirdest = $fileentry['path'].'/'.$dirdest; - @rename($dirsource, $dirdest); - } - } - } - } - } - - // Set new ref and current status - if (!$error) - { - $this->ref = $num; - $this->status = self::STATUS_VALIDATED; - } - - if (!$error) - { - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - return -1; - } - } - - - /** - * Set draft status - * - * @param User $user Object user that modify - * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers - * @return int <0 if KO, >0 if OK - */ - public function setDraft($user, $notrigger = 0) - { - // Protection - if ($this->status <= self::STATUS_DRAFT) - { - return 0; - } - - /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->write)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation_advance->validate)))) - { - $this->error='Permission denied'; - return -1; - }*/ - - return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'WORKSTATION_UNVALIDATE'); - } - - /** - * Set cancel status - * - * @param User $user Object user that modify - * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers - * @return int <0 if KO, 0=Nothing done, >0 if OK - */ - public function cancel($user, $notrigger = 0) - { - // Protection - if ($this->status != self::STATUS_VALIDATED) - { - return 0; - } - - /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->write)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation_advance->validate)))) - { - $this->error='Permission denied'; - return -1; - }*/ - - return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'WORKSTATION_CLOSE'); - } - - /** - * Set back to validated status - * - * @param User $user Object user that modify - * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers - * @return int <0 if KO, 0=Nothing done, >0 if OK - */ - public function reopen($user, $notrigger = 0) - { - // Protection - if ($this->status != self::STATUS_CANCELED) - { - return 0; - } - - /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->write)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->workstation->workstation_advance->validate)))) - { - $this->error='Permission denied'; - return -1; - }*/ - - return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'WORKSTATION_REOPEN'); - } - - /** - * Return a link to the object card (with optionaly the picto) - * - * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) - * @param string $option On what the link point to ('nolink', ...) - * @param int $notooltip 1=Disable tooltip - * @param string $morecss Add more css on link - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string String with URL - */ - public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) - { - global $conf, $langs, $hookmanager; - - if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips - - $result = ''; - - $label = img_picto('', $this->picto).' '.$langs->trans("Workstation").''; - $label .= '
    '; - $label .= ''.$langs->trans('Ref').': '.$this->ref; - if (isset($this->status)) { - $label .= '
    '.$langs->trans("Status").": ".$this->getLibStatut(5); - } - - $url = dol_buildpath('/workstation/workstation_card.php', 1).'?id='.$this->id; - - if ($option != 'nolink') - { - // Add param to save lastsearch_values or not - $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; - if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; - } - - $linkclose = ''; - if (empty($notooltip)) - { - if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label = $langs->trans("ShowWorkstation"); - $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); - - $linkstart = ''; - $linkend = ''; - - $result .= $linkstart; - - if (empty($this->showphoto_on_popup)) { - if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); - } else { - if ($withpicto) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - list($class, $module) = explode('@', $this->picto); - $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); - $filearray = dol_dir_list($upload_dir, "files"); - $filename = $filearray[0]['name']; - if (!empty($filename)) { - $pospoint = strpos($filearray[0]['name'], '.'); - - $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); - if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { - $result .= '
    No photo
    '; - } else { - $result .= '
    No photo
    '; - } - - $result .= ''; - } else { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); - } - } - } - - if ($withpicto != 2) $result .= $this->ref; - - $result .= $linkend; - //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); - - global $action, $hookmanager; - $hookmanager->initHooks(array('workstationdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); - $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $result = $hookmanager->resPrint; - else $result .= $hookmanager->resPrint; - - return $result; - } - - /** - * Return the label of the status - * - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto - * @return string Label of status - */ - public function getLibStatut($mode = 0) - { - return $this->LibStatut($this->status, $mode); - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return the status - * - * @param int $status Id status - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto - * @return string Label of status - */ - public function LibStatut($status, $mode = 0) - { - // phpcs:enable - if (empty($this->labelStatus) || empty($this->labelStatusShort)) - { - global $langs; - //$langs->load("workstation@workstation"); - $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); - $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); - } - - $statusType = 'status'.$status; - //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; - if ($status == self::STATUS_CANCELED) $statusType = 'status6'; - - return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); - } - - /** - * Load the info information in the object - * - * @param int $id Id of object - * @return void - */ - public function info($id) - { - $sql = 'SELECT rowid, date_creation as datec, tms as datem,'; - $sql .= ' fk_user_creat, fk_user_modif'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; - $sql .= ' WHERE t.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; - if ($obj->fk_user_author) - { - $cuser = new User($this->db); - $cuser->fetch($obj->fk_user_author); - $this->user_creation = $cuser; - } - - if ($obj->fk_user_valid) - { - $vuser = new User($this->db); - $vuser->fetch($obj->fk_user_valid); - $this->user_validation = $vuser; - } - - if ($obj->fk_user_cloture) - { - $cluser = new User($this->db); - $cluser->fetch($obj->fk_user_cloture); - $this->user_cloture = $cluser; - } - - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_modification = $this->db->jdate($obj->datem); - $this->date_validation = $this->db->jdate($obj->datev); - } - - $this->db->free($result); - } else { - dol_print_error($this->db); - } - } - - /** - * Initialise object with example values - * Id must be 0 if object instance is a specimen - * - * @return void - */ - public function initAsSpecimen() - { - $this->initAsSpecimenCommon(); - } - - /** - * Create an array of lines - * - * @return array|int array of lines if OK, <0 if KO - */ - public function getLinesArray() - { - $this->lines = array(); - - $objectline = new WorkstationLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_workstation = '.$this->id)); - - if (is_numeric($result)) - { - $this->error = $this->error; - $this->errors = $this->errors; - return $result; - } else { - $this->lines = $result; - return $this->lines; - } - } - - /** - * Returns the reference to the following non used object depending on the active numbering module. - * - * @return string Object free reference - */ - public function getNextNumRef() - { - global $langs, $conf; - $langs->load("workstation@workstation"); - - if (empty($conf->global->WORKSTATION_WORKSTATION_ADDON)) { - $conf->global->WORKSTATION_WORKSTATION_ADDON = 'mod_workstation_standard'; - } - - if (!empty($conf->global->WORKSTATION_WORKSTATION_ADDON)) - { - $mybool = false; - - $file = $conf->global->WORKSTATION_WORKSTATION_ADDON.".php"; - $classname = $conf->global->WORKSTATION_WORKSTATION_ADDON; - - // Include file with class - $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) - { - $dir = dol_buildpath($reldir."core/modules/workstation/"); - - // Load file with numbering class (if found) - $mybool |= @include_once $dir.$file; - } - - if ($mybool === false) - { - dol_print_error('', "Failed to include file ".$file); - return ''; - } - - if (class_exists($classname)) { - $obj = new $classname(); - $numref = $obj->getNextValue($this); - - if ($numref != '' && $numref != '-1') - { - return $numref; - } else { - $this->error = $obj->error; - //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); - return ""; - } - } else { - print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; - return ""; - } - } else { - print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); - return ""; - } - } - - /** - * Create a document onto disk according to template module. - * - * @param string $modele Force template to use ('' to not force) - * @param Translate $outputlangs objet lang a utiliser pour traduction - * @param int $hidedetails Hide details of lines - * @param int $hidedesc Hide description - * @param int $hideref Hide ref - * @param null|array $moreparams Array to provide more information - * @return int 0 if KO, 1 if OK - */ - public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) - { - global $conf, $langs; - - $result = 0; - $includedocgeneration = 0; - - $langs->load("workstation@workstation"); - - if (!dol_strlen($modele)) { - $modele = 'standard_workstation'; - - if ($this->model_pdf) { - $modele = $this->model_pdf; - } elseif (!empty($conf->global->WORKSTATION_ADDON_PDF)) { - $modele = $conf->global->WORKSTATION_ADDON_PDF; - } - } - - $modelpath = "core/modules/workstation/doc/"; - - if ($includedocgeneration) { - $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); - } - - return $result; - } - - /** - * Action executed by scheduler - * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' - * Use public function doScheduledJob($param1, $param2, ...) to get parameters - * - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) - */ - public function doScheduledJob() - { - global $conf, $langs; - - //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; - - $error = 0; - $this->output = ''; - $this->error = ''; - - dol_syslog(__METHOD__, LOG_DEBUG); - - $now = dol_now(); - - $this->db->begin(); - - // ... - - $this->db->commit(); - - return $error; - } -} - - -require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; - -/** - * Class WorkstationLine. You can also remove this and generate a CRUD class for lines objects. - */ -class WorkstationLine extends CommonObjectLine -{ - // To complete with content of an object WorkstationLine - // We should have a field rowid, fk_workstation and position - - /** - * @var int Does object support extrafields ? 0=No, 1=Yes - */ - public $isextrafieldmanaged = 0; - - /** - * Constructor - * - * @param DoliDb $db Database handler - */ - public function __construct(DoliDB $db) - { - $this->db = $db; - } -} From 5116337e0bcd2f47958157ab982b3e3ef10ad5dd Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 21 Dec 2020 13:29:44 +0100 Subject: [PATCH 04/28] FIX : stickler feedbacks --- htdocs/admin/workstation.php | 2 +- htdocs/core/modules/modWorkstation.class.php | 2 +- .../workstation/mod_workstation_advanced.php | 1 + .../workstation/mod_workstation_standard.php | 1 + .../workstation/modules_workstation.php | 1 + .../llx_workstation_workstation.key.sql | 2 +- .../tables/llx_workstation_workstation.sql | 2 +- .../llx_workstation_workstation_resource.sql | 2 +- ...llx_workstation_workstation_user_group.sql | 2 +- .../class/html.formresource.class.php | 1 + .../workstation/class/workstation.class.php | 8 ++--- .../class/workstationresource.class.php | 36 +++++++++++++++++++ .../class/workstationusergroup.class.php | 36 +++++++++++++++++++ htdocs/workstation/lib/workstation.lib.php | 2 +- .../lib/workstation_workstation.lib.php | 2 +- htdocs/workstation/workstation_agenda.php | 2 +- htdocs/workstation/workstation_card.php | 4 +-- htdocs/workstation/workstation_document.php | 2 +- htdocs/workstation/workstation_list.php | 2 +- htdocs/workstation/workstation_note.php | 2 +- 20 files changed, 94 insertions(+), 18 deletions(-) diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index 8f9ee369d4f..502a573e98b 100755 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -1,6 +1,6 @@ - * Copyright (C) 2020 SuperAdmin + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php index 216d591670a..499dcc5de48 100755 --- a/htdocs/core/modules/modWorkstation.class.php +++ b/htdocs/core/modules/modWorkstation.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2004-2018 Laurent Destailleur * Copyright (C) 2018-2019 Nicolas ZABOURI * Copyright (C) 2019-2020 Frédéric France - * Copyright (C) 2020 SuperAdmin + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/core/modules/workstation/mod_workstation_advanced.php b/htdocs/core/modules/workstation/mod_workstation_advanced.php index d9133b4063c..cf9a1247e2b 100755 --- a/htdocs/core/modules/workstation/mod_workstation_advanced.php +++ b/htdocs/core/modules/workstation/mod_workstation_advanced.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2019 Frédéric France + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/core/modules/workstation/mod_workstation_standard.php b/htdocs/core/modules/workstation/mod_workstation_standard.php index 87e94233c88..0e793953f46 100755 --- a/htdocs/core/modules/workstation/mod_workstation_standard.php +++ b/htdocs/core/modules/workstation/mod_workstation_standard.php @@ -1,6 +1,7 @@ * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/core/modules/workstation/modules_workstation.php b/htdocs/core/modules/workstation/modules_workstation.php index bfd0f6c95ea..ec6c2fc945b 100755 --- a/htdocs/core/modules/workstation/modules_workstation.php +++ b/htdocs/core/modules/workstation/modules_workstation.php @@ -6,6 +6,7 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2014 Marcos García + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql index 2e013ee0128..6bdf16aa6d7 100755 --- a/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql +++ b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql @@ -1,4 +1,4 @@ --- Copyright (C) ---Put here your own copyright and developer email--- +-- Copyright (C) 2020 Gauthier VERDOL -- -- 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 diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.sql index 5c141ed59df..a4d9fd4dbc8 100755 --- a/htdocs/install/mysql/tables/llx_workstation_workstation.sql +++ b/htdocs/install/mysql/tables/llx_workstation_workstation.sql @@ -1,4 +1,4 @@ --- Copyright (C) ---Put here your own copyright and developer email--- +-- Copyright (C) 2020 Gauthier VERDOL -- -- 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 diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql index 1ab019f4385..92463ade696 100755 --- a/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql +++ b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql @@ -1,4 +1,4 @@ --- Copyright (C) ---Put here your own copyright and developer email--- +-- Copyright (C) 2020 Gauthier VERDOL -- -- 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 diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql index 9bffb4f30c9..9ecccc88d82 100755 --- a/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql +++ b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql @@ -1,4 +1,4 @@ --- Copyright (C) ---Put here your own copyright and developer email--- +-- Copyright (C) 2020 Gauthier VERDOL -- -- 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 diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php index 4a9b467c32c..30d7a13a194 100644 --- a/htdocs/resource/class/html.formresource.class.php +++ b/htdocs/resource/class/html.formresource.class.php @@ -75,6 +75,7 @@ class FormResource * @param int $outputmode 0=HTML select string, 1=Array, 2=without form tag * @param int $limit Limit number of answers * @param string $morecss More css + * @param bool $multiple add [] in the name of element and add 'multiple' attribut * @return string HTML string with */ public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '', $multiple = false) diff --git a/htdocs/workstation/class/workstation.class.php b/htdocs/workstation/class/workstation.class.php index 42533c4100f..31497cbc919 100755 --- a/htdocs/workstation/class/workstation.class.php +++ b/htdocs/workstation/class/workstation.class.php @@ -1,6 +1,6 @@ - * Copyright (C) ---Put here your own copyright and developer email--- + * Copyright (C) 2020 Gauthier VERDOL * * 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 @@ -667,7 +667,7 @@ class Workstation extends CommonObject /** * Set draft status * - * @param User $user Object user that modify + * @param int $status New status to set * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers * @return int <0 if KO, >0 if OK */ @@ -677,8 +677,8 @@ class Workstation extends CommonObject $this->status = $status; - if (empty($status)) $this->setDisabled($user, $notrigger); - else $this->setEnabled($user, $notrigger); + if (empty($status)) return $this->setDisabled($user, $notrigger); + else return $this->setEnabled($user, $notrigger); } diff --git a/htdocs/workstation/class/workstationresource.class.php b/htdocs/workstation/class/workstationresource.class.php index b9897b6f541..cfb6706058d 100644 --- a/htdocs/workstation/class/workstationresource.class.php +++ b/htdocs/workstation/class/workstationresource.class.php @@ -1,4 +1,30 @@ + * Copyright (C) 2020 Gauthier VERDOL + * + * 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 class/workstationresource.class.php + * \ingroup workstation + * \brief This file is a CRUD class file for WorkstationResource (Create/Read/Update/Delete) + */ + +/** + * Class for WorkstationResource + */ class WorkstationResource extends CommonObject { @@ -46,6 +72,11 @@ class WorkstationResource extends CommonObject } } + /** + * Function used to get an array with all resources linked to a workstation + * @param int $fk_workstation id of workstation we need to get linked resources + * @return array + */ static public function getAllResourcesOfWorkstation($fk_workstation) { @@ -65,6 +96,11 @@ class WorkstationResource extends CommonObject return $TRes; } + /** + * Function used to remove all resources linked to a workstation + * @param int $fk_workstation id of workstation we need to remove linked resources + * @return int + */ static public function deleteAllResourcesOfWorkstation($fk_workstation) { diff --git a/htdocs/workstation/class/workstationusergroup.class.php b/htdocs/workstation/class/workstationusergroup.class.php index 1221476203c..6b6bcb5cb4c 100644 --- a/htdocs/workstation/class/workstationusergroup.class.php +++ b/htdocs/workstation/class/workstationusergroup.class.php @@ -1,4 +1,30 @@ + * Copyright (C) 2020 Gauthier VERDOL + * + * 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 class/workstationusergroup.class.php + * \ingroup workstation + * \brief This file is a CRUD class file for WorkstationUserGroup (Create/Read/Update/Delete) + */ + +/** + * Class for WorkstationUserGroup + */ class WorkstationUserGroup extends CommonObject { @@ -46,6 +72,11 @@ class WorkstationUserGroup extends CommonObject } } + /** + * Function used to get an array with all usergroups linked to a workstation + * @param int $fk_workstation id of workstation we need to get linked usergroups + * @return array + */ static public function getAllGroupsOfWorkstation($fk_workstation) { @@ -65,6 +96,11 @@ class WorkstationUserGroup extends CommonObject return $TRes; } + /** + * Function used to remove all usergroups linked to a workstation + * @param int $fk_workstation id of workstation we need to remove linked usergroups + * @return int + */ static public function deleteAllGroupsOfWorkstation($fk_workstation) { diff --git a/htdocs/workstation/lib/workstation.lib.php b/htdocs/workstation/lib/workstation.lib.php index 526323ec45d..18307d0cd3a 100755 --- a/htdocs/workstation/lib/workstation.lib.php +++ b/htdocs/workstation/lib/workstation.lib.php @@ -1,5 +1,5 @@ * * 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 diff --git a/htdocs/workstation/lib/workstation_workstation.lib.php b/htdocs/workstation/lib/workstation_workstation.lib.php index 1c6b7492f0c..cc7fcc58f89 100755 --- a/htdocs/workstation/lib/workstation_workstation.lib.php +++ b/htdocs/workstation/lib/workstation_workstation.lib.php @@ -1,5 +1,5 @@ * * 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 diff --git a/htdocs/workstation/workstation_agenda.php b/htdocs/workstation/workstation_agenda.php index 132acc02bee..e2951554488 100755 --- a/htdocs/workstation/workstation_agenda.php +++ b/htdocs/workstation/workstation_agenda.php @@ -1,6 +1,6 @@ - * Copyright (C) ---Put here your own copyright and developer email--- + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/workstation/workstation_card.php b/htdocs/workstation/workstation_card.php index d28aecce67d..e5d51b20c84 100755 --- a/htdocs/workstation/workstation_card.php +++ b/htdocs/workstation/workstation_card.php @@ -422,7 +422,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea foreach ($object->usergroups as $id_group) { $g = new UserGroup($db); $g->fetch($id_group); - $toprint[] = '
  • ' . $g->getNomUrl(1) . '
  • '; + $toprint[] = '
  • ' . $g->getNomUrl(1) . '
  • '; } print '' . $langs->trans('Groups') . ''; print '
      ' . implode(' ', $toprint) . '
    '; @@ -435,7 +435,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea foreach ($object->resources as $id_resource) { $r = new Dolresource($db); $r->fetch($id_resource); - $toprint[] = '
  • ' . $r->getNomUrl(1) . '
  • '; + $toprint[] = '
  • ' . $r->getNomUrl(1) . '
  • '; } print '' . $langs->trans('Machines') . ''; print '
      ' . implode(' ', $toprint) . '
    '; diff --git a/htdocs/workstation/workstation_document.php b/htdocs/workstation/workstation_document.php index 104ea93c4db..89a34f55549 100755 --- a/htdocs/workstation/workstation_document.php +++ b/htdocs/workstation/workstation_document.php @@ -1,6 +1,6 @@ - * Copyright (C) ---Put here your own copyright and developer email--- + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php index c544446aabb..d4da9bd246f 100755 --- a/htdocs/workstation/workstation_list.php +++ b/htdocs/workstation/workstation_list.php @@ -1,6 +1,6 @@ - * Copyright (C) ---Put here your own copyright and developer email--- + * Copyright (C) 2020 Gauthier VERDOL * * 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 diff --git a/htdocs/workstation/workstation_note.php b/htdocs/workstation/workstation_note.php index b8e85ddaf6f..a9d8a7f3fc2 100755 --- a/htdocs/workstation/workstation_note.php +++ b/htdocs/workstation/workstation_note.php @@ -1,6 +1,6 @@ - * Copyright (C) ---Put here your own copyright and developer email--- + * Copyright (C) 2020 Gauthier VERDOL * * 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 From 93fc72a2ae3bd087f6b98c0bb036649591bed5a2 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 24 Dec 2020 12:16:51 +0100 Subject: [PATCH 05/28] NEW : search usergroups & resources --- htdocs/workstation/workstation_list.php | 88 ++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php index d4da9bd246f..1b6a81c0422 100755 --- a/htdocs/workstation/workstation_list.php +++ b/htdocs/workstation/workstation_list.php @@ -61,6 +61,7 @@ if (!$res) die("Include of main fails"); require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; // load workstation libraries require_once __DIR__.'/class/workstation.class.php'; @@ -119,6 +120,9 @@ foreach ($object->fields as $key => $val) if (in_array($key, array('type', 'status')) && GETPOST('search_'.$key, 'alpha') == -1) $search[$key] = ''; } +$groups = GETPOST('groups'); +$resources = GETPOST('resources'); + // List of fields to search into when doing a "search in all" $fieldstosearchall = array(); foreach ($object->fields as $key => $val) @@ -142,6 +146,23 @@ foreach ($object->fields as $key => $val) ); } } + +$arrayfields['wug.fk_usergroup'] = array( + 'label'=>$langs->trans('Groups'), + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>1000, + 'help'=>$val['help'] +); + +$arrayfields['wr.fk_resource'] = array( + 'label'=>$langs->trans('Resources'), + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>1001, + 'help'=>$val['help'] +); + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -188,6 +209,7 @@ if (empty($reshook)) { $search[$key] = ''; } + $groups=$resources=array(); $toselect = ''; $search_array_options = array(); } @@ -211,6 +233,7 @@ if (empty($reshook)) */ $form = new Form($db); +$formresource = new FormResource($db); $now = dol_now(); @@ -237,6 +260,8 @@ $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; +if(!empty($groups) || $sortfield === 'wug.fk_usergroup') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_usergroup wug ON (wug.fk_workstation = t.rowid)'; +if(!empty($resources) || $sortfield === 'wr.fk_resource') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_resource wr ON (wr.fk_workstation = t.rowid)'; // Add table from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook @@ -256,6 +281,13 @@ foreach ($search as $key => $val) if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); //$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear); // Add where from extra fields + +// usergroups +if(!empty($groups)) $sql.= ' AND wug.fk_usergroup IN('.implode(',', $groups).')'; + +// resources +if(!empty($resources)) $sql.= ' AND wr.fk_resource IN('.implode(',', $resources).')'; + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters = array(); @@ -278,7 +310,7 @@ $reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters, $object $sql.=$hookmanager->resPrint; $sql=preg_replace('/,\s*$/','', $sql); */ - +$sql.= ' GROUP BY t.rowid'; $sql .= $db->order($sortfield, $sortorder); // Count total nb of records @@ -422,6 +454,7 @@ print ''; foreach ($object->fields as $key => $val) { @@ -440,6 +473,21 @@ foreach ($object->fields as $key => $val) print ''; } } + +// usergroups +if (!empty($arrayfields['wug.fk_usergroup']['checked'])) { + print ''; +} + +// resources +if (!empty($arrayfields['wr.fk_resource']['checked'])) { + print ''; +} + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -470,6 +518,17 @@ foreach ($object->fields as $key => $val) print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; } } + +// usergroups +if (!empty($arrayfields['wug.fk_usergroup']['checked'])) { + print getTitleFieldOfList($arrayfields['wug.fk_usergroup']['label'], 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, '') . "\n"; +} + +// resources +if (!empty($arrayfields['wr.fk_resource']['checked'])) { + print getTitleFieldOfList($arrayfields['wr.fk_resource']['label'], 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, '') . "\n"; +} + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -503,6 +562,8 @@ while ($i < ($limit ? min($num, $limit) : $num)) // Store properties in $object $object->setVarsFromFetchObj($obj); + $object->usergroups = WorkstationUserGroup::getAllGroupsOfWorkstation($obj->rowid); + $object->resources = WorkstationResource::getAllResourcesOfWorkstation($obj->rowid); // Show here line of result print ''; @@ -532,6 +593,31 @@ while ($i < ($limit ? min($num, $limit) : $num)) } } } + + if (!empty($arrayfields['wug.fk_usergroup']['checked'])) { + $toprint = array(); + foreach ($object->usergroups as $id_group) { + $g = new UserGroup($db); + $g->fetch($id_group); + $toprint[] = '
  • ' . $g->getNomUrl(1) . '
  • '; + } + print ''; + } + + if (!empty($arrayfields['wr.fk_resource']['checked'])) { + $toprint = array(); + foreach ($object->resources as $id_resource) { + $r = new Dolresource($db); + $r->fetch($id_resource); + $toprint[] = '
  • ' . $r->getNomUrl(1) . '
  • '; + } + print ''; + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook From 93c3e13de937d5366e76353980281027591f786b Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 24 Dec 2020 11:19:40 +0000 Subject: [PATCH 06/28] Fixing style errors. --- htdocs/workstation/workstation_list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php index 1b6a81c0422..257a22c063b 100755 --- a/htdocs/workstation/workstation_list.php +++ b/htdocs/workstation/workstation_list.php @@ -260,8 +260,8 @@ $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; -if(!empty($groups) || $sortfield === 'wug.fk_usergroup') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_usergroup wug ON (wug.fk_workstation = t.rowid)'; -if(!empty($resources) || $sortfield === 'wr.fk_resource') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_resource wr ON (wr.fk_workstation = t.rowid)'; +if (!empty($groups) || $sortfield === 'wug.fk_usergroup') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_usergroup wug ON (wug.fk_workstation = t.rowid)'; +if (!empty($resources) || $sortfield === 'wr.fk_resource') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_resource wr ON (wr.fk_workstation = t.rowid)'; // Add table from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook @@ -283,10 +283,10 @@ if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_ // Add where from extra fields // usergroups -if(!empty($groups)) $sql.= ' AND wug.fk_usergroup IN('.implode(',', $groups).')'; +if (!empty($groups)) $sql.= ' AND wug.fk_usergroup IN('.implode(',', $groups).')'; // resources -if(!empty($resources)) $sql.= ' AND wr.fk_resource IN('.implode(',', $resources).')'; +if (!empty($resources)) $sql.= ' AND wr.fk_resource IN('.implode(',', $resources).')'; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks From 7de9272b907c4e6733601231ae93ea95833a0fa0 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 24 Dec 2020 12:25:12 +0100 Subject: [PATCH 07/28] FIX : useless test --- htdocs/workstation/workstation_list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php index 257a22c063b..996e7dc34fd 100755 --- a/htdocs/workstation/workstation_list.php +++ b/htdocs/workstation/workstation_list.php @@ -260,8 +260,8 @@ $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; -if (!empty($groups) || $sortfield === 'wug.fk_usergroup') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_usergroup wug ON (wug.fk_workstation = t.rowid)'; -if (!empty($resources) || $sortfield === 'wr.fk_resource') $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_resource wr ON (wr.fk_workstation = t.rowid)'; +if (!empty($groups)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_usergroup wug ON (wug.fk_workstation = t.rowid)'; +if (!empty($resources)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_workstation_resource wr ON (wr.fk_workstation = t.rowid)'; // Add table from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook From 27b0b0e8d520a74a899ede4bd3654bb7f9c0fda1 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 6 Jan 2021 09:11:04 +0100 Subject: [PATCH 08/28] =?UTF-8?q?add=20contacg=20tag=20on=20thirdparty=20a?= =?UTF-8?q?nd=20contact=20cr=C3=A9ation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/societe/card.php | 13 +++++++++++-- htdocs/societe/class/societe.class.php | 18 ++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 7fccdf994b9..c24689675ea 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -562,7 +562,8 @@ if (empty($reshook)) if ($object->particulier) { dol_syslog("We ask to create a contact/address too", LOG_DEBUG); - $result = $object->create_individual($user); + $contcats = GETPOST('contcats', 'array'); + $result = $object->create_individual($user, $contcats); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -1356,7 +1357,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) // Email / Web print ''; - print ''; + print 'browser->layout == 'phone' ? ' colspan="3"' : '').'>'.img_picto('', 'object_email').' '; print ''; print ''; @@ -1512,6 +1513,14 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print ""; //} + if (!empty($conf->global->THIRDPARTY_SUGGEST_ALSO_ADDRESS_CREATION)) + { + print '"; + } + // Supplier //if ($object->fournisseur) { print ''; +// default blacklist from mailing +print ''; +print ''; +print ''; +print ''; + + if (!empty($conf->use_javascript_ajax) && $conf->global->MAIN_FEATURES_LEVEL >= 1) { print ''; print ''; + //Unsubscribe if (!empty($conf->mailing->enabled)) { - $noemail = ''; - if (empty($noemail) && !empty($object->email)) + if ($conf->use_javascript_ajax && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1) { - $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing').") AND email = '".$db->escape($object->email)."'"; - //print $sql; - $resql = $db->query($sql); - if ($resql) - { - $obj = $db->fetch_object($resql); - $noemail = $obj->nb; + print "\n".''."\n"; + } + if (!GETPOSTISSET("no_email") && !empty($object->email)) + { + $result=$object->getNoEmail(); + if ($result<0) { + setEventMessages($object->error, $object->errors, 'errors'); } } - print ''; - print ''; - print ''; + print ''; + print ''; print ''; } - print ''; + if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { @@ -774,39 +796,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) } } } - // if (! empty($conf->socialnetworks->enabled)) - // { - // // Jabber - // if (! empty($conf->global->SOCIALNETWORKS_JABBER)) - // { - // print ''; - // print ''; - // } - // // Skype - // if (! empty($conf->global->SOCIALNETWORKS_SKYPE)) - // { - // print ''; - // print ''; - // } - // // Twitter - // if (! empty($conf->global->SOCIALNETWORKS_TWITTER)) - // { - // print ''; - // print ''; - // } - // // Facebook - // if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK)) - // { - // print ''; - // print ''; - // } - // // LinkedIn - // if (! empty($conf->global->SOCIALNETWORKS_LINKEDIN)) - // { - // print ''; - // print ''; - // } - // } // Visibility print ''; // Unsubscribe - print ''; if (!empty($conf->mailing->enabled)) { - $noemail = ''; - if (empty($noemail) && !empty($object->email)) + if ($conf->use_javascript_ajax && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1) { - $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing').") AND email = '".$db->escape($object->email)."'"; - //print $sql; - $resql = $db->query($sql); - if ($resql) - { - $obj = $db->fetch_object($resql); - $noemail = $obj->nb; + print "\n".''."\n"; + } + if (!GETPOSTISSET("no_email") && !empty($object->email)) + { + $result=$object->getNoEmail(); + if ($result<0) { + setEventMessages($object->error, $object->errors, 'errors'); } } - - print ''; - print ''; - } else { - print ''; + print ''; + print ''; + print ''; + print ''; } - print ''; if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { @@ -1300,20 +1295,11 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) // Unsubscribe opt-out if (!empty($conf->mailing->enabled)) { - //print 'eee'.$object->email; - $noemail = $object->no_email; - if (empty($noemail) && !empty($object->email)) - { - $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing').") AND email = '".$db->escape($object->email)."'"; - //print $sql; - $resql = $db->query($sql); - if ($resql) - { - $obj = $db->fetch_object($resql); - $noemail = $obj->nb; - } + $result=$object->getNoEmail(); + if ($result<0) { + setEventMessages($object->error, $object->errors, 'errors'); } - print ''; + print ''; } print ''; - print 'browser->layout == 'phone' ? ' colspan="3"' : '').'>'.img_picto('', 'object_email').' '; + print 'browser->layout == 'phone') || empty($conf->mailing->enabled) ? ' colspan="3"' : '').'>'.img_picto('', 'object_email').' '; + if (!empty($conf->mailing->enabled) && !empty($conf->global->THIRDPARTY_SUGGEST_ALSO_ADDRESS_CREATION)) { + if ($conf->browser->layout == 'phone') print ''; + print ''; + print ''; + } + print ''; print ''; print ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index a809fe7d10d..91cc0cb1e13 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -900,11 +900,18 @@ class Societe extends CommonObject * Create a contact/address from thirdparty * * @param User $user Object user + * @param int $no_email 1=Do not send mailing, 0=Ok to recieve mailling * @param array $tags Array of tag to affect to contact * @return int <0 if KO, >0 if OK */ - public function create_individual(User $user, $tags=array()) + public function create_individual(User $user, $no_email, $tags = array()) { + global $conf; + + $error = 0; + + $this->db->begin(); + // phpcs:enable require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; $contact = new Contact($this->db); @@ -926,20 +933,40 @@ class Societe extends CommonObject $contactId = $contact->create($user); if ($contactId < 0) { + $error++; $this->error = $contact->error; $this->errors = $contact->errors; dol_syslog(get_class($this)."::create_individual ERROR:".$this->error, LOG_ERR); - } elseif (is_array($tags) && !empty($tags)) { + } + + if (empty($error) && is_array($tags) && !empty($tags)) { $result = $contact->setCategories($tags); - if ($result < 0) - { + if ($result < 0) { + $error++; $this->error = $contact->error; $this->errors = array_merge($this->errors, $contact->errors); - dol_syslog(get_class($this)."::create_individual Affect Tag ERROR:".$this->error, LOG_ERR); + dol_syslog(get_class($this) . "::create_individual Affect Tag ERROR:" . $this->error, LOG_ERR); $contactId = $result; } } + if (empty($error) && !empty($conf->mailing->enabled) && !empty($contact->email) && isset($no_email)) { + $result = $contact->setNoEmail($no_email); + if ($result < 0) { + $this->error = $contact->error; + $this->errors = array_merge($this->errors, $contact->errors); + dol_syslog(get_class($this) . "::create_individual set mailing status ERROR:" . $this->error, LOG_ERR); + $contactId = $result; + } + } + + if (!empty($error)) { + dol_syslog(get_class($this)."::create_individual success"); + $this->db->commit(); + } else { + $this->db->rollback(); + } + return $contactId; } From afc85c2f2d8be6c50c72aa218f6ccc517c73bc94 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Thu, 7 Jan 2021 18:24:44 +0100 Subject: [PATCH 10/28] Fix expedition class - update shipment, tms is auto update field - wrong vars - clean code --- htdocs/expedition/class/expedition.class.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index e4722cabb4d..752da8aca04 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -499,8 +499,8 @@ class Expedition extends CommonObject // create shipment lines foreach ($stockLocationQty as $stockLocation => $qty) { - if (($line_id = $this->create_line($stockLocation, $line_ext->origin_line_id, $qty, $line_ext->rang, $array_options)) < 0) - { + $line_id = $this->create_line($stockLocation, $line_ext->origin_line_id, $qty, $line_ext->rang, $array_options); + if ($line_id < 0) { $error++; } else { // create shipment batch lines for stockLocation @@ -629,7 +629,7 @@ class Expedition extends CommonObject if (!empty($conf->multicurrency->enabled)) { if (!empty($this->multicurrency_code)) $this->multicurrency_code = $this->thirdparty->multicurrency_code; - if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx)) $this->multicurrency_tx = $this->thirdparty->multicurrency_tx; + if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($this->thirdparty->multicurrency_tx)) $this->multicurrency_tx = $this->thirdparty->multicurrency_tx; } /* @@ -1081,8 +1081,8 @@ class Expedition extends CommonObject if (isset($this->size_units)) $this->size_units = trim($this->size_units); if (isset($this->weight_units)) $this->weight_units = trim($this->weight_units); if (isset($this->trueWeight)) $this->weight = trim($this->trueWeight); - if (isset($this->note_private)) $this->note = trim($this->note_private); - if (isset($this->note_public)) $this->note = trim($this->note_public); + if (isset($this->note_private)) $this->note_private = trim($this->note_private); + if (isset($this->note_public)) $this->note_public = trim($this->note_public); if (isset($this->model_pdf)) $this->model_pdf = trim($this->model_pdf); @@ -1093,7 +1093,6 @@ class Expedition extends CommonObject // Update request $sql = "UPDATE ".MAIN_DB_PREFIX."expedition SET"; - $sql .= " tms=".(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; $sql .= " ref=".(isset($this->ref) ? "'".$this->db->escape($this->ref)."'" : "null").","; $sql .= " ref_ext=".(isset($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null").","; $sql .= " ref_customer=".(isset($this->ref_customer) ? "'".$this->db->escape($this->ref_customer)."'" : "null").","; @@ -2751,7 +2750,7 @@ class ExpeditionLigne extends CommonObjectLine $ranktouse = $this->rang; if ($ranktouse == -1) { - $rangmax = $this->line_max($fk_expedition); + $rangmax = $this->line_max($this->fk_expedition); $ranktouse = $rangmax + 1; } From 843f49643de526a1fbcfe9c3820c0a517b5277e7 Mon Sep 17 00:00:00 2001 From: Indelog Date: Fri, 8 Jan 2021 11:42:20 +0100 Subject: [PATCH 11/28] Fix Debugbarr : TraceableDB::idate not compatible with DolDB::idate The `TracableDB` class extend the `DolDB` but not implement the method `idate` correctly : it missing the `$gm` parameter. --- htdocs/debugbar/class/TraceableDB.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/debugbar/class/TraceableDB.php b/htdocs/debugbar/class/TraceableDB.php index 0cb380f39a1..af11f4c1d67 100644 --- a/htdocs/debugbar/class/TraceableDB.php +++ b/htdocs/debugbar/class/TraceableDB.php @@ -80,12 +80,13 @@ class TraceableDB extends DoliDB * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field. * Function to use to build INSERT, UPDATE or WHERE predica * - * @param int $param Date TMS to convert - * @return string Date in a string YYYYMMDDHHMMSS + * @param int $param Date TMS to convert + * @param mixed $gm 'gmt'=Input informations are GMT values, 'tzserver'=Local to server TZ + * @return string Date in a string YYYY-MM-DD HH:MM:SS */ - public function idate($param) + public function idate($param, $gm = 'tzserver') { - return $this->db->idate($param); + return $this->db->idate($param, $gm); } /** From 004ee952d919d621f4043ad4248a6d7baf725925 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 10 Jan 2021 08:16:19 +0100 Subject: [PATCH 12/28] Various payment - Add Amount & Sens in clone mode --- htdocs/compta/bank/various_payment/card.php | 29 ++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index 0efe367089c..597c2f4452c 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2017-2021 Alexandre Spangaro * Copyright (C) 2018-2020 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -266,6 +266,18 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->banque->m $object->datev = $newdatepayment; } + if (GETPOSTINT("clone_sens")) { + $object->sens = GETPOSTINT("clone_sens"); + } else { + $object->sens = $object->sens; + } + + if (GETPOST("clone_amount", "alpha")) { + $object->amount = price2num(GETPOST("clone_amount", "alpha")); + } else { + $object->amount = price2num($object->amount); + } + if ($object->check()) { $id = $object->create($user); @@ -486,14 +498,19 @@ if ($id) // Clone confirmation if ($action === 'clone') { + $set_value_help = $form->textwithpicto('', $langs->trans($langs->trans("AccountingDirectionHelp"))); + $sensarray = array('0' => $langs->trans("Debit"), '1' => $langs->trans("Credit")); + $formquestion = array( array('type' => 'text', 'name' => 'clone_label', 'label' => $langs->trans("Label"), 'value' => $langs->trans("CopyOf").' '.$object->label), - ); - $formquestion[] = array('type' => 'date', 'tdclass'=>'fieldrequired', 'name' => 'clone_date_payment', 'label' => $langs->trans("DatePayment"), 'value' => -1); - $formquestion[] = array('type' => 'date', 'name' => 'clone_date_value', 'label' => $langs->trans("DateValue"), 'value' => -1); - $formquestion[] = array('type' => 'other', 'tdclass'=>'fieldrequired', 'name' => 'accountid', 'label' => $langs->trans("BankAccount"), 'value' => $form->select_comptes($accountid, "accountid", 0, '', 1, '', 0, 'minwidth200', 1)); + array('type' => 'date', 'tdclass'=>'fieldrequired', 'name' => 'clone_date_payment', 'label' => $langs->trans("DatePayment"), 'value' => -1), + array('type' => 'date', 'name' => 'clone_date_value', 'label' => $langs->trans("DateValue"), 'value' => -1), + array('type' => 'other', 'tdclass'=>'fieldrequired', 'name' => 'clone_accountid', 'label' => $langs->trans("BankAccount"), 'value' => $form->select_comptes($object->fk_account, "accountid", 0, '', 1, '', 0, 'minwidth200', 1)), + array('type' => 'text', 'name' => 'clone_amount', 'label' => $langs->trans("Amount"), 'value' => price($object->amount)), + array('type' => 'select', 'name' => 'clone_sens', 'label' => $langs->trans("Sens") . ' ' . $set_value_help, 'values' => $sensarray, 'default' => $object->sens), + ); - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneVariousPayment', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 300); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneVariousPayment', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 350); } print dol_get_fiche_head($head, 'card', $langs->trans("VariousPayment"), -1, $object->picto); From c40976e4f9298ca4ff676c9088535c506ac6bbb1 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 11 Jan 2021 09:47:59 +0100 Subject: [PATCH 13/28] FIX: Hidden accountancy export button without any right --- htdocs/accountancy/bookkeeping/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index b3cec7710a4..39596d26ebe 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -638,7 +638,7 @@ if (empty($reshook)) { } $newcardbutton .= ''.$langs->trans("IncludeDocsAlreadyExported").''; - $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file'.($param ? '&'.$param : ''), $user->rights->accounting->mouvements->export); + if(!empty($user->rights->accounting->mouvements->export)) $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file'.($param ? '&'.$param : ''), $user->rights->accounting->mouvements->export); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); From 7339217cf1163e7497e29e59fef77a1ab2f6159f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 11 Jan 2021 08:51:52 +0000 Subject: [PATCH 14/28] Fixing style errors. --- htdocs/accountancy/bookkeeping/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 39596d26ebe..33845492670 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -638,7 +638,7 @@ if (empty($reshook)) { } $newcardbutton .= ''.$langs->trans("IncludeDocsAlreadyExported").''; - if(!empty($user->rights->accounting->mouvements->export)) $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file'.($param ? '&'.$param : ''), $user->rights->accounting->mouvements->export); + if (!empty($user->rights->accounting->mouvements->export)) $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file'.($param ? '&'.$param : ''), $user->rights->accounting->mouvements->export); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); From e3e4f0590c768673302165039107ee3c93ec19d3 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 11 Jan 2021 11:36:19 +0100 Subject: [PATCH 15/28] FIX : get and delete linked items with association tables methods created in common object --- htdocs/core/class/commonobject.class.php | 50 +++++++++++++++++++ .../class/workstationresource.class.php | 23 +-------- .../class/workstationusergroup.class.php | 23 +-------- 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index c8994d32a1d..57f2364e42f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3660,6 +3660,56 @@ abstract class CommonObject } } + /** + * Function used to get an array with all items linked to an object id in association table + * @param int $fk_object_where id of object we need to get linked items + * @param string $field_select name of field we need to get a list + * @param string $field_where name of field of object we need to get linked items + * @param string $table_element name of association table + * @return array + */ + static public function getAllItemsLinkedByObjectID($fk_object_where, $field_select, $field_where, $table_element) + { + if(empty($fk_object_where) || empty($field_where) || empty($table_element)) return -1; + + global $db; + + $sql = 'SELECT '.$field_select.' FROM '.MAIN_DB_PREFIX.$table_element.' WHERE '.$field_where.' = '.$fk_object_where; + $resql = $db->query($sql); + + $TRes = array(); + if (!empty($resql)) { + while ($res = $db->fetch_object($resql)) { + $TRes[] = $res->{$field_select}; + } + } + + return $TRes; + + } + + /** + * Function used to remove all items linked to an object id in association table + * @param int $fk_object_where id of object we need to remove linked items + * @param string $field_where name of field of object we need to delete linked items + * @param string $table_element name of association table + * @return int + */ + static public function deleteAllItemsLinkedByObjectID($fk_object_where, $field_where, $table_element) + { + if(empty($fk_object_where) || empty($field_where) || empty($table_element)) return -1; + + global $db; + + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$table_element.' WHERE '.$field_where.' = '.$fk_object_where; + $resql = $db->query($sql); + + if (empty($resql)) return 0; + + return 1; + + } + /** * Set status of an object * diff --git a/htdocs/workstation/class/workstationresource.class.php b/htdocs/workstation/class/workstationresource.class.php index cfb6706058d..21398460eca 100644 --- a/htdocs/workstation/class/workstationresource.class.php +++ b/htdocs/workstation/class/workstationresource.class.php @@ -79,21 +79,9 @@ class WorkstationResource extends CommonObject */ static public function getAllResourcesOfWorkstation($fk_workstation) { - global $db; - $obj = new self($db); - $sql = 'SELECT fk_resource FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; - $resql = $db->query($sql); - - $TRes = array(); - if (!empty($resql)) { - while ($res = $db->fetch_object($resql)) { - $TRes[] = $res->fk_resource; - } - } - - return $TRes; + return parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_resource', 'fk_workstation', $obj->table_element); } /** @@ -103,15 +91,8 @@ class WorkstationResource extends CommonObject */ static public function deleteAllResourcesOfWorkstation($fk_workstation) { - global $db; - $obj = new self($db); - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; - $resql = $db->query($sql); - - if (empty($resql)) return 0; - - return 1; + return parent::deleteAllItemsLinkedByObjectID($fk_workstation, 'fk_workstation', $obj->table_element); } } diff --git a/htdocs/workstation/class/workstationusergroup.class.php b/htdocs/workstation/class/workstationusergroup.class.php index 6b6bcb5cb4c..b45d24c7c60 100644 --- a/htdocs/workstation/class/workstationusergroup.class.php +++ b/htdocs/workstation/class/workstationusergroup.class.php @@ -79,21 +79,9 @@ class WorkstationUserGroup extends CommonObject */ static public function getAllGroupsOfWorkstation($fk_workstation) { - global $db; - $obj = new self($db); - $sql = 'SELECT fk_usergroup FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; - $resql = $db->query($sql); - - $TRes = array(); - if (!empty($resql)) { - while ($res = $db->fetch_object($resql)) { - $TRes[] = $res->fk_usergroup; - } - } - - return $TRes; + return parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_usergroup', 'fk_workstation', $obj->table_element); } /** @@ -103,15 +91,8 @@ class WorkstationUserGroup extends CommonObject */ static public function deleteAllGroupsOfWorkstation($fk_workstation) { - global $db; - $obj = new self($db); - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$obj->table_element.' WHERE fk_workstation = '.$fk_workstation; - $resql = $db->query($sql); - - if (empty($resql)) return 0; - - return 1; + return parent::deleteAllItemsLinkedByObjectID($fk_workstation, 'fk_workstation', $obj->table_element); } } From 6668cfa3118716aa630dddfa4d6ee13e86f8dcab Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 11 Jan 2021 11:40:04 +0100 Subject: [PATCH 16/28] FIX : name in copyrights --- htdocs/core/class/commonobject.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 57f2364e42f..0a58ded8710 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -14,6 +14,7 @@ * Copyright (C) 2017 Rui Strecht * Copyright (C) 2018-2020 Frédéric France * Copyright (C) 2018 Josep Lluís Amador + * Copyright (C) 2021 Gauthier VERDOL * * 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 From d2c86578fa2d3ec5172c620d2d426896360ee9e7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 11 Jan 2021 15:58:20 +0100 Subject: [PATCH 17/28] Update card.php --- htdocs/compta/bank/various_payment/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index 597c2f4452c..0c2db362e75 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -266,8 +266,8 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->banque->m $object->datev = $newdatepayment; } - if (GETPOSTINT("clone_sens")) { - $object->sens = GETPOSTINT("clone_sens"); + if (GETPOSTISSET("clone_sens")) { + $object->sens = GETPOST("clone_sens", 'int'); } else { $object->sens = $object->sens; } From f6de6078893bccc0b4c49aad39d2ba51e468e33e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 11 Jan 2021 16:07:02 +0100 Subject: [PATCH 18/28] Fix warning --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 90532e5ee1e..d6b67088e78 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1977,7 +1977,7 @@ function dol_print_date($time, $format = '', $tzoutput = 'auto', $outputlangs = global $conf, $langs; if ($tzoutput == 'auto') { - $tzoutput = $conf->tzuserinputkey; + $tzoutput = (empty($conf) ? 'tzserver' : $conf->tzuserinputkey); } // Clean parameters From 6e860efa448157880a430e6bf7fe236f11985502 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 11 Jan 2021 20:53:18 +0100 Subject: [PATCH 19/28] CSS --- htdocs/projet/tasks/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 1951df8c0e1..b318b44f053 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -511,7 +511,7 @@ if (!empty($arrayfields['t.label']['checked'])) print ''; print ''; } -//Task Description +// Task Description if (!empty($arrayfields['t.description']['checked'])) { print ''; From 7f90c88d6a518709d7806b9193107ac0fbf4e5cc Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 12 Jan 2021 09:51:39 +0100 Subject: [PATCH 20/28] fix js syntax --- htdocs/societe/card.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 0e2b10bcb19..58f5645e25d 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1167,8 +1167,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) $("#email").keyup(function() { init_check_no_email($(this)); }); - init_check_no_email($("#email")); - });'; + init_check_no_email($("#email"));'; } print '});'; print ''."\n"; From 3906acc951836b80306ac49f76e971a722de3ec1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Jan 2021 10:00:05 +0100 Subject: [PATCH 21/28] Must use the generic version --- htdocs/core/class/html.formmail.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index a4f936cfca0..1edcabf36a5 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -1264,8 +1264,6 @@ class FormMail extends Form $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendActionComm"); } elseif ($type_template == 'thirdparty') { $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentThirdparty"); - } elseif ($type_template == 'user') { - $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentUser"); } elseif (!empty($type_template)) { $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentGeneric"); } From 2be924d5d8a96d3d3ac0f85172b71309cf856435 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 12 Jan 2021 10:01:32 +0100 Subject: [PATCH 22/28] fix js bulkemail --- htdocs/contact/card.php | 24 +++++++++++++++--------- htdocs/societe/card.php | 1 - 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 6ce4493c947..8c7e3b6c066 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -1044,15 +1044,21 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) if ($conf->use_javascript_ajax && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1) { print "\n".''."\n"; } if (!GETPOSTISSET("no_email") && !empty($object->email)) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 58f5645e25d..3632137c637 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1155,7 +1155,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) document.formsoc.submit(); });'; if ($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1) { - print ' function init_check_no_email(input) { if (input.val()!="") { From 3f13dacacd6da5373f42ae02af1aa5df97be1ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Luttringer?= Date: Sun, 10 Jan 2021 18:15:26 +0100 Subject: [PATCH 23/28] Use login from LDAP attribute The LDAP authentication function (check_user_password_ldap) returns the login sting when authentication is successful. The current implementation always return the provided login to the check function, instead of LDAP entry login field (as defined in the LDAP_FIELD_LOGIN). This is problematic when you expect user to log with several login, like mail, or the LDAP login doesn't match the dolibarr database. For example, the following filter allows users auth with mail and cn ldap fields: $dolibarr_main_auth_ldap_filter = '(&(objectClass=person)(|(cn=%1%)(mail=%1%)))'; but, dolibarr will not find the user when mail is provided. This patch returns the $ldap->login when LDAP_FIELD_LOGIN is configured. --- htdocs/core/login/functions_ldap.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 41ce8a67316..c62c6add140 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -148,8 +148,11 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) { if ($result == 2) // Connection is ok for user/pass into LDAP { - dol_syslog("functions_ldap::check_user_password_ldap Authentification ok"); $login = $usertotest; + if (!empty($conf->global->LDAP_FIELD_LOGIN)) { + $login = $ldap->login; + } + dol_syslog("functions_ldap::check_user_password_ldap $login authentication ok"); require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; From cf24fd5d857a4738d4a843035a7a192e8cd6ac01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 12 Jan 2021 23:30:59 +0100 Subject: [PATCH 24/28] code syntax --- htdocs/core/actions_sendmails.inc.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 929d35d9730..1bea255bda2 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -227,7 +227,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST } if (count($receivercc) > 0) { foreach ($receivercc as $key => $val) { - if ($val == 'thirdparty') { // Key selected means currentthird party (may be usd for current member or current user too) + if ($val == 'thirdparty') { // Key selected means current thirdparty (may be usd for current member or current user too) // Recipient was provided from combo list $tmparray[] = dol_string_nospecial($thirdparty->name, ' ', array(",")).' <'.$thirdparty->email.'>'; } elseif ($val == 'contact') { // Key selected means current contact @@ -399,7 +399,6 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $error++; } // End call triggers - if ($error) { setEventMessages($object->error, $object->errors, 'errors'); } From dad329602aa3b940c5c0fec5478d3d90d62bfee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 12 Jan 2021 23:46:29 +0100 Subject: [PATCH 25/28] Update html.formmail.class.php --- htdocs/core/class/html.formmail.class.php | 148 +++++++++++++++------- 1 file changed, 101 insertions(+), 47 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 3d8f3e72d9e..1b29af772a7 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -391,7 +391,9 @@ class FormMail extends Form // Define output language $outputlangs = $langs; $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $this->param['langsmodels']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $this->param['langsmodels']; + } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); @@ -423,13 +425,13 @@ class FormMail extends Form } } - if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) { + if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) { $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]); } - if (!empty($_SESSION["listofnames".$keytoavoidconflict])) { + if (!empty($_SESSION["listofnames".$keytoavoidconflict])) { $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]); } - if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) { + if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) { $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]); } @@ -449,7 +451,7 @@ class FormMail extends Form $out .= ''; } } - foreach ($this->param as $key=>$value) { + foreach ($this->param as $key => $value) { if (is_array($value)) { $out .= "\n"; } else { @@ -475,8 +477,12 @@ class FormMail extends Form // We escape the $labeltouse to store it into $modelmail_array. $modelmail_array[$line->id] = dol_escape_htmltag($labeltouse); - if ($line->lang) $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang); - if ($line->private) $modelmail_array[$line->id] .= ' - '.dol_escape_htmltag($langs->trans("Private")).''; + if ($line->lang) { + $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang); + } + if ($line->private) { + $modelmail_array[$line->id] .= ' - '.dol_escape_htmltag($langs->trans("Private")).''; + } } } @@ -486,7 +492,9 @@ class FormMail extends Form $out .= '
    '."\n"; $out .= ''.$langs->trans('SelectMailModel').': '; $out .= $this->selectarray('modelmailselected', $modelmail_array, 0, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1); - if ($user->admin) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1); + if ($user->admin) { + $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1); + } $out .= '   '; $out .= ''; $out .= '   '; @@ -499,7 +507,9 @@ class FormMail extends Form // If list of template is empty $out .= '
    '."\n"; $out .= $langs->trans('SelectMailModel').': '; // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy. - if ($user->admin) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1); + if ($user->admin) { + $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1); + } $out .= '   '; $out .= ''; $out .= '   '; @@ -513,24 +523,24 @@ class FormMail extends Form // Substitution array/string $helpforsubstitution = ''; - if (is_array($this->substit) && count($this->substit)) $helpforsubstitution .= $langs->trans('AvailableVariables').' :
    '."\n"; + if (is_array($this->substit) && count($this->substit)) { + $helpforsubstitution .= $langs->trans('AvailableVariables').' :
    '."\n"; + } foreach ($this->substit as $key => $val) { $helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText($val))).'
    '; } - if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this. + if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this. $out .= '
    \n"; //$out.=''; } - /*var_dump(! empty($this->withfromreadonly)); - var_dump($this->withfrom); - var_dump($this->fromtype); - var_dump($this->fromname);*/ - // From if (!empty($this->withfrom)) { if (!empty($this->withfromreadonly)) { @@ -609,7 +619,9 @@ class FormMail extends Form if ($listaliasval) { $listaliasval = preg_replace('//', '>', $listaliasval); - if (!preg_match('/</', $listaliasval)) $listaliasval = '<'.$listaliasval.'>'; + if (!preg_match('/</', $listaliasval)) { + $listaliasval = '<'.$listaliasval.'>'; + } $liste[$typealias.'_'.$posalias] = $listaliasval; } } @@ -621,7 +633,9 @@ class FormMail extends Form if (empty($reshook)) { $defaultfrom = $this->fromtype; } - if (!empty($hookmanager->resArray['defaultfrom'])) $defaultfrom = $hookmanager->resArray['defaultfrom']; + if (!empty($hookmanager->resArray['defaultfrom'])) { + $defaultfrom = $hookmanager->resArray['defaultfrom']; + } // Using combo here make the '' no more visible on list. //$out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails); @@ -639,11 +653,13 @@ class FormMail extends Form } // To - if (!empty($this->withto) || is_array($this->withto)) - { + if (!empty($this->withto) || is_array($this->withto)) { $out .= '\n"; @@ -1200,11 +1235,21 @@ class FormMail extends Form $sql .= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')"; $sql .= " AND entity IN (".getEntity('c_email_templates').")"; $sql .= " AND (private = 0 OR fk_user = ".$user->id.")"; // Get all public or private owned - if ($active >= 0) $sql .= " AND active = ".$active; - if ($label) $sql .= " AND label ='".$db->escape($label)."'"; - if (!($id > 0) && $languagetosearch) $sql .= " AND (lang = '".$db->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$db->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')"; - if ($id > 0) $sql .= " AND rowid=".$id; - if ($id == -1) $sql .= " AND position=0"; + if ($active >= 0) { + $sql .= " AND active = ".$active; + } + if ($label) { + $sql .= " AND label ='".$db->escape($label)."'"; + } + if (!($id > 0) && $languagetosearch) { + $sql .= " AND (lang = '".$db->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$db->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')"; + } + if ($id > 0) { + $sql .= " AND rowid=".$id; + } + if ($id == -1) { + $sql .= " AND position=0"; + } if ($languagetosearch) { $sql .= $db->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or '' } else { @@ -1229,7 +1274,8 @@ class FormMail extends Form } elseif ($id == -2) { // Not found with the provided label return -1; - } else { // If there is no template at all + } else { + // If there is no template at all $defaultmessage = ''; if ($type_template == 'body') { @@ -1460,7 +1506,7 @@ class FormMail extends Form $tmparray['__USER_SIGNATURE__'] = 'TagSignature'; $tmparray['__CHECK_READ__'] = 'TagCheckMail'; $tmparray['__UNSUBSCRIBE__'] = 'TagUnsubscribe'; - //,'__PERSONALIZED__' => 'Personalized' // Hidden because not used yet in mass emailing + //,'__PERSONALIZED__' => 'Personalized' // Hidden because not used yet in mass emailing $onlinepaymentenabled = 0; if (!empty($conf->paypal->enabled)) $onlinepaymentenabled++; @@ -1469,10 +1515,18 @@ class FormMail extends Form if ($onlinepaymentenabled && !empty($conf->global->PAYMENT_SECURITY_TOKEN)) { $tmparray['__SECUREKEYPAYMENT__'] = $conf->global->PAYMENT_SECURITY_TOKEN; if (!empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { - if ($conf->adherent->enabled) $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember'; - if ($conf->facture->enabled) $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice'; - if ($conf->commande->enabled) $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder'; - if ($conf->contrat->enabled) $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine'; + if ($conf->adherent->enabled) { + $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember'; + } + if ($conf->facture->enabled) { + $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice'; + } + if ($conf->commande->enabled) { + $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder'; + } + if ($conf->contrat->enabled) { + $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine'; + } } } else { /* No need to show into tooltip help, option is not enabled From ffc936fff32e0039fd5cf8a4181f6cc741119acd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 13 Jan 2021 11:15:30 +0100 Subject: [PATCH 26/28] Fix missing param --- htdocs/compta/paiement/class/paiement.class.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 6b7f1612836..89737ca917f 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -578,9 +578,10 @@ class Paiement extends CommonObject * @param string $emetteur_nom Name of transmitter * @param string $emetteur_banque Name of bank * @param int $notrigger No trigger + * @param string $accountancycode When we record a free bank entry, we must provide accounting account if accountancy module is on. * @return int <0 if KO, bank_line_id if OK */ - public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0) + public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0, $accountancycode = '') { global $conf, $langs, $user; @@ -625,7 +626,8 @@ class Paiement extends CommonObject '', $user, $emetteur_nom, - $emetteur_banque + $emetteur_banque, + $accountancycode ); // Mise a jour fk_bank dans llx_paiement From 3bed2c91c7e3ba184559d53dbec6734fd00bd67b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 13 Jan 2021 12:20:32 +0100 Subject: [PATCH 27/28] Fix version --- htdocs/core/modules/modWorkstation.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php index 499dcc5de48..4d9d14c6dc2 100755 --- a/htdocs/core/modules/modWorkstation.class.php +++ b/htdocs/core/modules/modWorkstation.class.php @@ -64,7 +64,7 @@ class modWorkstation extends DolibarrModules $this->editor_name = 'Editor name'; $this->editor_url = 'https://www.example.com'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = '1.0'; + $this->version = 'development'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; From 93a2edd8d9fd21a3cc2063bfe0ffc61fd4236058 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 13 Jan 2021 12:21:26 +0100 Subject: [PATCH 28/28] Fix property not used --- htdocs/core/modules/modWorkstation.class.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php index 4d9d14c6dc2..5f55e2b2207 100755 --- a/htdocs/core/modules/modWorkstation.class.php +++ b/htdocs/core/modules/modWorkstation.class.php @@ -60,9 +60,7 @@ class modWorkstation extends DolibarrModules // Module description, used if translation string 'ModuleWorkstationDesc' not found (Workstation is name of module). $this->description = "WorkstationsDescription"; // Used only if file README.md and README-LL.md not found. - $this->descriptionlong = "Workstation description (Long)"; - $this->editor_name = 'Editor name'; - $this->editor_url = 'https://www.example.com'; + $this->descriptionlong = "WorkstationsDescription"; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' $this->version = 'development'; // Url to the file with your last numberversion of this module
    '; + print $form->select_dolgroups($groups, 'groups', 1, '', 0, '', '', $conf->entity, true); + print ''; + print $formresource->select_resource_list($resources, 'resources', '', '', 0, '', '', $conf->entity, true, 0, '', true); + print '
    '; + print '
      ' . implode(' ', $toprint) . '
    '; + print '
    '; + print '
      ' . implode(' ', $toprint) . '
    '; + print '
    '.$form->editfieldkey('EMail', 'email', '', $object, 0, 'string', '', empty($conf->global->SOCIETE_EMAIL_MANDATORY) ? '' : $conf->global->SOCIETE_EMAIL_MANDATORY).''.img_picto('', 'object_email').'
    '.$form->editfieldkey('Web', 'url', '', $object, 0).''.img_picto('', 'globe').'
    '.$form->editfieldkey('ContactCategoriesShort', 'contcats', '', $object, 0).''; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_CONTACT, null, 'parent', null, null, 1); + print img_picto('', 'category').$form->multiselectarray('contcats', $cate_arbo, GETPOST('contcats', 'array'), null, null, 'quatrevingtpercent widthcentpercentminusx', 0, 0); + print "
    '.$form->editfieldkey('SuppliersCategoriesShort', 'suppcats', '', $object, 0).''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 4c25a002a8f..a809fe7d10d 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -900,9 +900,10 @@ class Societe extends CommonObject * Create a contact/address from thirdparty * * @param User $user Object user + * @param array $tags Array of tag to affect to contact * @return int <0 if KO, >0 if OK */ - public function create_individual(User $user) + public function create_individual(User $user, $tags=array()) { // phpcs:enable require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; @@ -923,14 +924,23 @@ class Societe extends CommonObject $contact->town = $this->town; $contact->phone_pro = $this->phone; - $result = $contact->create($user); - if ($result < 0) { + $contactId = $contact->create($user); + if ($contactId < 0) { $this->error = $contact->error; $this->errors = $contact->errors; dol_syslog(get_class($this)."::create_individual ERROR:".$this->error, LOG_ERR); + } elseif (is_array($tags) && !empty($tags)) { + $result = $contact->setCategories($tags); + if ($result < 0) + { + $this->error = $contact->error; + $this->errors = array_merge($this->errors, $contact->errors); + dol_syslog(get_class($this)."::create_individual Affect Tag ERROR:".$this->error, LOG_ERR); + $contactId = $result; + } } - return $result; + return $contactId; } /** From 5c53a963e221443a3dff7f0cd6d3db3555ab4205 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 7 Jan 2021 17:23:02 +0100 Subject: [PATCH 09/28] bulk email management --- htdocs/admin/mailing.php | 28 ++- htdocs/contact/card.php | 232 +++++++++++------------ htdocs/contact/class/contact.class.php | 104 ++++++++++ htdocs/core/modules/modMailing.class.php | 8 + htdocs/langs/en_US/mails.lang | 4 +- htdocs/societe/card.php | 36 +++- htdocs/societe/class/societe.class.php | 37 +++- 7 files changed, 314 insertions(+), 135 deletions(-) diff --git a/htdocs/admin/mailing.php b/htdocs/admin/mailing.php index 1c96ce68780..32aa7accfcf 100644 --- a/htdocs/admin/mailing.php +++ b/htdocs/admin/mailing.php @@ -34,7 +34,7 @@ if (!$user->admin) accessforbidden(); $action = GETPOST('action', 'aZ09'); - +$form = new Form($db); /* * Actions @@ -49,6 +49,7 @@ if ($action == 'setvalue') $checkread = GETPOST('value', 'alpha'); $checkread_key = GETPOST('MAILING_EMAIL_UNSUBSCRIBE_KEY', 'alpha'); $mailingdelay = GETPOST('MAILING_DELAY', 'int'); + $contactbulkdefault = GETPOST('MAILING_CONTACT_DEFAULT_BULK_STATUS', 'int'); $res = dolibarr_set_const($db, "MAILING_EMAIL_FROM", $mailfrom, 'chaine', 0, '', $conf->entity); if (!$res > 0) $error++; @@ -56,11 +57,14 @@ if ($action == 'setvalue') if (!$res > 0) $error++; $res = dolibarr_set_const($db, "MAILING_DELAY", $mailingdelay, 'chaine', 0, '', $conf->entity); if (!$res > 0) $error++; + $res = dolibarr_set_const($db, "MAILING_CONTACT_DEFAULT_BULK_STATUS", $contactbulkdefault, 'chaine', 0, '', $conf->entity); + if (!$res > 0) $error++; // Create temporary encryption key if nedded $res = dolibarr_set_const($db, "MAILING_EMAIL_UNSUBSCRIBE_KEY", $checkread_key, 'chaine', 0, '', $conf->entity); if (!$res > 0) $error++; + if (!$error) { $db->commit(); @@ -70,7 +74,17 @@ if ($action == 'setvalue') setEventMessages($langs->trans("Error"), null, 'errors'); } } - +if ($action == 'setonsearchandlistgooncustomerorsuppliercard') { + $setonsearchandlistgooncustomerorsuppliercard = GETPOST('value', 'int'); + $res = dolibarr_set_const($db, "SOCIETE_ON_SEARCH_AND_LIST_GO_ON_CUSTOMER_OR_SUPPLIER_CARD", $setonsearchandlistgooncustomerorsuppliercard, 'yesno', 0, '', $conf->entity); + if (!$res > 0) $error++; + if (!$error) + { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} /* * View @@ -136,6 +150,16 @@ print '
    ' . $langs->trans("DefaultBlacklistMailingStatus") . ''; +$blacklist_setting=array(0=>$langs->trans('No'),1=>$langs->trans('Yes'),-1=>$langs->trans('DefaultStatusEmptyMandatory')); +print $form->selectarray("MAILING_CONTACT_DEFAULT_BULK_STATUS", $blacklist_setting, $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS); +print '
    '; print $langs->trans("MailAdvTargetRecipients").''; diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 0726e2c33e2..6ce4493c947 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -200,7 +200,7 @@ if (empty($reshook)) } } } - $object->email = (string) GETPOST("email", 'alpha'); + $object->email = (string) GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL); $object->no_email = GETPOST("no_email", "int"); $object->phone_pro = (string) GETPOST("phone_pro", 'alpha'); $object->phone_perso = (string) GETPOST("phone_perso", 'alpha'); @@ -225,44 +225,59 @@ if (empty($reshook)) $action = 'create'; } - if (!GETPOST("lastname")) { + if (!empty($conf->mailing->enabled) && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1 && $object->no_email==-1 && !empty($object->email)) { + $error++; + $errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("No_Email")); + $action = 'create'; + } + + if (!empty($object->email) && !isValidEMail($object->email)) + { + $langs->load("errors"); + $error++; + $errors[] = $langs->trans("ErrorBadEMail", GETPOST('email', 'alpha')); + $action = 'create'; + } + + if (empty($object->lastname)) { $error++; $errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("Lastname").' / '.$langs->transnoentities("Label")); $action = 'create'; } - if (!$error) - { + if (empty($error)) { $id = $object->create($user); - if ($id <= 0) - { + if ($id <= 0) { $error++; $errors = array_merge($errors, ($object->error ? array($object->error) : $object->errors)); $action = 'create'; - } else { - // Categories association - $contcats = GETPOST('contcats', 'array'); - $object->setCategories($contcats); + } + } - // Add mass emailing flag into table mailing_unsubscribe - if (GETPOST('no_email', 'int') && $object->email) - { - $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing', 0).") AND email = '".$db->escape($object->email)."'"; - $resql = $db->query($sql); - if ($resql) - { - $obj = $db->fetch_object($resql); - if (empty($obj->nb)) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe(email, entity, date_creat) VALUES ('".$db->escape($object->email)."', ".$db->escape(getEntity('mailing', 0)).", '".$db->idate(dol_now())."')"; - $resql = $db->query($sql); - } - } + if (empty($error)) { + // Categories association + $contcats = GETPOST('contcats', 'array'); + if (count($contcats)>0) { + $result = $object->setCategories($contcats); + if ($result <= 0) { + $error++; + $errors = array_merge($errors, ($object->error ? array($object->error) : $object->errors)); + $action = 'create'; } } } - if (!$error && $id > 0) + if (empty($error) && !empty($conf->mailing->enabled) && !empty($object->email)) { + // Add mass emailing flag into table mailing_unsubscribe + $result=$object->setNoEmail($object->no_email); + if ($result<0) { + $error++; + $errors = array_merge($errors, ($object->error ? array($object->error) : $object->errors)); + $action = 'create'; + } + } + + if (empty($error) && $id > 0) { $db->commit(); if (!empty($backtopage)) $url = $backtopage; @@ -298,12 +313,26 @@ if (empty($reshook)) if ($action == 'update' && !$_POST["cancel"] && $user->rights->societe->contact->creer) { - if (empty($_POST["lastname"])) + if (empty(GETPOST("lastname", 'alpha'))) { $error++; $errors = array($langs->trans("ErrorFieldRequired", $langs->transnoentities("Name").' / '.$langs->transnoentities("Label"))); $action = 'edit'; } + if (!empty($conf->mailing->enabled) && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1 && GETPOST("no_email", "int")==-1 && !empty(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL))) { + $error++; + $errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("No_Email")); + $action = 'edit'; + } + + if (!empty(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL)) && !isValidEMail(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL))) + { + $langs->load("errors"); + $error++; + $errors[] = $langs->trans("ErrorBadEMail", GETPOST('email', 'alpha')); + $action = 'edit'; + } + if (!$error) { $contactid = GETPOST("contactid", 'int'); @@ -374,7 +403,7 @@ if (empty($reshook)) $object->state_id = GETPOST("state_id", 'int'); $object->country_id = GETPOST("country_id", 'int'); - $object->email = (string) GETPOST("email", 'alpha'); + $object->email = (string) GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL); $object->no_email = GETPOST("no_email", "int"); //$object->jabberid = GETPOST("jabberid", 'alpha'); //$object->skype = GETPOST("skype", 'alpha'); @@ -411,31 +440,15 @@ if (empty($reshook)) $categories = GETPOST('contcats', 'array'); $object->setCategories($categories); - $no_email = GETPOST('no_email', 'int'); - // Update mass emailing flag into table mailing_unsubscribe if (GETPOSTISSET('no_email') && $object->email) { - if ($no_email) - { - $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing', 0).") AND email = '".$db->escape($object->email)."'"; - $resql = $db->query($sql); - if ($resql) - { - $obj = $db->fetch_object($resql); - $noemail = $obj->nb; - if (empty($noemail)) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe(email, entity, date_creat) VALUES ('".$db->escape($object->email)."', ".$db->escape(getEntity('mailing', 0)).", '".$db->idate(dol_now())."')"; - $resql = $db->query($sql); - } - } - } else { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = '".$db->escape($object->email)."' AND entity = ".$db->escape(getEntity('mailing', 0)); - $resql = $db->query($sql); + $no_email = GETPOST('no_email', 'int'); + $result=$object->setNoEmail($no_email); + if ($result<0) { + setEventMessages($object->error, $object->errors, 'errors'); + $action = 'edit'; } - - $object->no_email = $no_email; } $object->old_lastname = ''; @@ -738,27 +751,36 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print '
    '.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ? GETPOST("no_email", 'alpha') : $noemail), 1).''.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ? GETPOST("no_email", 'int') : $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS), 1, false, ($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1)).'
    jabberid).'">
    skype).'">
    twitter).'">
    facebook).'">
    linkedin).'">
    '; @@ -1050,28 +1039,34 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print '
    '.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ?GETPOST("no_email", 'alpha') : $noemail), 1).'
    '.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ? GETPOST("no_email", 'int') : $object->no_email), 1, false, ($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1)).'
    '.$langs->trans("No_Email").''.yn($noemail).'
    '.$langs->trans("No_Email").''.yn($object->no_email).'
    '.$langs->trans("ContactVisibility").''; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 367a2e7cd62..7427e16e5db 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -1180,6 +1180,20 @@ class Contact extends CommonObject } } + if (!$error) + { + // Remove Roles + $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople = ".$this->id; + dol_syslog(__METHOD__, LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag = -1; + } + } + if (!$error) { // Remove category @@ -1910,4 +1924,94 @@ class Contact extends CommonObject return "Error, mode/status not found"; } + + + /** + * Set "blacklist" mailing status + * + * @param int $no_email 1=Do not send mailing, 0=Ok to recieve mailling + * @return int <0 if KO, >0 if OK + */ + public function setNoEmail($no_email) + { + $error = 0; + + // Update mass emailing flag into table mailing_unsubscribe + if ($this->email) + { + $this->db->begin(); + + if ($no_email) + { + $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing', 0).") AND email = '".$this->db->escape($this->email)."'"; + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $noemail = $obj->nb; + if (empty($noemail)) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe(email, entity, date_creat) VALUES ('".$this->db->escape($this->email)."', ".$this->db->escape(getEntity('mailing', 0)).", '".$this->db->idate(dol_now())."')"; + $resql = $this->db->query($sql); + if (!$resql) + { + $error++; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->error; + } + } + } else { + $error++; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->error; + } + } else { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = '".$this->db->escape($this->email)."' AND entity = ".$this->db->escape(getEntity('mailing', 0)); + $resql = $this->db->query($sql); + if (!$resql) + { + $error++; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->error; + } + } + + if (empty($error)) { + $this->no_email = $no_email; + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return $error * -1; + } + } + + return 0; + } + + /** + * get "blacklist" mailing status + * set no_email attribut to 1 or 0 + * + * @return int <0 if KO, >0 if OK + */ + public function getNoEmail() + { + if ($this->email) + { + $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing').") AND email = '".$this->db->escape($this->email)."'"; + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $this->no_email = $obj->nb; + return 1; + } else { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->error; + return -1; + } + } + return 0; + } } diff --git a/htdocs/core/modules/modMailing.class.php b/htdocs/core/modules/modMailing.class.php index 22cc75689a5..75d423e3ecd 100644 --- a/htdocs/core/modules/modMailing.class.php +++ b/htdocs/core/modules/modMailing.class.php @@ -74,6 +74,14 @@ class modMailing extends DolibarrModules // Constants $this->const = array(); + $r = 0; + + $this->const[$r][0] = "MAILING_CONTACT_DEFAULT_BULK_STATUS"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "0"; + $this->const[$r][3] = 'Default black list mailing'; + $this->const[$r][4] = 0; + $r++; // Boxes $this->boxes = array(); diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index a7cfde68ae7..4345dd15d86 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -174,4 +174,6 @@ Unanswered=Unanswered Answered=Answered IsNotAnAnswer=Is not answer (initial email) IsAnAnswer=Is an answer of an initial email -RecordCreatedByEmailCollector=Record created by the Email Collector %s from email %s \ No newline at end of file +RecordCreatedByEmailCollector=Record created by the Email Collector %s from email %s +DefaultBlacklistMailingStatus=Default contact status for refuse bulk emailing +DefaultStatusEmptyMandatory=Empty but mandatory diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index c24689675ea..b1951affe7f 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -394,6 +394,11 @@ if (empty($reshook)) $error++; } + if (!empty($conf->mailing->enabled) && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1 && GETPOST('contact_no_email', 'int')==-1 && !empty(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL))) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("No_Email")), null, 'errors'); + } + if (!$error) { if ($action == 'update') @@ -563,7 +568,8 @@ if (empty($reshook)) { dol_syslog("We ask to create a contact/address too", LOG_DEBUG); $contcats = GETPOST('contcats', 'array'); - $result = $object->create_individual($user, $contcats); + $no_email = GETPOST('contact_no_email', 'int'); + $result = $object->create_individual($user, $no_email, $contcats); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -1147,8 +1153,24 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) $("#selectcountry_id").change(function() { document.formsoc.action.value="create"; document.formsoc.submit(); - }); - });'; + });'; + if ($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1) { + + print ' + function init_check_no_email(input) { + if (input.val()!="") { + $(".noemail").addClass("fieldrequired"); + } else { + $(".noemail").removeClass("fieldrequired"); + } + } + $("#email").keyup(function() { + init_check_no_email($(this)); + }); + init_check_no_email($("#email")); + });'; + } + print '});'; print ''."\n"; print '
    '; @@ -1357,7 +1379,13 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) // Email / Web print '
    '.$form->editfieldkey('EMail', 'email', '', $object, 0, 'string', '', empty($conf->global->SOCIETE_EMAIL_MANDATORY) ? '' : $conf->global->SOCIETE_EMAIL_MANDATORY).'
    '.$form->editfieldkey($langs->trans('No_Email') .' ('.$langs->trans('Contact').')', 'contact_no_email', '', $object, 0).'browser->layout == 'phone') || empty($conf->mailing->enabled) ? ' colspan="3"' : '').'>'.$form->selectyesno('contact_no_email', (GETPOSTISSET("contact_no_email") ?GETPOST("contact_no_email", 'alpha') : $object->no_email), 1, false, 1).'
    '.$form->editfieldkey('Web', 'url', '', $object, 0).''.img_picto('', 'globe').'
    '; @@ -728,7 +728,7 @@ while ($i < min($num, $limit)) // Project ref if (!empty($arrayfields['p.ref']['checked'])) { - print ''; + print ''; print $projectstatic->getNomUrl(1, 'task'); if ($projectstatic->hasDelay()) print img_warning("Late"); print '
    '; //$out.='
    '; - if (is_numeric($this->withsubstit)) $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage - else $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage + if (is_numeric($this->withsubstit)) { + $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage + } else { + $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage + } $out .= "
    '; - if ($this->withtofree) $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients")); - else $out .= $langs->trans("MailTo"); + if ($this->withtofree) { + $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients")); + } else { + $out .= $langs->trans("MailTo"); + } $out .= ''; if ($this->withtoreadonly) { if (!empty($this->toname) && !empty($this->tomail)) { @@ -675,7 +691,9 @@ class FormMail extends Form } // The select combo if (!empty($this->withto) && is_array($this->withto)) { - if (!empty($this->withtofree)) $out .= " ".$langs->trans("and")."/".$langs->trans("or")." "; + if (!empty($this->withtofree)) { + $out .= " ".$langs->trans("and")."/".$langs->trans("or")." "; + } // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time $tmparray = $this->withto; foreach ($tmparray as $key => $val) { @@ -805,7 +823,8 @@ class FormMail extends Form $out .= ''; - if ($this->withmaindocfile) { // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked) + if ($this->withmaindocfile) { + // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked) if (GETPOSTISSET('sendmail')) { $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1); } elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { @@ -847,12 +866,17 @@ class FormMail extends Form } $out .= '
    '; } - } elseif (empty($this->withmaindocfile)) { // Do not show message if we asked to show the checkbox + } elseif (empty($this->withmaindocfile)) { + // Do not show message if we asked to show the checkbox $out .= $langs->trans("NoAttachedFiles").'
    '; } - if ($this->withfile == 2) { // Can add other files - if (!empty($conf->global->FROM_MAIL_USE_INPUT_FILE_MULTIPLE)) $out .= ''; - else $out .= ''; + if ($this->withfile == 2) { + // Can add other files + if (!empty($conf->global->FROM_MAIL_USE_INPUT_FILE_MULTIPLE)) { + $out .= ''; + } else { + $out .= ''; + } $out .= ' '; $out .= ''; } @@ -972,8 +996,11 @@ class FormMail extends Form // Editor wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; if ($this->withfckeditor == -1) { - if (!empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $this->withfckeditor = 1; - else $this->withfckeditor = 0; + if (!empty($conf->global->FCKEDITOR_ENABLE_MAIL)) { + $this->withfckeditor = 1; + } else { + $this->withfckeditor = 0; + } } $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%'); @@ -1118,10 +1145,18 @@ class FormMail extends Form $out .= yn($this->withdeliveryreceipt); } else { $defaultvaluefordeliveryreceipt = 0; - if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') $defaultvaluefordeliveryreceipt = 1; - if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $defaultvaluefordeliveryreceipt = 1; - if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && !empty($this->param['models']) && $this->param['models'] == 'order_send') $defaultvaluefordeliveryreceipt = 1; - if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') $defaultvaluefordeliveryreceipt = 1; + if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') { + $defaultvaluefordeliveryreceipt = 1; + } + if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') { + $defaultvaluefordeliveryreceipt = 1; + } + if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && !empty($this->param['models']) && $this->param['models'] == 'order_send') { + $defaultvaluefordeliveryreceipt = 1; + } + if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') { + $defaultvaluefordeliveryreceipt = 1; + } $out .= $form->selectyesno('deliveryreceipt', (GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt), 1); } $out .= "