From 6d460d78ca38b65cb1e061451656883317de951d Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 29 Jul 2021 11:26:27 +0200 Subject: [PATCH 001/128] NEW : Stocks transfers objects management --- htdocs/admin/stocktransfer.php | 526 +++++++ htdocs/core/menus/standard/eldy.lib.php | 6 + .../core/modules/modStockTransfer.class.php | 535 ++++++++ .../stocktransfer/doc/pdf_eagle.modules.php | 1212 +++++++++++++++++ .../mod_stocktransfer_advanced.php | 150 ++ .../mod_stocktransfer_standard.php | 160 +++ .../stocktransfer/modules_stocktransfer.php | 150 ++ .../install/mysql/migration/14.0.0-15.0.0.sql | 72 + .../llx_stocktransfer_stocktransfer.key.sql | 29 + .../llx_stocktransfer_stocktransfer.sql | 43 + ...transfer_stocktransfer_extrafields.key.sql | 19 + ...tocktransfer_stocktransfer_extrafields.sql | 23 + ...lx_stocktransfer_stocktransferline.key.sql | 24 + .../llx_stocktransfer_stocktransferline.sql | 31 + ...sfer_stocktransferline_extrafields.key.sql | 19 + ...transfer_stocktransferline_extrafields.sql | 23 + htdocs/langs/en_US/stocks.lang | 43 +- htdocs/langs/fr_FR/stocks.lang | 41 + .../class/stocktransfer.class.php | 1107 +++++++++++++++ .../class/stocktransferline.class.php | 1125 +++++++++++++++ .../stocktransfer/lib/stocktransfer.lib.php | 67 + .../lib/stocktransfer_stocktransfer.lib.php | 96 ++ .../stocktransfer/stocktransfer_agenda.php | 260 ++++ .../stocktransfer/stocktransfer_card.php | 1064 +++++++++++++++ .../stocktransfer/stocktransfer_contact.php | 225 +++ .../stocktransfer/stocktransfer_document.php | 211 +++ .../stocktransfer/stocktransfer_list.php | 606 +++++++++ .../stocktransfer/stocktransfer_note.php | 163 +++ 28 files changed, 8029 insertions(+), 1 deletion(-) create mode 100644 htdocs/admin/stocktransfer.php create mode 100644 htdocs/core/modules/modStockTransfer.class.php create mode 100644 htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php create mode 100644 htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php create mode 100644 htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php create mode 100644 htdocs/core/modules/stocktransfer/modules_stocktransfer.php create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.key.sql create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.key.sql create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.key.sql create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.sql create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.key.sql create mode 100644 htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql create mode 100644 htdocs/product/stock/stocktransfer/class/stocktransfer.class.php create mode 100644 htdocs/product/stock/stocktransfer/class/stocktransferline.class.php create mode 100644 htdocs/product/stock/stocktransfer/lib/stocktransfer.lib.php create mode 100644 htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php create mode 100644 htdocs/product/stock/stocktransfer/stocktransfer_agenda.php create mode 100644 htdocs/product/stock/stocktransfer/stocktransfer_card.php create mode 100644 htdocs/product/stock/stocktransfer/stocktransfer_contact.php create mode 100644 htdocs/product/stock/stocktransfer/stocktransfer_document.php create mode 100644 htdocs/product/stock/stocktransfer/stocktransfer_list.php create mode 100644 htdocs/product/stock/stocktransfer/stocktransfer_note.php diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php new file mode 100644 index 00000000000..10d29453a49 --- /dev/null +++ b/htdocs/admin/stocktransfer.php @@ -0,0 +1,526 @@ + + * Copyright (C) 2021 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 stocktransfer/admin/setup.php + * \ingroup stocktransfer + * \brief StockTransfer setup page. + */ + +// 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"); + +global $langs, $user; + +// Libraries +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer.lib.php'; + +// Translations +$langs->loadLangs(array("admin", "stocks")); + +// Access control +if (!$user->admin) accessforbidden(); + +// Parameters +$action = GETPOST('action', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$value = GETPOST('value', 'alpha'); + +$arrayofparameters = array( + 'STOCKTRANSFER_MYPARAM1'=>array('css'=>'minwidth200', 'enabled'=>1), + 'STOCKTRANSFER_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') +{ + $maskconststocktransfer = GETPOST('maskconststocktransfer', 'alpha'); + $maskstocktransfer = GETPOST('maskStockTransfer', 'alpha'); + + if ($maskconststocktransfer) $res = dolibarr_set_const($db, $maskconststocktransfer, $maskstocktransfer, '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/stocktransfer/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, 'stocktransfer', $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 = 'STOCKTRANSFER_'.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 = "StockTransferSetup"; +llxHeader('', $langs->trans($page_name)); + +// Subheader +$linkback = ''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans($page_name), $linkback, 'stock'); + +// Configuration header +$head = stocktransferAdminPrepareHead(); +dol_fiche_head($head, 'settings', '', -1, "stocktransfer@stocktransfer"); + +// Setup page goes here +echo ''.$langs->trans("StockTransferSetupPage").''; + + +/*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 = 'stocktransfer'; +$myTmpObjects = array(); +$myTmpObjects[$moduledir]=array('includerefgeneration'=>1, 'includedocgeneration'=>1); + +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)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp == 'NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + $constforvar = 'STOCKTRANSFER_'.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 = '".$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 = 'STOCKTRANSFER_'.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 +dol_fiche_end(); + +llxFooter(); +$db->close(); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index c192d5e6ac6..5c82d1237f6 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1641,6 +1641,12 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM } } + if($conf->stocktransfer->enabled) { + $newmenu->add('/product/stock/stocktransfer/stocktransfer_list.php', $langs->trans("ModuleStockTransferName"), 0, $user->rights->stocktransfer->stocktransfer->read, '', $mainmenu, 'stocktransfer', 0, '', '', '', img_picto('', 'stock', 'class="pictofixedwidth"')); + $newmenu->add('/product/stock/stocktransfer/stocktransfer_card.php?action=create', $langs->trans('StockTransferNew'), 1, $user->rights->stocktransfer->stocktransfer->write); + $newmenu->add('/product/stock/stocktransfer/stocktransfer_list.php', $langs->trans('List'), 1, $user->rights->stocktransfer->stocktransfer->read); + } + // Inventory if (!empty($conf->stock->enabled)) { $langs->load("stocks"); diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php new file mode 100644 index 00000000000..cc5479410e3 --- /dev/null +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -0,0 +1,535 @@ + + * Copyright (C) 2018-2019 Nicolas ZABOURI + * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2021 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 stocktransfer Module StockTransfer + * \brief StockTransfer module descriptor. + * + * \file htdocs/stocktransfer/core/modules/modStockTransfer.class.php + * \ingroup stocktransfer + * \brief Description and activation file for module StockTransfer + */ +include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; + +/** + * Description and activation class for module StockTransfer + */ +class modStockTransfer extends DolibarrModules +{ + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $langs, $conf; + $this->db = $db; + + $langs->load('stocks'); + // 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 = 701; // 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 = 'stocktransfer'; + // 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 'ModuleStockTransferName' not found (StockTransfer is name of module). + $this->name = preg_replace('/^mod/i', '', get_class($this)); + // Module description, used if translation string 'ModuleStockTransferDesc' not found (StockTransfer is name of module). + $this->description = $langs->trans("ModuleStockTransferDesc"); + // Used only if file README.md and README-LL.md not found. + $this->descriptionlong = "StockTransfer 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 = 'dolibarr'; + // 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 STOCKTRANSFER 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 = 'stock'; + // 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 theme directory (theme) + 'theme' => 0, + // Set this to relative path of css file if module has its own css file + 'css' => array( + // '/stocktransfer/css/stocktransfer.css.php', + ), + // Set this to relative path of js file if module must load a js on all pages + 'js' => array( + // '/stocktransfer/js/stocktransfer.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, + 'contactelement'=>1 + ); + // Data directories to create when module is enabled. + // Example: this->dirs = array("/stocktransfer/temp","/stocktransfer/subdir"); + $this->dirs = array("/stocktransfer/temp"); + // Config pages. Put here list of php page, stored into stocktransfer/admin directory, to use to setup module. + $this->config_page_url = array("stocktransfer.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('modStock', 'modProduct'); + $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("stocktransfer@stocktransfer"); + $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'=>'StockTransferWasAutomaticallyActivatedBecauseOfYourCountryChoice'); + //$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('STOCKTRANSFER_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1), + // 2 => array('STOCKTRANSFER_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->stocktransfer) || !isset($conf->stocktransfer->enabled)) { + $conf->stocktransfer = new stdClass(); + $conf->stocktransfer->enabled = 0; + } + + // Array to add new pages in new tabs + $this->tabs = array(); + // Example: + // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@stocktransfer:$user->rights->stocktransfer->read:/stocktransfer/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1 + // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@stocktransfer:$user->rights->othermodule->read:/stocktransfer/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'=>'stocktransfer@stocktransfer', + // 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->stocktransfer->enabled, $conf->stocktransfer->enabled, $conf->stocktransfer->enabled) + ); + */ + + // Boxes/Widgets + // Add here list of php file(s) stored in stocktransfer/core/boxes that contains a class to show a widget. + $this->boxes = array( + // 0 => array( + // 'file' => 'stocktransferwidget1.php@stocktransfer', + // 'note' => 'Widget provided by StockTransfer', + // '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' => '/stocktransfer/class/stocktransfer.class.php', + // 'objectname' => 'StockTransfer', + // 'method' => 'doScheduledJob', + // 'parameters' => '', + // 'comment' => 'Comment', + // 'frequency' => 2, + // 'unitfrequency' => 3600, + // 'status' => 0, + // 'test' => '$conf->stocktransfer->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->stocktransfer->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->stocktransfer->enabled', 'priority'=>50) + // ); + + // Permissions provided by this module + $this->rights = array(); + $r = 10; + // 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] = $langs->trans('StockTransferRightRead'); // Permission label + $this->rights[$r][4] = 'stocktransfer'; // In php code, permission will be checked by test if ($user->rights->stocktransfer->level1->level2) + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->stocktransfer->level1->level2) + $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = $langs->trans('StockTransferRightCreateUpdate'); // Permission label + $this->rights[$r][4] = 'stocktransfer'; // In php code, permission will be checked by test if ($user->rights->stocktransfer->level1->level2) + $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->stocktransfer->level1->level2) + $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = $langs->trans('StockTransferRightDelete'); // Permission label + $this->rights[$r][4] = 'stocktransfer'; // In php code, permission will be checked by test if ($user->rights->stocktransfer->level1->level2) + $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->stocktransfer->level1->level2) + $r++; + /* END MODULEBUILDER PERMISSIONS */ + + // Main menu entries to add + $langs->load('stocktransfer@stocktransfer'); + $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'=>'ModuleStockTransferName', + 'mainmenu'=>'stocktransfer', + 'leftmenu'=>'', + 'url'=>'/stocktransfer/stocktransferindex.php', + 'langs'=>'stocktransfer@stocktransfer', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000 + $r, + 'enabled'=>'$conf->stocktransfer->enabled', // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->stocktransfer->stocktransfer->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 STOCKTRANSFER + $this->menu[$r++]=array( + 'fk_menu'=>'fk_mainmenu=stocktransfer', // '' 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'=>'StockTransfer', + 'mainmenu'=>'stocktransfer', + 'leftmenu'=>'stocktransfer', + 'url'=>'/stocktransfer/stocktransferindex.php', + 'langs'=>'stocktransfer@stocktransfer', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000+$r, + 'enabled'=>'$conf->stocktransfer->enabled', // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. + 'perms'=>'$user->rights->stocktransfer->stocktransfer->read', // Use 'perms'=>'$user->rights->stocktransfer->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=stocktransfer,fk_leftmenu=stocktransfer', // '' 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 StockTransfer', + 'mainmenu'=>'stocktransfer', + 'leftmenu'=>'stocktransfer_stocktransfer_list', + 'url'=>'/stocktransfer/stocktransfer_list.php', + 'langs'=>'stocktransfer@stocktransfer', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000+$r, + 'enabled'=>'$conf->stocktransfer->enabled', // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'$user->rights->stocktransfer->stocktransfer->read', // Use 'perms'=>'$user->rights->stocktransfer->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=stocktransfer,fk_leftmenu=stocktransfer', // '' 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 StockTransfer', + 'mainmenu'=>'stocktransfer', + 'leftmenu'=>'stocktransfer_stocktransfer_new', + 'url'=>'/stocktransfer/stocktransfer_card.php?action=create', + 'langs'=>'stocktransfer@stocktransfer', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>1000+$r, + 'enabled'=>'$conf->stocktransfer->enabled', // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'$user->rights->stocktransfer->stocktransfer->write', // Use 'perms'=>'$user->rights->stocktransfer->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=products,fk_leftmenu=stock', + // This is a Left menu entry + 'type'=>'left', + 'titre'=>$langs->trans('StockTransferNew'), + 'mainmenu'=>'products', + 'leftmenu'=>'stocktransfer_stocktransfer', + 'url'=>'/stocktransfer/stocktransfer_card.php?action=create', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'stocktransfer@stocktransfer', + 'position'=>1100+$r, + // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->stocktransfer->enabled', + // Use 'perms'=>'$user->rights->stocktransfer->level1->level2' if you want your menu with a permission rules + 'perms'=>'1', + '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=products,fk_leftmenu=stock', + // This is a Left menu entry + 'type'=>'left', + 'titre'=>$langs->trans('StockTransferList'), + 'mainmenu'=>'products', + 'leftmenu'=>'stocktransfer_stocktransferlist', + 'url'=>'/stocktransfer/stocktransfer_list.php', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'stocktransfer@stocktransfer', + 'position'=>1100+$r, + // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->stocktransfer->enabled', + // Use 'perms'=>'$user->rights->stocktransfer->level1->level2' if you want your menu with a permission rules + 'perms'=>'1', + 'target'=>'', + // 0=Menu for internal users, 1=external users, 2=both + 'user'=>2, + );*/ + + /* END MODULEBUILDER LEFTMENU STOCKTRANSFER */ + + // Exports profiles provided by this module + $r = 1; + /* BEGIN MODULEBUILDER EXPORT STOCKTRANSFER */ + /* + $langs->load("stocktransfer@stocktransfer"); + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]='StockTransferLines'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r]='stocktransfer@stocktransfer'; + // Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array + $keyforclass = 'StockTransfer'; $keyforclassfile='/stocktransfer/class/stocktransfer.class.php'; $keyforelement='stocktransfer@stocktransfer'; + 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 = 'StockTransferLine'; $keyforclassfile='/stocktransfer/class/stocktransfer.class.php'; $keyforelement='stocktransferline@stocktransfer'; $keyforalias='tl'; + //include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + $keyforselect='stocktransfer'; $keyforaliasextra='extra'; $keyforelement='stocktransfer@stocktransfer'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$keyforselect='stocktransferline'; $keyforaliasextra='extraline'; $keyforelement='stocktransferline@stocktransfer'; + //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$this->export_dependencies_array[$r] = array('stocktransferline'=>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.'stocktransfer as t'; + //$this->export_sql_end[$r] =' LEFT JOIN '.MAIN_DB_PREFIX.'stocktransfer_line as tl ON tl.fk_stocktransfer = t.rowid'; + $this->export_sql_end[$r] .=' WHERE 1 = 1'; + $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('stocktransfer').')'; + $r++; */ + /* END MODULEBUILDER EXPORT STOCKTRANSFER */ + + // Imports profiles provided by this module + $r = 1; + /* BEGIN MODULEBUILDER IMPORT STOCKTRANSFER */ + /* + $langs->load("stocktransfer@stocktransfer"); + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]='StockTransferLines'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r]='stocktransfer@stocktransfer'; + $keyforclass = 'StockTransfer'; $keyforclassfile='/stocktransfer/class/stocktransfer.class.php'; $keyforelement='stocktransfer@stocktransfer'; + include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + $keyforselect='stocktransfer'; $keyforaliasextra='extra'; $keyforelement='stocktransfer@stocktransfer'; + 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.'stocktransfer as t'; + $this->export_sql_end[$r] .=' WHERE 1 = 1'; + $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('stocktransfer').')'; + $r++; */ + /* END MODULEBUILDER IMPORT STOCKTRANSFER */ + } + + /** + * 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 $db, $conf, $langs; + + $result = $this->_load_tables('/stocktransfer/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('stocktransfer_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'stocktransfer@stocktransfer', '$conf->stocktransfer->enabled'); + //$result2=$extrafields->addExtraField('stocktransfer_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'stocktransfer@stocktransfer', '$conf->stocktransfer->enabled'); + //$result3=$extrafields->addExtraField('stocktransfer_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'stocktransfer@stocktransfer', '$conf->stocktransfer->enabled'); + //$result4=$extrafields->addExtraField('stocktransfer_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'stocktransfer@stocktransfer', '$conf->stocktransfer->enabled'); + //$result5=$extrafields->addExtraField('stocktransfer_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'stocktransfer@stocktransfer', '$conf->stocktransfer->enabled'); + + // Permissions + $this->remove($options); + + $sql = array(); + + // Document templates + $moduledir = 'stocktransfer'; + $myTmpObjects = array(); + $myTmpObjects['StockTransfer']=array('includerefgeneration'=>0, 'includedocgeneration'=>0); + + foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { + if ($myTmpObjectKey == 'StockTransfer') continue; + if ($myTmpObjectArray['includerefgeneration']) { + $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/stocktransfer/template_stocktransfers.odt'; + $dirodt=DOL_DATA_ROOT.'/doctemplates/stocktransfer'; + $dest=$dirodt.'/template_stocktransfers.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.")" + )); + } + } + + // Rôles + $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "internal"'); + $res = $db->fetch_object($resql); + if(empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "internal", "STRESP", "Responsable du transfert de stocks", 1, NULL, 0)'); + + $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STFROM" AND element = "StockTransfer" AND source = "external"'); + $res = $db->fetch_object($resql); + if(empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STFROM", "Contact expéditeur transfert de stocks", 1, NULL, 0)'); + + $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "external"'); + $res = $db->fetch_object($resql); + if(empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STDEST", "Contact destinataire transfert de stocks", 1, NULL, 0)'); + + return $this->_init($sql, $options); + } + + function getNextId() { + + global $db; + + // Get free id for insert + $newid = 0; + $sql = "SELECT max(rowid) newid from ".MAIN_DB_PREFIX."c_type_contact"; + $result = $db->query($sql); + if ($result) + { + $obj = $db->fetch_object($result); + $newid = ($obj->newid + 1); + } else { + dol_print_error($db); + } + return $newid; + } + + /** + * 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/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php new file mode 100644 index 00000000000..c2d595a026e --- /dev/null +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -0,0 +1,1212 @@ + + * Copyright (C) 2005-2012 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2018 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/expedition/doc/pdf_rouget.modules.php + * \ingroup expedition + * \brief Class file used to generate the dispatch slips for the Rouget model + */ + +require_once DOL_DOCUMENT_ROOT . '/core/modules/stocktransfer/modules_stocktransfer.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; + + +/** + * Class to build sending documents with model Eagle + */ +class pdf_eagle extends ModelePdfStockTransfer +{ + /** + * @var DoliDb Database handler + */ + public $db; + + /** + * @var string model name + */ + public $name; + + /** + * @var string model description (short text) + */ + public $description; + + /** + * @var string document type + */ + public $type; + + /** + * @var array Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.5 = array(5, 5) + */ + public $phpmin = array(5, 5); + + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; + + /** + * @var int page_largeur + */ + public $page_largeur; + + /** + * @var int page_hauteur + */ + public $page_hauteur; + + /** + * @var array format + */ + public $format; + + /** + * @var int marge_gauche + */ + public $marge_gauche; + + /** + * @var int marge_droite + */ + public $marge_droite; + + /** + * @var int marge_haute + */ + public $marge_haute; + + /** + * @var int marge_basse + */ + public $marge_basse; + + /** + * Issuer + * @var Societe object that emits + */ + public $emetteur; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db = 0) + { + global $conf, $langs, $mysoc; + + $this->db = $db; + $this->name = $langs->trans("StockTransferSheet"); + $this->description = $langs->trans("DocumentModelStandardPDF"); + + $this->type = 'pdf'; + $formatarray = pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur, $this->page_hauteur); + $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10; + $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10; + $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10; + $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10; + + $this->option_logo = 1; // Display logo + + // Get source company + $this->emetteur = $mysoc; + if (!$this->emetteur->country_code) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined + + // Define position of columns + $this->posxdesc = $this->marge_gauche + 1; + $this->posxlot = $this->page_largeur - $this->marge_droite - 125; + $this->posxqty = $this->page_largeur - $this->marge_droite - 105; + $this->posxwarehousesource = $this->page_largeur - $this->marge_droite - 90; + $this->posxwarehousedestination = $this->page_largeur - $this->marge_droite - 45; + $this->posxpuht = $this->page_largeur - $this->marge_droite; + + /*if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { // Show also the prices + $this->posxqty = $this->page_largeur - $this->marge_droite - 118; + $this->posxwarehousesource = $this->page_largeur - $this->marge_droite - 96; + $this->posxwarehousedestination = $this->page_largeur - $this->marge_droite - 68; + $this->posxpuht = $this->page_largeur - $this->marge_droite - 40; + $this->posxtotalht = $this->page_largeur - $this->marge_droite - 20; + }*/ + + //if (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) $this->posxqty = $this->posxwarehousesource; + + $this->posxpicture = $this->posxqty - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images + + // To work with US executive format + if ($this->page_largeur < 210) { + $this->posxqty -= 20; + $this->posxpicture -= 20; + $this->posxwarehousesource -= 20; + $this->posxwarehousedestination -= 20; + } + + if (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) { + $this->posxqty += ($this->posxwarehousedestination - $this->posxwarehousesource); + $this->posxpicture += ($this->posxwarehousedestination - $this->posxwarehousesource); + $this->posxwarehousesource = $this->posxwarehousedestination; + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function to build pdf onto disk + * + * @param Object $object Object StockTransfer to generate (or id if old method) + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + // phpcs:enable + global $db, $user, $conf, $langs, $hookmanager; + + $object->fetch_thirdparty(); + + $this->atLeastOneBatch = $this->atLeastOneBatch($object); + + if (!is_object($outputlangs)) $outputlangs = $langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (!empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output = 'ISO-8859-1'; + + // Load traductions files required by page + $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies", "propal", "deliveries", "sendings", "productbatch", "stocks", "stocktransfer@stocktransfer")); + + $nblines = count($object->lines); + + // Loop on each lines to detect if there is at least one image to show + $realpatharray = array(); + if (!empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE)) + { + $objphoto = new Product($this->db); + + for ($i = 0; $i < $nblines; $i++) + { + if (empty($object->lines[$i]->fk_product)) continue; + + $objphoto = new Product($this->db); + $objphoto->fetch($object->lines[$i]->fk_product); + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/"; + $dir = $conf->product->dir_output.'/'.$pdir; + } + else + { + $pdir = get_exdir(0, 2, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; + $dir = $conf->product->dir_output.'/'.$pdir; + } + + $realpath = ''; + + foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { + // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + if ($obj['photo_vignette']) + { + $filename = $obj['photo_vignette']; + } + else + { + $filename = $obj['photo']; + } + } + else + { + $filename = $obj['photo']; + } + + $realpath = $dir.$filename; + break; + } + + if ($realpath) $realpatharray[$i] = $realpath; + } + } + + if (count($realpatharray) == 0) $this->posxpicture = $this->posxqty; + + if ($conf->stocktransfer->dir_output) + { + // Definition de $dir et $file + if ($object->specimen) + { + $dir = $conf->stocktransfer->dir_output; + $file = $dir."/SPECIMEN.pdf"; + } + else + { + $stocktransferref = dol_sanitizeFileName($object->ref); + $dir = $conf->stocktransfer->dir_output.'/'.$object->element."/".$stocktransferref; + $file = $dir."/".$stocktransferref.".pdf"; + } + + if (!file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (!is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + + // Set nblines with the new facture lines content after hook + $nblines = count($object->lines); + + $pdf = pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); + $heightforinfotot = 8; // Height reserved to output the info and total part + $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) + if ($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS > 0) $heightforfooter += 6; + $pdf->SetAutoPageBreak(1, 0); + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + // Set path to the background PDF File + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb = 0; + $pdf->SetDrawColor(128, 128, 128); + + if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("Shipment")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Shipment")); + if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + // New page + $pdf->AddPage(); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0, 0, 0); + + $tab_top = 90; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 : 10); + $tab_height = 130; + $tab_height_newpage = 150; + + // Incoterm + $height_incoterms = 0; + if ($conf->incoterm->enabled) + { + $desc_incoterms = $object->getIncotermsForPDF(); + if ($desc_incoterms) + { + $tab_top = 88; + + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1); + $nexY = $pdf->GetY(); + $height_incoterms = $nexY - $tab_top; + + // Rect takes a length in 3rd parameter + $pdf->SetDrawColor(192, 192, 192); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1); + + $tab_top = $nexY + 6; + $height_incoterms += 4; + } + } + + if (!empty($object->note_public) || !empty($object->tracking_number)) + { + $tab_top = 88 + $height_incoterms; + $tab_top_alt = $tab_top; + + $pdf->SetFont('', 'B', $default_font_size - 2); + + //$tab_top_alt += 1; + + // Tracking number + if (!empty($object->tracking_number)) + { + $pdf->writeHTMLCell(60, 4, $this->posxdesc - 1, $tab_top - 1, $outputlangs->transnoentities("TrackingNumber")." : ".$object->tracking_number, 0, 1, false, true, 'L'); + $tab_top_alt = $pdf->GetY(); + + $object->getUrlTrackingStatus($object->tracking_number); + if (!empty($object->tracking_url)) + { + if ($object->shipping_method_id > 0) + { + // Get code using getLabelFromKey + $code = $outputlangs->getLabelFromKey($this->db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); + $label = ''; + if ($object->tracking_url != $object->tracking_number) $label .= $outputlangs->trans("LinkToTrackYourPackage")."
"; + $label .= $outputlangs->trans("SendingMethod").": ".$outputlangs->trans("SendingMethod".strtoupper($code)); + //var_dump($object->tracking_url != $object->tracking_number);exit; + if ($object->tracking_url != $object->tracking_number) + { + $label .= " : "; + $label .= $object->tracking_url; + } + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->writeHTMLCell(60, 4, $this->posxdesc - 1, $tab_top_alt, $label, 0, 1, false, true, 'L'); + + $tab_top_alt = $pdf->GetY(); + } + } + } + + // Notes + if (!empty($object->note_public)) + { + $pdf->SetFont('', '', $default_font_size - 1); // Dans boucle pour gerer multi-page + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1); + } + + $nexY = $pdf->GetY(); + $height_note = $nexY - $tab_top; + + // Rect takes a length in 3rd parameter + $pdf->SetDrawColor(192, 192, 192); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1); + + $tab_height = $tab_height - $height_note; + $tab_top = $nexY + 6; + } + else + { + $height_note = 0; + } + + $iniY = $tab_top + 7; + $curY = $tab_top + 7; + $nexY = $tab_top + 7; + + $TCacheEntrepots=array(); + // Loop on each lines + for ($i = 0; $i < $nblines; $i++) + { + $curY = $nexY; + $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0, 0, 0); + + // Define size of image if we need it + $imglinesize = array(); + if (!empty($realpatharray[$i])) $imglinesize = pdf_getSizeForImage($realpatharray[$i]); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore = $pdf->getPage(); + + $showpricebeforepagebreak = 1; + $posYAfterImage = 0; + $posYAfterDescription = 0; + + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page + { + $pdf->AddPage('', '', true); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pageposbefore + 1); + + $curY = $tab_top_newpage; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; + } + + if (isset($imglinesize['width']) && isset($imglinesize['height'])) + { + $curX = $this->posxpicture - 1; + $pdf->Image($realpatharray[$i], $curX + (($this->posxqty - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage = $curY + $imglinesize['height']; + } + + // Description of product line + $curX = $this->posxdesc - 1; + + $pdf->startTransaction(); + if(method_exists($object->lines[$i], 'fetch_product')) { + $object->lines[$i]->fetch_product(); + $object->lines[$i]->label = $object->lines[$i]->product->label; + $object->lines[$i]->description = $object->lines[$i]->product->description; + } + //var_dump($object->lines[$i]->product);exit; + pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc); + + $pageposafter = $pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter = $pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc); + + $pageposafter = $pdf->getPage(); + $posyafter = $pdf->GetY(); + //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page + { + $pdf->AddPage('', '', true); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pageposafter + 1); + } + } + else + { + // We found a page break + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $posYAfterDescription = $pdf->GetY(); + + $nexY = $pdf->GetY(); + $pageposafter = $pdf->getPage(); + + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description or photo were moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + // We suppose that a too long description is moved completely on next page + if ($pageposafter > $pageposbefore) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut + + + $pdf->SetXY($this->posxqty, $curY); + // Lot / série + if(!empty($conf->productbatch->enabled)) { + $pdf->SetXY($this->posxlot, $curY); + $pdf->MultiCell(($this->posxqty - $this->posxlot), 3, $object->lines[$i]->batch, '', 'C'); + } + + // Qty + $pdf->SetXY($this->posxqty, $curY); + $pdf->writeHTMLCell($this->posxwarehousesource - $this->posxqty + 2, 3, $this->posxqty - 1, $curY, $object->lines[$i]->qty, 0, 0, false, true, 'C'); + //$pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), 3, $weighttxt.(($weighttxt && $voltxt)?'
':'').$voltxt,'','C'); + + // Warehouse source + $wh_source = new Entrepot($db); + if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_source])) $wh_source = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source]; + else { + $wh_source->fetch($object->lines[$i]->fk_warehouse_source); + $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source] = $wh_source; + } + $pdf->SetXY($this->posxwarehousesource, $curY); + $pdf->MultiCell(($this->posxwarehousedestination - $this->posxwarehousesource), 3, $wh_source->ref.(!empty($wh_source->lieu) ? ' - '.$wh_source->lieu : ''), '', 'C'); + + // Warehouse destination + $wh_destination = new Entrepot($db); + if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination])) $wh_destination = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination]; + else { + $wh_destination->fetch($object->lines[$i]->fk_warehouse_destination); + $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination] = $wh_destination; + } + $pdf->SetXY($this->posxwarehousedestination, $curY); + $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination), 3, $wh_destination->ref.(!empty($wh_destination->lieu) ? ' - '.$wh_destination->lieu : ''), '', 'C'); + + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) + { + $pdf->SetXY($this->posxpuht, $curY); + $pdf->MultiCell(($this->posxtotalht - $this->posxpuht - 1), 3, price($object->lines[$i]->subprice, 0, $outputlangs), '', 'R'); + + $pdf->SetXY($this->posxtotalht, $curY); + $pdf->MultiCell(($this->page_largeur - $this->marge_droite - $this->posxtotalht), 3, price($object->lines[$i]->total_ht, 0, $outputlangs), '', 'R'); + } + + $nexY += 3; + if ($weighttxt && $voltxt) $nexY += 2; + + // Add line + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) + { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY - 1, $this->page_largeur - $this->marge_droite, $nexY - 1); + $pdf->SetLineStyle(array('dash'=>0)); + } + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) + { + $pdf->setPage($pagenb); + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) + { + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + // New page + $pdf->AddPage(); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + + // Show square + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + + // Affiche zone totaux + //$posy = $this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); + + // Pied de page + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file, 'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) + { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + } + + if (!empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $this->result = array('fullpath'=>$file); + + return 1; // No error + } + else + { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } + else + { + $this->error = $langs->transnoentities("ErrorConstantNotDefined", "EXP_OUTPUTDIR"); + return 0; + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Show total to pay + * + * @param PDF $pdf Object PDF + * @param Facture $object Object invoice + * @param int $deja_regle Montant deja regle + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs) + { + // phpcs:enable + global $conf, $mysoc; + + $sign = 1; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $tab2_top = $posy; + $tab2_hl = 4; + $pdf->SetFont('', 'B', $default_font_size - 1); + + // Tableau total + $col1x = $this->posxqty - 50; $col2x = $this->posxqty; + /*if ($this->page_largeur < 210) // To work with US executive format + { + $col2x-=20; + }*/ + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) $largcol2 = ($this->posxwarehousesource - $this->posxqty); + else $largcol2 = ($this->posxwarehousedestination - $this->posxqty); + + $useborder = 0; + $index = 0; + + $totalWeighttoshow = ''; + $totalVolumetoshow = ''; + + // Load dim data + $tmparray = $object->getTotalWeightVolume(); + $totalWeight = $tmparray['weight']; + $totalVolume = $tmparray['volume']; + $totalOrdered = $tmparray['ordered']; + $totalToShip = $tmparray['toship']; + // Set trueVolume and volume_units not currently stored into database + if ($object->trueWidth && $object->trueHeight && $object->trueDepth) + { + $object->trueVolume = price(($object->trueWidth * $object->trueHeight * $object->trueDepth), 0, $outputlangs, 0, 0); + $object->volume_units = $object->size_units * 3; + } + + if ($totalWeight != '') $totalWeighttoshow = showDimensionInBestUnit($totalWeight, 0, "weight", $outputlangs); + if ($totalVolume != '') $totalVolumetoshow = showDimensionInBestUnit($totalVolume, 0, "volume", $outputlangs); + if ($object->trueWeight) $totalWeighttoshow = showDimensionInBestUnit($object->trueWeight, $object->weight_units, "weight", $outputlangs); + if ($object->trueVolume) $totalVolumetoshow = showDimensionInBestUnit($object->trueVolume, $object->volume_units, "volume", $outputlangs); + + $pdf->SetFillColor(255, 255, 255); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Total"), 0, 'L', 1); + + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) + { + $pdf->SetXY($this->posxwarehousesource, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->posxwarehousedestination - $this->posxwarehousesource, $tab2_hl, $totalOrdered, 0, 'C', 1); + } + + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_QTYTOSHIP)) + { + $pdf->SetXY($this->posxwarehousedestination, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->posxpuht - $this->posxwarehousedestination, $tab2_hl, $totalToShip, 0, 'C', 1); + } + + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) + { + $pdf->SetXY($this->posxpuht, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->posxtotalht - $this->posxpuht, $tab2_hl, '', 0, 'C', 1); + + $pdf->SetXY($this->posxtotalht, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxtotalht, $tab2_hl, price($object->total_ht, 0, $outputlangs), 0, 'C', 1); + } + + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) + { + // Total Weight + if ($totalWeighttoshow) + { + $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), $tab2_hl, $totalWeighttoshow, 0, 'C', 1); + + $index++; + } + if ($totalVolumetoshow) + { + $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), $tab2_hl, $totalVolumetoshow, 0, 'C', 1); + + $index++; + } + if (!$totalWeighttoshow && !$totalVolumetoshow) $index++; + } + + $pdf->SetTextColor(0, 0, 0); + + return ($tab2_top + ($tab2_hl * $index)); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show table for lines + * + * @param PDF $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y + * @param Translate $outputlangs Langs object + * @param int $hidetop Hide top bar of array + * @param int $hidebottom Hide bottom bar of array + * @return void + */ + protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0) + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom = 0; + if ($hidetop) $hidetop = -1; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + + // Output Rect + $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter + + $pdf->SetDrawColor(128, 128, 128); + $pdf->SetFont('', '', $default_font_size - 1); + + if (empty($hidetop)) + { + $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5); + + $pdf->SetXY($this->posxdesc - 1, $tab_top + 1); + $pdf->MultiCell($this->posxwarehousesource - $this->posxdesc, 2, $outputlangs->transnoentities("Description"), '', 'L'); + } + + if(!empty($conf->productbatch->enabled) && $this->atLeastOneBatch) { + $pdf->line($this->posxlot - 1, $tab_top, $this->posxlot - 1, $tab_top + $tab_height); + if (empty($hidetop)) { + $pdf->SetXY($this->posxlot - 8, $tab_top + 1); + $pdf->MultiCell(($this->posxwarehousesource - $this->posxlot), 2, $outputlangs->transnoentities("Batch"), '', 'C'); + } + } + + $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxqty - 1, $tab_top + 1); + $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), 2, $outputlangs->transnoentities("Qty"), '', 'C'); + } + + $pdf->line($this->posxwarehousesource - 1, $tab_top, $this->posxwarehousesource - 1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxwarehousesource - 1, $tab_top + 1); + $pdf->MultiCell(($this->posxwarehousedestination - $this->posxwarehousesource), 2, $outputlangs->transnoentities("WarehouseSource"), '', 'C'); + } + + + $pdf->line($this->posxwarehousedestination - 1, $tab_top, $this->posxwarehousedestination - 1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxwarehousedestination-2.5, $tab_top + 1); + $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination+4), 2, $outputlangs->transnoentities("WarehouseTarget"), '', 'C'); + } + + /*if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { + $pdf->line($this->posxpuht - 1, $tab_top, $this->posxpuht - 1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxpuht - 1, $tab_top + 1); + $pdf->MultiCell(($this->posxtotalht - $this->posxpuht), 2, $outputlangs->transnoentities("PriceUHT"), '', 'C'); + } + + $pdf->line($this->posxtotalht - 1, $tab_top, $this->posxtotalht - 1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxtotalht - 1, $tab_top + 1); + $pdf->MultiCell(($this->page_largeur - $this->marge_droite - $this->posxtotalht), 2, $outputlangs->transnoentities("TotalHT"), '', 'C'); + } + }*/ + } + + function atLeastOneBatch($object) { + + $atLeastOneBatch = false; + + foreach ($object->lines as $line) { + if(!empty($line->batch)) { + return true; + } + } + + return false; + + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show top header of page. + * + * @param PDF $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @return void + */ + protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs) + { + global $conf, $langs, $mysoc; + + $langs->load("orders"); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); + + // Show Draft Watermark + if ($object->statut == 0 && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) + { + pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->SHIPPING_DRAFT_WATERMARK); + } + + //Prepare la suite + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFont('', 'B', $default_font_size + 3); + + $w = 110; + + $posy = $this->marge_haute; + $posx = $this->page_largeur - $this->marge_droite - $w; + + $pdf->SetXY($this->marge_gauche, $posy); + + // Logo + $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) + { + if (is_readable($logo)) + { + $height = pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } + else + { + $text = $this->emetteur->name; + $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + + // Show barcode + if (!empty($conf->barcode->enabled)) + { + $posx = 105; + } + else + { + $posx = $this->marge_gauche + 3; + } + //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); + if (!empty($conf->barcode->enabled)) + { + // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref + //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); + //$pdf->Image($logo,10, 5, 0, 24); + } + + $pdf->SetDrawColor(128, 128, 128); + if (!empty($conf->barcode->enabled)) + { + // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref + //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); + //$pdf->Image($logo,10, 5, 0, 24); + } + + + $posx = $this->page_largeur - $w - $this->marge_droite; + $posy = $this->marge_haute; + + $pdf->SetFont('', 'B', $default_font_size + 2); + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $title = $outputlangs->transnoentities("StockTransferSheet"); + $pdf->MultiCell($w, 4, $title, '', 'R'); + + $pdf->SetFont('', '', $default_font_size + 1); + + $posy += 5; + + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("Ref")." : ".$object->ref, '', 'R'); + + // Date reelle depart + if (!empty($object->date_prevue_depart)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DatePrevueDepart")." : ".dol_print_date($object->date_prevue_depart, "day", false, $outputlangs, true), '', 'R'); + } + + // Date reelle arrivée + if (!empty($object->date_prevue_arrivee)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DatePrevueArrivee")." : ".dol_print_date($object->date_prevue_arrivee, "day", false, $outputlangs, true), '', 'R'); + } + + // Date reelle depart + if (!empty($object->date_reelle_depart)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleDepart")." : ".dol_print_date($object->date_reelle_depart, "day", false, $outputlangs, true), '', 'R'); + } + + // Date reelle arrivée + if (!empty($object->date_reelle_arrivee)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); + } + + if (!empty($object->thirdparty->code_client)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); + } + + + $pdf->SetFont('', '', $default_font_size + 3); + $Yoff = 25; + + // Add list of linked orders + $origin = $object->origin; + $origin_id = $object->origin_id; + + // TODO move to external function + if (!empty($conf->$origin->enabled)) // commonly $origin='commande' + { + $outputlangs->load('orders'); + + $classname = ucfirst($origin); + $linkedobject = new $classname($this->db); + $result = $linkedobject->fetch($origin_id); + if ($result >= 0) + { + //$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects + + $pdf->SetFont('', '', $default_font_size - 2); + $text = $linkedobject->ref; + if ($linkedobject->ref_client) $text .= ' ('.$linkedobject->ref_client.')'; + $Yoff = $Yoff + 8; + $pdf->SetXY($this->page_largeur - $this->marge_droite - $w, $Yoff); + $pdf->MultiCell($w, 2, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), 0, 'R'); + $Yoff = $Yoff + 3; + $pdf->SetXY($this->page_largeur - $this->marge_droite - $w, $Yoff); + $pdf->MultiCell($w, 2, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($linkedobject->date, "day", false, $outputlangs, true), 0, 'R'); + } + } + + if ($showaddress) + { + // Sender properties + $carac_emetteur = ''; + // Add internal contact of origin element if defined + $arrayidcontact = array(); + $arrayidcontact = $object->getIdContact('external', 'STFROM'); + + $usecontact = false; + if (count($arrayidcontact) > 0) + { + /*$object->fetch_user(reset($arrayidcontact)); + $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ + $usecontact = true; + $result = $object->fetch_contact($arrayidcontact[0]); + } + + if ($usecontact) $thirdparty = $object->contact; + else $thirdparty = $this->emetteur; + + if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + + if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); + + // Show sender + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posx = $this->marge_gauche; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->page_largeur - $this->marge_droite - 80; + + $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40; + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82; + + // Show sender frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx, $posy - 5); + $pdf->MultiCell(66, 5, $outputlangs->transnoentities("Sender").":", 0, 'L'); + $pdf->SetXY($posx, $posy); + $pdf->SetFillColor(230, 230, 230); + $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFillColor(255, 255, 255); + + // Show sender name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($carac_emetteur_name), 0, 'L'); + $posy = $pdf->getY(); + + // Show sender information + $pdf->SetXY($posx + 2, $posy); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L'); + + + // If SHIPPING contact defined, we use it + $usecontact = false; + $arrayidcontact = $object->getIdContact('external', 'STDEST'); + if (count($arrayidcontact) > 0) + { + $usecontact = true; + $result = $object->fetch_contact($arrayidcontact[0]); + } + + //Recipient name + // On peut utiliser le nom de la societe du contact + if ($usecontact/* && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)*/) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); + + // Show recipient + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100; + if ($this->page_largeur < 210) $widthrecbox = 84; // To work with US executive format + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posx = $this->page_largeur - $this->marge_droite - $widthrecbox; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->marge_gauche; + + // Show recipient frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx + 2, $posy - 5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("Recipient").":", 0, 'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->SetXY($posx + 2, $posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0, 0, 0); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0) + { + global $conf; + $showdetails = $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf, $outputlangs, 'SHIPPING_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext); + } +} diff --git a/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php b/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php new file mode 100644 index 00000000000..60207efb650 --- /dev/null +++ b/htdocs/core/modules/stocktransfer/mod_stocktransfer_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/stocktransfer/mod_stocktransfer_advanced.php + * \ingroup stocktransfer + * \brief File containing class for advanced numbering model of StockTransfer + */ + +require_once DOL_DOCUMENT_ROOT . '/core/modules/stocktransfer/modules_stocktransfer.php'; + + +/** + * Class to manage customer Bom numbering rules advanced + */ +class mod_stocktransfer_advanced extends ModeleNumRefStockTransfer +{ + /** + * 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 = 'got2be'; + + + /** + * 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("StockTransfer"), $langs->transnoentities("StockTransfer")); + $tooltip .= $langs->trans("GenericMaskCodes2"); + $tooltip .= $langs->trans("GenericMaskCodes3"); + $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("StockTransfer"), $langs->transnoentities("StockTransfer")); + $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 StockTransfer($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->STOCKTRANSFER_STOCKTRANSFER_ADVANCED_MASK; + + if (!$mask) + { + $this->error = 'NotConfigured'; + return 0; + } + + $date = $object->date; + + $numFinal = get_next_value($db, $mask, 'stocktransfer_stocktransfer', 'ref', '', null, $date); + + return $numFinal; + } +} diff --git a/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php b/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php new file mode 100644 index 00000000000..d4a06024136 --- /dev/null +++ b/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php @@ -0,0 +1,160 @@ + + * 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/stocktransfer/mod_stocktransfer_standard.php + * \ingroup stocktransfer + * \brief File of class to manage StockTransfer numbering rules standard + */ +require_once DOL_DOCUMENT_ROOT . '/core/modules/stocktransfer/modules_stocktransfer.php'; + + +/** + * Class to manage customer order numbering rules standard + */ +class mod_stocktransfer_standard extends ModeleNumRefStockTransfer +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + public $prefix = 'ST'; + + /** + * @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."stocktransfer_stocktransfer"; + $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."stocktransfer_stocktransfer"; + $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) + { + $obj = $db->fetch_object($resql); + if ($obj) $max = intval($obj->max); + else $max = 0; + } + else + { + dol_syslog("mod_stocktransfer_standard::getNextValue", LOG_DEBUG); + return -1; + } + + //$date=time(); + $date = $object->date_creation; + $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_stocktransfer_standard::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } +} diff --git a/htdocs/core/modules/stocktransfer/modules_stocktransfer.php b/htdocs/core/modules/stocktransfer/modules_stocktransfer.php new file mode 100644 index 00000000000..0394f8ac1f0 --- /dev/null +++ b/htdocs/core/modules/stocktransfer/modules_stocktransfer.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/stocktransfer/modules_stocktransfer.php + * \ingroup stocktransfer + * \brief File that contains parent class for stocktransfers document models and parent class for stocktransfers 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 ModelePDFStockTransfer 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 = 'stocktransfer'; + $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 StockTransfer + */ +abstract class ModeleNumRefStockTransfer +{ + /** + * @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("stocktransfer@stocktransfer"); + return $langs->trans("NoDescription"); + } + + /** + * Returns an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $langs; + $langs->load("stocktransfer@stocktransfer"); + 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/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 8eaf1767b8a..b9243f11823 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -39,3 +39,75 @@ ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN ref_fourn varchar(128); ALTER TABLE llx_product_customer_price MODIFY COLUMN ref_customer varchar(128); +CREATE TABLE llx_stocktransfer_stocktransfer( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + entity integer DEFAULT 1 NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + fk_soc integer, + fk_project integer, + fk_warehouse_source integer, + fk_warehouse_destination integer, + description text, + note_public text, + note_private text, + tms timestamp, + date_creation datetime NOT NULL, + date_prevue_depart date DEFAULT NULL, + date_reelle_depart date DEFAULT NULL, + date_prevue_arrivee date DEFAULT NULL, + date_reelle_arrivee date DEFAULT NULL, + lead_time_for_warning integer DEFAULT NULL, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_rowid (rowid); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_ref (ref); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_soc (fk_soc); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_project (fk_project); +ALTER TABLE llx_stocktransfer_stocktransfer ADD CONSTRAINT llx_stocktransfer_stocktransfer_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_status (status); + +CREATE TABLE llx_stocktransfer_stocktransferline( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + amount double DEFAULT NULL, + qty real, + fk_warehouse_source integer NOT NULL, + fk_warehouse_destination integer NOT NULL, + fk_stocktransfer integer NOT NULL, + fk_product integer NOT NULL, + batch varchar(128) DEFAULT NULL, -- Lot or serial number + pmp double, + rang integer DEFAULT 0, + fk_parent_line integer NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransferline ADD INDEX idx_stocktransfer_stocktransferline_rowid (rowid); + +create table llx_stocktransfer_stocktransfer_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransfer_extrafields ADD INDEX idx_fk_object(fk_object); + +create table llx_stocktransfer_stocktransferline_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransferline_extrafields ADD INDEX idx_fk_object(fk_object); diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.key.sql new file mode 100644 index 00000000000..74108a5face --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.key.sql @@ -0,0 +1,29 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_rowid (rowid); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_ref (ref); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_soc (fk_soc); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_project (fk_project); +ALTER TABLE llx_stocktransfer_stocktransfer ADD CONSTRAINT llx_stocktransfer_stocktransfer_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_status (status); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_stocktransfer_stocktransfer ADD UNIQUE INDEX uk_stocktransfer_stocktransfer_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_stocktransfer_stocktransfer ADD CONSTRAINT llx_stocktransfer_stocktransfer_fk_field FOREIGN KEY (fk_field) REFERENCES llx_stocktransfer_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql new file mode 100644 index 00000000000..31bd144ef5e --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql @@ -0,0 +1,43 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransfer( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + entity integer DEFAULT 1 NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + fk_soc integer, + fk_project integer, + fk_warehouse_source integer, + fk_warehouse_destination integer, + description text, + note_public text, + note_private text, + tms timestamp, + date_creation datetime NOT NULL, + date_prevue_depart date DEFAULT NULL, + date_reelle_depart date DEFAULT NULL, + date_prevue_arrivee date DEFAULT NULL, + date_reelle_arrivee date DEFAULT NULL, + lead_time_for_warning integer DEFAULT NULL, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.key.sql new file mode 100644 index 00000000000..36850341a6c --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.key.sql @@ -0,0 +1,19 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransfer_extrafields ADD INDEX idx_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql new file mode 100644 index 00000000000..33a91fc1070 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql @@ -0,0 +1,23 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransfer_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.key.sql new file mode 100644 index 00000000000..32dfbd8bcd2 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.key.sql @@ -0,0 +1,24 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransferline ADD INDEX idx_stocktransfer_stocktransferline_rowid (rowid); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_stocktransfer_stocktransferline ADD UNIQUE INDEX uk_stocktransfer_stocktransferline_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_stocktransfer_stocktransferline ADD CONSTRAINT llx_stocktransfer_stocktransferline_fk_field FOREIGN KEY (fk_field) REFERENCES llx_stocktransfer_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.sql new file mode 100644 index 00000000000..10c22fed32c --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.sql @@ -0,0 +1,31 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransferline( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + amount double DEFAULT NULL, + qty real, + fk_warehouse_source integer NOT NULL, + fk_warehouse_destination integer NOT NULL, + fk_stocktransfer integer NOT NULL, + fk_product integer NOT NULL, + batch varchar(128) DEFAULT NULL, -- Lot or serial number + pmp double, + rang integer DEFAULT 0, + fk_parent_line integer NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.key.sql new file mode 100644 index 00000000000..a35079cbf0c --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.key.sql @@ -0,0 +1,19 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransferline_extrafields ADD INDEX idx_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql new file mode 100644 index 00000000000..5b5080441bd --- /dev/null +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql @@ -0,0 +1,23 @@ +-- Copyright (C) ---Put here your own copyright and developer email--- +-- 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 +-- 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_stocktransfer_stocktransferline_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index efa5257498c..4143eaacdc9 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -255,4 +255,45 @@ MakeMovementsAndClose=Generate movements and close AutofillWithExpected=Fill real quantity with expected quantity ShowAllBatchByDefault=By default, show batch details on product "stock" tab CollapseBatchDetailHelp=You can set batch detail default display in stocks module configuration -FieldCannotBeNegative=Field "%s" cannot be negative \ No newline at end of file +FieldCannotBeNegative=Field "%s" cannot be negative + +ModuleStockTransferName=Stocks Transfer +ModuleStockTransferDesc=Creation of stocks transfer objects, with generation of transfer sheet +StockTransferNew=New stocks transfer +StockTransferList=Stocks transfers list +ConfirmValidateStockTransfer=Are you sure you want to validate this stocks transfer with reference %s ? +ConfirmDestock=Decrease of stocks with transfer %s +ConfirmDestockCancel=Cancel decrease of stocks with transfer %s +DestockAllProduct=Decrease of stocks +DestockAllProductCancel=Cancel decrease of stocks +ConfirmAddStock=Increase stocks with transfer %s +ConfirmAddStockCancel=Cancel increase of stocks with transfer %s +AddStockAllProduct=Increase of stocks +AddStockAllProductCancel=Cancel increase of stocks +DatePrevueDepart=Intended date of departure +DateReelleDepart=Real date of departure +DatePrevueArrivee=Intended date of arrival +DateReelleArrivee=Real date of arrival +HelpWarehouseStockTransferSource=If this warehouse is set, only itself and its children will be available as source warehouse +HelpWarehouseStockTransferDestination=If this warehouse is set, only itself and its children will be available as destination warehouse +LeadTimeForWarning=Lead time before alert (in days) +TypeContact_stocktransfer_internal_STFROM=Sender of stocks transfer +TypeContact_stocktransfer_internal_STDEST=Recipient of stocks transfer +TypeContact_stocktransfer_internal_STRESP=Responsible of stocks transfer +StockTransferSheet=Stocks transfer sheet +StockTransferDecrementation=Decrease source warehouses +StockTransferIncrementation=Increase destination warehouses +StockTransferDecrementationCancel=Cancel decrease of source warehouses +StockTransferIncrementationCancel=Cancel increase of destination warehouses +StockStransferDecremented=Source warehouses decreased +StockStransferDecrementedCancel=Decrease of source warehouses canceled +StockStransferIncremented=Closed - Stocks transfered +StockStransferIncrementedShort=Stocks transfered +StockStransferIncrementedShortCancel=Increase of destination warehouses canceled +StockTransferNoBatchForProduct=Product %s doesn't use batch, clear batch on line and retry +StockTransferSetup = Stocks Transfer module configuration +Settings=Settings +StockTransferSetupPage = Configuration page for stocks transfer module +StockTransferRightRead=Read stocks transfers +StockTransferRightCreateUpdate=Create/Update stocks transfers +StockTransferRightDelete=Delete stocks transfers diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index f0fe7235a77..d832b160d02 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -256,3 +256,44 @@ AutofillWithExpected=Remplir la quantité réelle avec la quantité prévue ShowAllBatchByDefault=Par défaut, afficher les détails des lots sur l'onglet "stock" du produit CollapseBatchDetailHelp=You can set batch detail default display in stocks module configuration FieldCannotBeNegative=Le champ "%s" ne peut pas être négatif + +ModuleStockTransferName = Transferts de stocks +ModuleStockTransferDesc = Création d'objets transfert de stocks, avec génération de bons de transfert +StockTransferNew=Nouveau transfert de stocks +StockTransferList=Liste des transferts de stocks +ConfirmValidateStockTransfer=Êtes-vous sûr de vouloir valider ce transfert de stocks sous la référence %s ? +ConfirmDestock=Décrémentation des stocks via transfert %s +ConfirmDestockCancel=Annulation décrémentation des stocks via transfert %s +DestockAllProduct=Décrémentation des stocks +DestockAllProductCancel=Annulation décrémentation des stocks +ConfirmAddStock=Incrémentation des stocks via transfert %s +ConfirmAddStockCancel=Annulation incrémentation des stocks via transfert %s +AddStockAllProduct=Incrémentation des stocks +AddStockAllProductCancel=Annulation incrémentation des stocks +DatePrevueDepart=Date prévue de départ +DateReelleDepart=Date réelle de départ +DatePrevueArrivee=Date prévue d'arrivée +DateReelleArrivee=Date réelle d'arrivée +HelpWarehouseStockTransferSource=Si renseigné, seul cet entrepôt source et ses enfants seront sélectionnables pour l'ajout des lignes +HelpWarehouseStockTransferDestination=Si renseigné, seul cet entrepôt de destination et ses enfants seront sélectionnables pour l'ajout des lignes +LeadTimeForWarning=Délai pour alerte (en jours) +TypeContact_stocktransfer_internal_STFROM=Contact expéditeur transfert de stocks +TypeContact_stocktransfer_internal_STDEST=Contact destinataire transfert de stocks +TypeContact_stocktransfer_internal_STRESP=Responsable du transfert de stocks +StockTransferSheet=Bon de transfert +StockTransferDecrementation=Décrémenter les entrepôts sources +StockTransferIncrementation=Incrémenter les entrepôts de destination +StockTransferDecrementationCancel=Annuler décrémentation des entrepôts sources +StockTransferIncrementationCancel=Annuler incrémentation des entrepôts de destination +StockStransferDecremented=Entrepôts sources décrémentés +StockStransferDecrementedCancel=Décrémentation entrepôts source annulée +StockStransferIncremented=Clôturé - Stocks transférés +StockStransferIncrementedShort=Stocks transférés +StockStransferIncrementedShortCancel=Incrémentation entrepôts de destination annulée +StockTransferNoBatchForProduct=Le produit %s ne gère pas les numéros de lot, retirez le lot sur la ligne avant d'exécuter à nouveau cette action +StockTransferSetup = Configuration du module transferts de stocks +Settings=Réglages +StockTransferSetupPage = Page de configuration du module transferts de stocks +StockTransferRightRead=Lire les transferts de stocks +StockTransferRightCreateUpdate=Créer/Mettre à jour les transferts de stocks +StockTransferRightDelete=Supprimer les transferts de stocks diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php new file mode 100644 index 00000000000..7faf8d7c530 --- /dev/null +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -0,0 +1,1107 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * 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/stocktransfer.class.php + * \ingroup stocktransfer + * \brief This file is a CRUD class file for StockTransfer (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 StockTransfer + */ +class StockTransfer extends CommonObject +{ + /** + * @var string ID to identify managed object. + */ + public $element = 'stocktransfer'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'stocktransfer_stocktransfer'; + + /** + * @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 stocktransfer. Must be the part after the 'object_' into object_stocktransfer.png + */ + public $picto = 'stock'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_TRANSFERED = 2; + const STATUS_CLOSED = 3; + + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', '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. + * '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' is the CSS style to use on field. For example: 'maxwidth200' + * '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, 'comment'=>"Id"), + 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>'1', 'position'=>1, 'default'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, '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'=>'minwidth200'/*, 'help'=>"Help text"*/, 'showoncombobox'=>'1',), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>3,), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>32, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1/*, 'help'=>"LinkToThirparty"*/,), + 'fk_warehouse_source' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt source', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferSource',), + 'fk_warehouse_destination' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt de destination', 'enabled'=>'1', 'position'=>51, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferDestination'), + '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,), + 'date_prevue_depart' => array('type'=>'date', 'label'=>'DatePrevueDepart', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>1,), + 'date_reelle_depart' => array('type'=>'date', 'label'=>'DateReelleDepart', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>5,), + 'date_prevue_arrivee' => array('type'=>'date', 'label'=>'DatePrevueArrivee', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>1,), + 'date_reelle_arrivee' => array('type'=>'date', 'label'=>'DateReelleArrivee', 'enabled'=>'1', 'position'=>103, 'notnull'=>0, 'visible'=>5,), + 'lead_time_for_warning' => array('type'=>'integer', 'label'=>'LeadTimeForWarning', 'enabled'=>'1', 'position'=>200, 'default'=>0, 'notnull'=>0, 'visible'=>1), + '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'=>'ChangedBy', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>5, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '2'=>'StockStransferDecremented', '3'=>'StockStransferIncremented'),), + ); + public $rowid; + public $ref; + public $label; + public $fk_soc; + public $fk_project; + 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 $model_pdf; + public $status; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var int Name of subtable line + */ + public $table_element_line = 'stocktransfer_stocktransferline'; + + /** + * @var int Field with ID of parent key if this object has a parent + */ + public $fk_element = 'fk_stocktransfer'; + + /** + * @var int Name of subtable class that manage subtable lines + */ + //public $class_element_line = 'StockTransferline'; + + /** + * @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('stocktransfer_stocktransferdet'); + + /** + * @var StockTransferLine[] Array of subtable lines + */ + //public $lines = array(); + + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $conf, $langs; + + $this->db = $db; + $this->origin_type = 'StockTransfer@stocktransfer'; + + 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->stocktransfer->stocktransfer->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 (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) + { + $this->status = (int)$this->status; + if($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0; + if($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0; + 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); + unset($object->date_prevue_depart); + unset($object->date_prevue_arrivee); + unset($object->date_reelle_depart); + unset($object->date_reelle_arrivee); + + + // Clear fields + $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default']; + $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + $object->status = self::STATUS_DRAFT; + // ... + // 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() + { + require_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransferline.class.php'; + $this->lines = array(); + + $result = $this->fetchLinesCommon(); + usort($this->lines, array('stocktransfer', 'cmp')); + return $result; + } + + function cmp($a, $b) + { + if ($a->rang == $b->rang) { + return 0; + } + return ($a->rang < $b->rang) ? -1 : 1; + } + + function getValorisationTotale() { + + $total_pmp = 0; + + if(empty($this->lines)) $this->fetchLines(); + if(!empty($this->lines)) { + foreach ($this->lines as $l) $total_pmp+= ($l->pmp * $l->qty); + } + + return $total_pmp; + + } + + /** + * 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 (strpos($key, 'date') !== false) { + $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; + } + elseif ($key == 'customsql') { + $sqlwhere[] = $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) + { + if(empty($this->lines)) $this->fetchLines(); + if(!empty($this->lines)) { + foreach ($this->lines as $l) $res = $this->deleteLine($user, $l->id); + } + 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) + { + global $db; + if ($this->status < 0) + { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + $res = $this->deleteLineCommon($user, $idline, $notrigger); + $this->line_order(true); + return $res; + } + + + /** + * 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->stocktransfer->stocktransfer->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransfer->stocktransfer_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('STOCKTRANSFER_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 = 'stocktransfer/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$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->stocktransfer->dir_output.'/stocktransfer/'.$oldref; + $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$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->stocktransfer->dir_output.'/stocktransfer/'.$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->stocktransfer->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransfer_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_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->stocktransfer->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransfer_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_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_CLOSED) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransfer_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_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 = ''.$langs->trans("StockTransfer").''; + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_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("ShowStockTransfer"); + $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('stocktransferdao')); + $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 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("stocktransfer@stocktransfer"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); + $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented'); + $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated'); + $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented'); + $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + if ($status == self::STATUS_CLOSED) $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 StockTransferLine($this->db); + $result = $objectline->fetchAll('ASC', 'rang', 0, 0, array('customsql'=>'fk_stocktransfer = '.$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("stocks"); + + if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) { + $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard'; + } + + if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) + { + $mybool = false; + + $file = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON.".php"; + $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/stocktransfer/"); + + // 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 = 1; + + $langs->load("stocks"); + + if (!dol_strlen($modele)) { + $modele = 'eagle'; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (!empty($conf->global->STOCKTRANSFER_ADDON_PDF)) { + $modele = $conf->global->STOCKTRANSFER_ADDON_PDF; + } + } + + $modelpath = "core/modules/stocktransfer/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; + } +} + +/** + * Class StockTransferLine. You can also remove this and generate a CRUD class for lines objects. + */ +//class StockTransferLine +//{ +// // To complete with content of an object StockTransferLine +// // We should have a field rowid, fk_stocktransfer 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/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php new file mode 100644 index 00000000000..35d79dda95d --- /dev/null +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -0,0 +1,1125 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * 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/stocktransferline.class.php + * \ingroup stocktransfer + * \brief This file is a CRUD class file for StockTransferLine (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 StockTransferLine + */ +class StockTransferLine extends CommonObject +{ + /** + * @var string ID to identify managed object. + */ + public $element = 'stocktransferline'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'stocktransfer_stocktransferline'; + + /** + * @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 stocktransferline. Must be the part after the 'object_' into object_stocktransferline.png + */ + public $picto = 'stocktransferline@stocktransfer'; + + + 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', '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. + * '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' is the CSS style to use on field. For example: 'maxwidth200' + * '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, 'comment'=>"Id"), + 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'default'=>'null', 'isameasure'=>'1', 'help'=>"Help text for amount",), + 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>'1', 'position'=>45, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'css'=>'maxwidth75imp', 'help'=>"Help text for quantity",), + 'fk_warehouse_destination' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt de destination', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>1,), + 'fk_warehouse_source' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt source', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>1,), + 'fk_stocktransfer' => array('type'=>'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php', 'label'=>'StockTransfer', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>0,), + 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>1,), + 'batch' => array('type'=>'varchar(128)', 'label'=>'Batch', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>1,), + 'pmp' => array('type'=>'double'/*, 'help'=>'THMEstimatedHelp'*/, 'label'=>'PMP', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,), + 'rang' => array('type'=>'integer', 'label'=>'Qty', 'enabled'=>'1', 'position'=>45, 'notnull'=>0, 'visible'=>0, 'default'=>'0', 'isameasure'=>'1', 'css'=>'maxwidth75imp', 'help'=>"Help text for quantity",), + ); + public $rowid; + public $amount; + public $qty; + public $fk_warehouse_destination; + public $fk_warehouse_source; + public $fk_stocktransfer; + public $fk_product; + public $batch; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var int Name of subtable line + */ + //public $table_element_line = 'stocktransfer_stocktransferlineline'; + + /** + * @var int Field with ID of parent key if this object has a parent + */ + //public $fk_element = 'fk_stocktransferline'; + + /** + * @var int Name of subtable class that manage subtable lines + */ + //public $class_element_line = 'StockTransferLineline'; + + /** + * @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('stocktransfer_stocktransferlinedet'); + + /** + * @var StockTransferLineLine[] 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->stocktransfer->stocktransferline->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 (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 + $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default']; + $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + $object->status = self::STATUS_DRAFT; + // ... + // 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 (strpos($key, 'date') !== false) { + $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; + } + elseif ($key == 'customsql') { + $sqlwhere[] = $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); + } + + function doStockMovement($label, $fk_entrepot, $direction=1) { + + global $db, $conf, $user, $langs; + + require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php'; + + $p = new Product($db); + $p->fetch($this->fk_product); + + $op[0] = "+".trim($this->qty); + $op[1] = "-".trim($this->qty); + $movementstock = new MouvementStock($db); + $movementstock->origin = new StockTransfer($db); + $movementstock->origin->id = $this->fk_stocktransfer; + + if (empty($this->batch)) // no batch for line + { + /*$result = $p->correct_stock( + $user, + $fk_entrepot, + $this->qty, + $direction, // 1=décrémentation + $label, + empty($direction) ? $this->pmp : 0, + GETPOST('inventorycode', 'alphanohtml'), + 'stocktransfer', + $this->fk_stocktransfer + );*/ + + $result = $movementstock->_create($user, $p->id, $fk_entrepot, $op[$direction], $direction, empty($direction) ? $this->pmp : 0, $label); + + if ($result < 0) { + setEventMessages($p->errors, $p->errorss, 'errors'); + return 0; + } + } + else { + if ($p->hasbatch()) { + $arraybatchinfo = $p->loadBatchInfo($this->batch); + if (count($arraybatchinfo) > 0) { + $firstrecord = array_shift($arraybatchinfo); + $dlc = $firstrecord['eatby']; + $dluo = $firstrecord['sellby']; + //var_dump($batch); var_dump($arraybatchinfo); var_dump($firstrecord); var_dump($dlc); var_dump($dluo); exit; + } else { + $dlc = ''; + $dluo = ''; + } + + /*$result = $p->correct_stock_batch( + $user, + $fk_entrepot, + $this->qty, + $direction, + $label, + empty($direction) ? $this->pmp : 0, + $dlc, + $dluo, + $this->batch, + GETPOST("codemove") + );*/ + + $result = $movementstock->_create($user, $p->id, $fk_entrepot, $op[$direction], $direction, empty($direction) ? $this->pmp : 0, $label, '', '', $dlc, $dluo, $this->batch); + + if ($result < 0) { + setEventMessages($p->errors, $p->errorss, 'errors'); + return 0; + } + } else { + setEventMessages($langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl()), '', 'errors'); + return -1; + } + } + + return 1; + + } + + /** + * 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->stocktransfer->stocktransferline->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransferline->stocktransferline_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('STOCKTRANSFERLINE_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 = 'stocktransferline/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$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->stocktransfer->dir_output.'/stocktransferline/'.$oldref; + $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$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->stocktransfer->dir_output.'/stocktransferline/'.$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->stocktransfer->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransfer_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_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->stocktransfer->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransfer_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_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->stocktransfer->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->stocktransfer->stocktransfer_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_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 = ''.$langs->trans("StockTransferLine").''; + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + $url = dol_buildpath('/stocktransfer/stocktransferline_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("ShowStockTransferLine"); + $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('stocktransferlinedao')); + $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 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("stocktransfer@stocktransfer"); + $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 StockTransferLineLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.$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("stocks"); + + if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) { + $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard'; + } + + if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) + { + $mybool = false; + + $file = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON.".php"; + $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/stocktransfer/"); + + // 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("stocks"); + + if (!dol_strlen($modele)) { + $modele = 'standard_stocktransferline'; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (!empty($conf->global->STOCKTRANSFERLINE_ADDON_PDF)) { + $modele = $conf->global->STOCKTRANSFERLINE_ADDON_PDF; + } + } + + $modelpath = "core/modules/stocktransfer/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; + } +} + +/** + * Class StockTransferLineLine. You can also remove this and generate a CRUD class for lines objects. + */ +class StockTransferLineLine +{ + // To complete with content of an object StockTransferLineLine + // We should have a field rowid, fk_stocktransferline 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/product/stock/stocktransfer/lib/stocktransfer.lib.php b/htdocs/product/stock/stocktransfer/lib/stocktransfer.lib.php new file mode 100644 index 00000000000..8460a6405bc --- /dev/null +++ b/htdocs/product/stock/stocktransfer/lib/stocktransfer.lib.php @@ -0,0 +1,67 @@ + + * + * 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 stocktransfer/lib/stocktransfer.lib.php + * \ingroup stocktransfer + * \brief Library files with common functions for StockTransfer + */ + +/** + * Prepare admin pages header + * + * @return array + */ +function stocktransferAdminPrepareHead() +{ + global $langs, $conf; + + $langs->load("stocks"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/admin/stocktransfer.php", 1); + $head[$h][1] = $langs->trans("Settings"); + $head[$h][2] = 'settings'; + $h++; + + /* + $head[$h][0] = dol_buildpath("/stocktransfer/admin/myobject_extrafields.php", 1); + $head[$h][1] = $langs->trans("ExtraFields"); + $head[$h][2] = 'myobject_extrafields'; + $h++; + */ + + /*$head[$h][0] = dol_buildpath("/product/stock/stocktransfer/admin/about.php", 1); + $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:@stocktransfer:/stocktransfer/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@stocktransfer:/stocktransfer/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, null, $head, $h, 'stocktransfer'); + + return $head; +} diff --git a/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php b/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php new file mode 100644 index 00000000000..03999b712e6 --- /dev/null +++ b/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php @@ -0,0 +1,96 @@ + + * + * 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 lib/stocktransfer_stocktransfer.lib.php + * \ingroup stocktransfer + * \brief Library files with common functions for StockTransfer + */ + +/** + * Prepare array of tabs for StockTransfer + * + * @param StockTransfer $object StockTransfer + * @return array Array of tabs + */ +function stocktransferPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("stocks"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/product/stock/stocktransfer/stocktransfer_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $h++; + + if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) + { + $nbContact = count($object->liste_contact(-1, 'internal')) + count($object->liste_contact(-1, 'external')); + $head[$h][0] = dol_buildpath('/product/stock/stocktransfer/stocktransfer_contact.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('ContactsAddresses'); + if ($nbContact > 0) $head[$h][1] .= ''.$nbContact.''; + $head[$h][2] = 'contact'; + $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('/product/stock/stocktransfer/stocktransfer_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->stocktransfer->dir_output."/stocktransfer/".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("/product/stock/stocktransfer/stocktransfer_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("/product/stock/stocktransfer/stocktransfer_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:@stocktransfer:/stocktransfer/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@stocktransfer:/stocktransfer/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'stocktransfer@stocktransfer'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'stocktransfer@stocktransfer', 'remove'); + + return $head; +} diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php new file mode 100644 index 00000000000..cc580d2ab4a --- /dev/null +++ b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php @@ -0,0 +1,260 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * 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 stocktransfer_agenda.php + * \ingroup stocktransfer + * \brief Page of StockTransfer events + */ + +// 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'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php'; + + +// Load translation files required by the page +$langs->loadLangs(array("stocks", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'alpha'); +$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 StockTransfer($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->stocktransfer->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('stocktransferagenda', '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->stocktransfer->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, 'stocktransfer', $object->id); + +$permissiontoadd = $user->rights->stocktransfer->stocktransfer->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 = stocktransferPrepareHead($object); + + + dol_fiche_head($head, 'agenda', $langs->trans("StockTransfer"), -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 '
'; + + $object->info($object->id); + dol_print_object_info($object, 1); + + print '
'; + + dol_fiche_end(); + + + + // Actions buttons + + $objthirdparty = $object; + $objcon = new stdClass(); + + $out = '&origin='.$object->element.'&originid='.$object->id; + $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("ActionsOnStockTransfer"), '', ''); + + // 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, ''); + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php new file mode 100644 index 00000000000..abc653d5e75 --- /dev/null +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -0,0 +1,1064 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * 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 stocktransfer_card.php + * \ingroup stocktransfer + * \brief Page to create/edit/view stocktransfer + */ + +//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 + + +// 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/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("stocks", "other", "productbatch", "companies")); + +// 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') : 'stocktransfercard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +$qty = GETPOST('qty', 'int'); +$fk_product = GETPOST('fk_product', 'int'); +$fk_warehouse_source = GETPOST('fk_warehouse_source', 'int'); +$fk_warehouse_destination = GETPOST('fk_warehouse_destination', 'int'); +$lineid = GETPOST('lineid', 'int'); +$label = GETPOST('label', 'alpha'); +$batch = GETPOST('batch', 'alpha'); + +// Initialize technical objects +$object = new StockTransfer($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->stocktransfer->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('stocktransfercard', '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 = trim(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->stocktransfer->stocktransfer->read; +$permissiontoadd = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); +$permissionnote = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_dellink.inc.php +$upload_dir = $conf->stocktransfer->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, 'stocktransfer', $object->id, '', '', 'fk_soc', 'rowid', $isdraft); + +//if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); + +$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('/product/stock/stocktransfer/stocktransfer_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('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + } + } + $triggermodname = 'STOCKTRANSFER_STOCKTRANSFER_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 == 'set_thirdparty' && $permissiontoadd) + { + $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'STOCKTRANSFER_MODIFY'); + } + if ($action == 'classin' && $permissiontoadd) + { + $object->setProject(GETPOST('projectid', 'int')); + } + + if($action == 'addline' && $permissiontoadd) { + + if($qty <= 0) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); + $action = 'view'; + } + + if($fk_warehouse_source <= 0) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); + $action = 'view'; + } + + if($fk_warehouse_destination <= 0) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); + $action = 'view'; + } + + $prod = new Product($db); + $prod->fetch($fk_product); + if ($prod->hasbatch()) + { + if (empty($batch)) + { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); + } + } else { + if(!empty($batch)) { + $error++; + setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); + } + } + + if(empty($error)) { + $line = new StockTransferLine($db); + $records = $line->fetchAll('', '', 0, 0, array('customsql'=>' fk_stocktransfer = '.$id.' AND fk_product = '.$fk_product.' AND fk_warehouse_source = '.$fk_warehouse_source.' AND fk_warehouse_destination = '.$fk_warehouse_destination.' AND ('.(empty($batch) ? 'batch = "" or batch IS NULL' : 'batch = "'.$batch.'"' ).')')); + if(!empty($records[key($records)])) $line = $records[key($records)]; + $line->fk_stocktransfer = $id; + $line->qty += $qty; + $line->fk_warehouse_source = $fk_warehouse_source; + $line->fk_warehouse_destination = $fk_warehouse_destination; + $line->fk_product = $fk_product; + $line->batch = $batch; + + $line->pmp = $prod->pmp; + if($line->id > 0) $line->update($user); + else { + $line->rang = count($object->lines) + 1; + $line->create($user); + } + $object->fetchLines(); + } + } elseif($action === 'updateline' && $permissiontoadd) { + + if($qty <= 0) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); + $action = 'editline'; + } + + if($fk_warehouse_source <= 0) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); + $action = 'editline'; + } + + if($fk_warehouse_destination <= 0) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); + $action = 'editline'; + } + + $prod = new Product($db); + $prod->fetch($fk_product); + if ($prod->hasbatch()) + { + if (empty($batch)) + { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); + $action = 'editline'; + } + } else { + if(!empty($batch)) { + $error++; + setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); + $action = 'editline'; + } + } + + if(empty($error)) { + $line = new StockTransferLine($db); + $line->fetch($lineid); + $line->qty = $qty; + $line->fk_warehouse_source = $fk_warehouse_source; + $line->fk_warehouse_destination = $fk_warehouse_destination; + $line->fk_product = $fk_product; + $line->batch = $batch; + $line->pmp = $prod->pmp; + $line->update($user); + } + } + + // Décrémentation + if($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { + $lines = $object->getLinesArray(); + if(!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $line->fk_warehouse_source); + if($res <= 0) $error++; + } + if(empty($error)) $db->commit(); + else $db->rollback(); + } + if(empty($error)) { + $object->setStatut($object::STATUS_TRANSFERED, $id); + $object->status = $object::STATUS_TRANSFERED; + $object->date_reelle_depart = date('Y-m-d'); + $object->update($user); + setEventMessage('StockStransferDecremented'); + } + } + + // Annulation décrémentation + if($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + $lines = $object->getLinesArray(); + if(!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $line->fk_warehouse_source, 0); + if($res <= 0) $error++; + } + if(empty($error)) $db->commit(); + else $db->rollback(); + } + if(empty($error)) { + $object->setStatut($object::STATUS_VALIDATED, $id); + $object->status = $object::STATUS_VALIDATED; + $object->date_reelle_depart = null; + $object->update($user); + setEventMessage('StockStransferDecrementedCancel', 'warnings'); + } + } + + // Incrémentation + if($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + $lines = $object->getLinesArray(); + if(!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $line->fk_warehouse_destination, 0); + if($res <= 0) $error++; + } + if(empty($error)) $db->commit(); + else $db->rollback(); + } + if(empty($error)) { + $object->setStatut($object::STATUS_CLOSED, $id); + $object->status = $object::STATUS_CLOSED; + $object->date_reelle_arrivee = date('Y-m-d'); + $object->update($user); + setEventMessage('StockStransferIncrementedShort'); + } + } + + // Annulation incrémentation + if($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { + $lines = $object->getLinesArray(); + if(!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $line->fk_warehouse_destination); + if($res <= 0) $error++; + } + if(empty($error)) $db->commit(); + else $db->rollback(); + } + if(empty($error)) { + $object->setStatut($object::STATUS_TRANSFERED, $id); + $object->status = $object::STATUS_TRANSFERED; + $object->date_reelle_arrivee = null; + $object->update($user); + setEventMessage('StockStransferIncrementedShortCancel', 'warnings'); + } + } + + // Actions to send emails + $triggersendname = 'STOCKTRANSFER_SENTBYMAIL'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_STOCKTRANSFER_TO'; + $trackid = 'stocktransfer'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; +} + + + + +/* + * View + * + * Put here all code to build page + */ + +$title = $langs->trans("StockTransfer"); +$help_url = ''; +llxHeader('', $title, $help_url); + + + +// Example : Adding jquery code +print ''; + + +// Part to create +if ($action == 'create') +{ + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("StockTransfer")), '', 'object_'.$object->picto); + + print '
'; + print ''; + print ''; + if ($backtopage) print ''; + if ($backtopageforcancel) print ''; + + dol_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'; + + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; + + print '
'."\n"; + + dol_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') +{ + //if($object->status < 3) { + print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto); + + print '
'; + print ''; + print ''; + print ''; + if ($backtopage) print ''; + if ($backtopageforcancel) print ''; + + dol_fiche_head(); + + print '' . "\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php'; + + print '
'; + + dol_fiche_end(); + + print '
'; + print '   '; + print '
'; + + print '
'; + //} else $action = 'view'; +} + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) +{ + $res = $object->fetch_optionals(); + + $head = stocktransferPrepareHead($object); + dol_fiche_head($head, 'card', $langs->trans("StockTransfer"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') + { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteStockTransfer'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } + // Confirmation to delete line + if ($action == 'deleteline') + { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 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); + } + // Destock confirmation + elseif ($action == 'destock') { + // Create an array for form + $formquestion = array( 'text' => '', + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40)); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1); + } + // Destock confirmation cancel + elseif ($action == 'destockcancel') { + // Create an array for form + $formquestion = array( 'text' => '', + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40)); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1); + } + // Addstock confirmation + elseif ($action == 'addstock') { + // Create an array for form + $formquestion = array( 'text' => '', + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40)); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1); + } + // Addstock confirmation cancel + elseif ($action == 'addstockcancel') { + // Create an array for form + $formquestion = array( 'text' => '', + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40)); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProductCancel'), '', 'confirm_addstockcancel', $formquestion, 'yes', 1); + } + + // Confirmation of action xxxx + if ($action == 'xxx') + { + $formquestion = array(); + /* + $forcecombo=0; + if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy + $formquestion = array( + // 'text' => $langs->trans("ConfirmClone"), + // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + // array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo)) + ); + */ + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220); + } + + + if ($action == 'valid' && $permissiontoadd) { + $nextref=$object->getNextNumRef(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->transnoentities('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2); + } + + // 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 + + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + echo ''; + echo ''; + echo ''; + // Other attributes. Fields from hook formObjectOptions and Extrafields. + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + + print '
'.$langs->trans('EnhancedValue').' '.strtolower($langs->trans('TotalWoman')); + echo ''.price($object->getValorisationTotale(), 0, '', 1, -1, -1, $conf->currency).'
'; + print '
'; + print '
'; + + print '
'; + + dol_fiche_end(); + + + /* + * Lines + */ + + if (!empty($object->table_element_line)) + { + // Show object lines + /*$result = $object->getLinesArray(); + + print '
+ + + + + ';*/ + + if (!empty($conf->use_javascript_ajax) && $object->status == 0) { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + /*print '
'; + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) + { + print ''; + } + + if (!empty($object->lines)) + { + $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1); + } + + // Form to add new line + if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') + { + if ($action != 'editline') + { + // Add products/services form + $object->formAddObjectLine(1, $mysoc, $soc); + + $parameters = array(); + $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + } + } + + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) + { + print '
'; + } + print '
'; + + print "
\n";*/ + } + + + $formproduct = new FormProduct($db); + print '
'; + print '
+ + + + + '; + if($lineid > 0) print ''; + print ''; +//print '
'; + + $param = ''; + + print '
'; + print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); + if ($conf->productbatch->enabled) { + print getTitleFieldOfList($langs->trans('Batch'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); + } + print getTitleFieldOfList($langs->trans('WarehouseSource'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); + print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); + print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); + print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); + print getTitleFieldOfList($langs->trans('PMPValue'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); + if(empty($object->status)) { + print getTitleFieldOfList('', 0); + print getTitleFieldOfList('', 0); + print getTitleFieldOfList('', 0); + } + + print ''; + + $listofdata = $object->getLinesArray(); + $productstatic = new Product($db); + $warehousestatics = new Entrepot($db); + $warehousestatict = new Entrepot($db); + + foreach ($listofdata as $key => $line) + { + $productstatic->fetch($line->fk_product); + $warehousestatics->fetch($line->fk_warehouse_source); + $warehousestatict->fetch($line->fk_warehouse_destination); + + // add html5 elements + $domData = ' data-element="'.$line->element.'"'; + $domData .= ' data-id="'.$line->id.'"'; + $domData .= ' data-qty="'.$line->qty.'"'; + //$domData .= ' data-product_type="'.$line->product_type.'"'; + + print ''; + print ''; + if ($conf->productbatch->enabled) + { + print ''; + } + print ''; + print ''; + if($action === 'editline' && $line->id == $lineid) print ''; + else print ''; + print ''; + print ''; + if(empty($object->status)) { + + if($action === 'editline' && $line->id == $lineid) { + //print ''; + print ''; + } else { + print ''; + print ''; + } + + $num = count($object->lines); + + if ($num > 1 && $conf->browser->layout != 'phone' && empty($disablemove)) { + print ''; + $coldisplay++; + } + } + + print ''; + } + + if(empty($object->status) && $action !== 'editline') { + print ''; +// Product + print ''; + // Batch number + if ($conf->productbatch->enabled) { + print ''; + } + + $formproduct->loadWarehouses(); // Pour charger la totalité des entrepôts + + // On stock ceux qui ne doivent pas être proposés dans la liste + $TExcludedWarehouseSource=array(); + if(!empty($object->fk_warehouse_source)) { + $source_ent = new Entrepot($db); + $source_ent->fetch($object->fk_warehouse_source); + foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { + if(strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id']; + } + } + + // On stock ceux qui ne doivent pas être proposés dans la liste + $TExcludedWarehouseDestination=array(); + if(!empty($object->fk_warehouse_destination)) { + $dest_ent = new Entrepot($db); + $dest_ent->fetch($object->fk_warehouse_destination); + foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { + if(strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id']; + } + } + + // On vide le tableau pour qu'il se charge tout seul lors de l'appel à la fonction select_warehouses + $formproduct->cache_warehouses=array(); + // In warehouse + print ''; + + // On vide le tableau pour qu'il se charge tout seul lors de l'appel à la fonction select_warehouses + $formproduct->cache_warehouses=array(); + // Out warehouse + print ''; + + // Qty + print ''; + // PMP + print ''; + // PMP * Qty + print ''; + // Button to add line + print ''; + // Grad and drop lines + print ''; + print ''; + + } + + print '
'; + if($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); + else print $productstatic->getNomUrl(1).' - '.$productstatic->label; + print ''; + if($action === 'editline' && $line->id == $lineid) print ''; + else print $line->batch; + print ''; + if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); + else print $warehousestatics->getNomUrl(1); + print ''; + if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination,'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); + else print $warehousestatict->getNomUrl(1); + print ''.$line->qty.''; + print price($line->pmp, 0, '', 1, -1, -1, $conf->currency); + print ''; + print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency); + print '
'; + print '
'; + print 'id . '#line_' . $line->id . '">'; + print img_edit() . ''; + print ''; + print 'id . '">' . img_delete($langs->trans("Remove")) . ''; + print ''; + $coldisplay++; + if ($i > 0) { ?> + id; ?>"> + + + + id; ?>"> + + + '; + } else { + print 'browser->layout != 'phone' && empty($disablemove)) ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'>
'; + $filtertype = 0; + if (!empty($conf->global->STOCK_SUPPORTS_SERVICES)) $filtertype = ''; + if ($conf->global->PRODUIT_LIMIT_SIZE <= 0) { + $limit = ''; + } else { + $limit = $conf->global->PRODUIT_LIMIT_SIZE; + } + + $form->select_produits($fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); + print ''; + print ''; + print ''; + print $formproduct->selectWarehouses(empty($fk_warehouse_source) ? $object->fk_warehouse_source : $fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); + print ''; + print $formproduct->selectWarehouses(empty($fk_warehouse_destination) ? $object->fk_warehouse_destination : $fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); + print '
'; + print '
'; + print '
'; + + // 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)) + { + // Send + if (empty($user->socid)) { + print ''.$langs->trans('SendMail').''."\n"; + } + + // Back to draft + if ($object->status == $object::STATUS_VALIDATED) + { + if ($permissiontoadd) + { + print ''.$langs->trans("SetToDraft").''; + } + } + + // Modify + if ($permissiontoadd) + { + print ''.$langs->trans("Modify").''."\n"; + } + /*else + { + print ''.$langs->trans('Modify').''."\n"; + }*/ + + // Validate + if ($object->status == $object::STATUS_DRAFT) + { + if ($permissiontoadd) + { + if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) + { + print ''.$langs->trans("Validate").''; + } + else + { + $langs->load("errors"); + print ''.$langs->trans("Validate").''; + } + } + } + + elseif($object->status == $object::STATUS_VALIDATED) { + print ''.$langs->trans("StockTransferDecrementation").''; + } + + elseif($object->status == $object::STATUS_TRANSFERED) { + print ''.$langs->trans("StockTransferDecrementationCancel").''; + print ''.$langs->trans("StockTransferIncrementation").''; + } + + elseif($object->status == $object::STATUS_CLOSED) { + print ''.$langs->trans("StockTransferIncrementationCancel").''; + } + + // 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"; + } + } + if ($permissiontoadd) + { + if ($object->status == $object::STATUS_VALIDATED) + { + print ''.$langs->trans("Cancel").''."\n"; + } + else + { + print ''.$langs->trans("Re-Open").''."\n"; + } + } + */ + + // Delete (need delete permission, or if draft, just need create/modify permission) + if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) + { + print ''.$langs->trans('Delete').''."\n"; + } + /*else + { + print ''.$langs->trans('Delete').''."\n"; + }*/ + } + print '
'."\n"; + } + + + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + if ($action != 'presend') + { + print '
'; + print ''; // ancre + + $includedocgeneration = 1; + + // Documents + if ($includedocgeneration) { + $objref = dol_sanitizeFileName($object->ref); + $relativepath = $objref . '/' . $objref . '.pdf'; + $filedir = $conf->stocktransfer->dir_output.'/'.$object->element.'/'.$objref; + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->stocktransfer->stocktransfer->read; // If you can read, you can build the PDF to read content + $delallowed = $user->rights->stocktransfer->stocktransfer->write; // If you can create/edit, you can remove a file on card + print $formfile->showdocuments('stocktransfer:StockTransfer', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); + } + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, array('stocktransfer')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + + print '
'; + + $MAXEVENT = 10; + + $morehtmlright = ''; + $morehtmlright .= $langs->trans("SeeAll"); + $morehtmlright .= ''; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'stocktransfer', 0, 1, '', $MAXEVENT, '', $morehtmlright); + + print '
'; + } + + //Select mail models is same action as presend + if (GETPOST('modelselected')) $action = 'presend'; + + // Presend form + $modelmail = 'stocktransfer'; + $defaulttopic = 'InformationMessage'; + $diroutput = $conf->stocktransfer->dir_output; + $trackid = 'stocktransfer'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php new file mode 100644 index 00000000000..6dc808f206d --- /dev/null +++ b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php @@ -0,0 +1,225 @@ + + * Copyright (C) 2005-2016 Destailleur Laurent + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2011-2015 Philippe Grand + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/comm/propal/contact.php + * \ingroup propal + * \brief Tab to manage contacts/adresses of proposal + */ + +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.'/product/stock/stocktransfer/class/stocktransfer.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array('facture', 'orders', 'sendings', 'companies', 'stocks')); + +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$lineid = GETPOST('lineid', 'int'); +$action = GETPOST('action', 'alpha'); + +// Security check +if ($user->socid) $socid = $user->socid; + +$result = restrictedArea($user, 'stocktransfer', $id, '', 'stocktransfer'); + +$object = new StockTransfer($db); + +// Load object +if ($id > 0 || !empty($ref)) +{ + $ret = $object->fetch($id, $ref); + if ($ret == 0) + { + $langs->load("errors"); + setEventMessages($langs->trans('ErrorRecordNotFound'), null, 'errors'); + $error++; + } + elseif ($ret < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } +} +if (!$error) +{ + $object->fetch_thirdparty(); +} +else +{ + header('Location: '.dol_buildpath('/stocktransfer/stocktransfer_list.php', 1)); + exit; +} + + +/* + * Add a new contact + */ + +if ($action == 'addcontact' && $user->rights->stocktransfer->stocktransfer->write) +{ + if ($object->id > 0) + { + $contactid = (GETPOST('userid', 'int') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); + $result = $object->add_contact($contactid, !empty($_POST["typecontact"]) ? $_POST["typecontact"] : $_POST["type"], $_POST["source"]); + } + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors'); + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } +} + +// Toggle the status of a contact +elseif ($action == 'swapstatut' && $user->rights->stocktransfer->stocktransfer->write) +{ + if ($object->id > 0) + { + $result = $object->swapContactStatus(GETPOST('ligne')); + } +} + +// Deletes a contact +elseif ($action == 'deletecontact' && $user->rights->stocktransfer->stocktransfer->write) +{ + $result = $object->delete_contact($lineid); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + dol_print_error($db); + } +} +/* +elseif ($action == 'setaddress' && $user->rights->stocktransfer->stocktransfer->write) +{ + $result=$object->setDeliveryAddress($_POST['fk_address']); + if ($result < 0) dol_print_error($db,$object->error); +}*/ + + +/* + * View + */ + +llxHeader('', $langs->trans('ModuleStockTransferName'), 'EN:Commercial_Proposals|FR:Proposition_commerciale|ES:Presupuestos'); + +$form = new Form($db); +$formcompany = new FormCompany($db); +$formother = new FormOther($db); + +if ($object->id > 0) +{ + $head = stocktransferPrepareHead($object); + dol_fiche_head($head, 'contact', $langs->trans("StockTransfer"), -1, 'stock'); + + + // Proposal 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 + if(!empty($object->thirdparty)) { + $morehtmlref .= '
' . $langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'customer'); + } + // Project + if (!empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref .= '
'.$langs->trans('Project').' '; + if ($user->rights->stocktransfer->stocktransfer->write) + { + 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 .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } + $morehtmlref .= '
'; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); + + dol_fiche_end(); + + $user->rights->stocktransfer->write = $user->rights->stocktransfer->stocktransfer->write; + // Contacts lines (modules that overwrite templates must declare this into descriptor) + $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl')); + foreach ($dirtpls as $reldir) + { + $res = @include dol_buildpath($reldir.'/contacts.tpl.php'); + if ($res) break; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_document.php b/htdocs/product/stock/stocktransfer/stocktransfer_document.php new file mode 100644 index 00000000000..bbde110ef0e --- /dev/null +++ b/htdocs/product/stock/stocktransfer/stocktransfer_document.php @@ -0,0 +1,211 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * 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 stocktransfer_document.php + * \ingroup stocktransfer + * \brief Tab for documents linked to StockTransfer + */ + +// 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'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("stocks", "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 StockTransfer($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->stocktransfer->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('stocktransferdocument', '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->stocktransfer->multidir_output[$object->entity?$object->entity:$conf->entity] . "/stocktransfer/" . dol_sanitizeFileName($object->id); +if ($id > 0 || !empty($ref)) $upload_dir = $conf->stocktransfer->multidir_output[$object->entity ? $object->entity : $conf->entity]."/stocktransfer/".dol_sanitizeFileName($object->ref); + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$result = restrictedArea($user, 'stocktransfer', $object->id); + +$permissiontoadd = $user->rights->stocktransfer->stocktransfer->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("ModuleStockTransferName").' - '.$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 = stocktransferPrepareHead($object); + + dol_fiche_head($head, 'document', $langs->trans("StockTransfer"), -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 '
'; + + dol_fiche_end(); + + $modulepart = 'stocktransfer'; + //$permission = $user->rights->stocktransfer->stocktransfer->write; + $permission = 1; + //$permtoedit = $user->rights->stocktransfer->stocktransfer->write; + $permtoedit = 1; + $param = '&id='.$object->id; + + //$relativepathwithnofile='stocktransfer/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = 'stocktransfer/'.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/product/stock/stocktransfer/stocktransfer_list.php b/htdocs/product/stock/stocktransfer/stocktransfer_list.php new file mode 100644 index 00000000000..10532fe889c --- /dev/null +++ b/htdocs/product/stock/stocktransfer/stocktransfer_list.php @@ -0,0 +1,606 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * 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 stocktransfer_list.php + * \ingroup stocktransfer + * \brief List page for stocktransfer + */ + +//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('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//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) +//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("XFRAMEOPTIONS_ALLOWALL")) define('XFRAMEOPTIONS_ALLOWALL', '1'); // Do not add the HTTP header 'X-Frame-Options: SAMEORIGIN' but 'X-Frame-Options: ALLOWALL' + +// 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 stocktransfer libraries +require_once __DIR__.'/class/stocktransfer.class.php'; + +// for other modules +//dol_include_once('/othermodule/class/otherobject.class.php'); + +// Load translation files required by the page +$langs->loadLangs(array("stocks", "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') : 'stocktransferlist'; // 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', 'alpha'); +$sortorder = GETPOST('sortorder', 'alpha'); +$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 StockTransfer($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->stocktransfer->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('stocktransferlist')); // 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') ? trim(GETPOST('search_all', 'alphanohtml')) : trim(GETPOST('sall', 'alphanohtml')); +$search = array(); +foreach ($object->fields as $key => $val) +{ + if (GETPOST('search_'.$key, 'alpha') !== '') $search[$key] = GETPOST('search_'.$key, 'alpha'); +} + +// 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 fields for list +$arrayfields = array(); +foreach ($object->fields as $key => $val) +{ + // If $val['visible']==0, then we never show the field + if (!empty($val['visible'])) $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']); +} +// Extra fields +if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) +{ + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) + { + if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) { + $arrayfields["ef.".$key] = array( + 'label'=>$extrafields->attributes[$object->table_element]['label'][$key], + 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), + 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], + 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]), + 'langfile'=>$extrafields->attributes[$object->table_element]['langfile'][$key] + ); + } + } +} +$object->fields = dol_sort_array($object->fields, 'position'); +$arrayfields = dol_sort_array($arrayfields, 'position'); + +$permissiontoread = $user->rights->stocktransfer->stocktransfer->read; +$permissiontoadd = $user->rights->stocktransfer->stocktransfer->write; +$permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete; + +// Security check +if (empty($conf->stocktransfer->enabled)) accessforbidden('Module not enabled'); +$socid = 0; +if ($user->socid > 0) // Protection if external user +{ + //$socid = $user->socid; + accessforbidden(); +} +//$result = restrictedArea($user, 'stocktransfer', $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 = 'StockTransfer'; + $objectlabel = 'StockTransfer'; + $uploaddir = $conf->stocktransfer->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +//$help_url="EN:Module_StockTransfer|FR:Module_StockTransfer_FR|ES:Módulo_StockTransfer"; +$help_url = ''; +$title = $langs->trans('StockTransferList'); + + +// 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)"; +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); // 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('/product/stock/stocktransfer/stocktransfer_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'; + +// 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 ''; +print ''; + +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/product/stock/stocktransfer/stocktransfer_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 = "SendStockTransferRef"; +$modelmail = "stocktransfer"; +$objecttmp = new StockTransfer($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['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 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')) && $key != '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, ''); + if($key === 'date_prevue_depart' && $object->lead_time_for_warning > 0 && $object->$key > 0) { + $date_prevue_depart = $object->$key; + $date_prevue_depart_plus_delai = $date_prevue_depart; + if($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); + if($date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) print img_warning($langs->trans('Alert').' - '.$langs->trans('Late')); + } + } + 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 (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth75'); + elseif (strpos($val['type'], 'integer:') === 0) { + print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth150', 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_stocktransfer', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_note.php b/htdocs/product/stock/stocktransfer/stocktransfer_note.php new file mode 100644 index 00000000000..085914936b7 --- /dev/null +++ b/htdocs/product/stock/stocktransfer/stocktransfer_note.php @@ -0,0 +1,163 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * 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 stocktransfer_note.php + * \ingroup stocktransfer + * \brief Car with notes on StockTransfer + */ + +// 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.'/product/stock/stocktransfer/class/stocktransfer.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("stocks", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new StockTransfer($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->stocktransfer->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('stocktransfernote', '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, 'stocktransfer', $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->stocktransfer->multidir_output[$object->entity]."/".$object->id; + +$permissionnote = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_setnotes.inc.php +$permissiontoadd = $user->rights->stocktransfer->stocktransfer->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('ModuleStockTransferName'), $help_url); + +if ($id > 0 || !empty($ref)) +{ + $object->fetch_thirdparty(); + + $head = stocktransferPrepareHead($object); + + dol_fiche_head($head, 'note', $langs->trans("StockTransfer"), -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 '
'; + + dol_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); From 3f42689633bb8395d1b6ec4fa8c8612644dbdd5d Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 29 Jul 2021 16:17:12 +0200 Subject: [PATCH 002/128] FIX : name --- htdocs/admin/stocktransfer.php | 1 + htdocs/core/modules/modStockTransfer.class.php | 1 + htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 1 + htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php | 1 + htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php | 1 + htdocs/core/modules/stocktransfer/modules_stocktransfer.php | 1 + 6 files changed, 6 insertions(+) diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index 10d29453a49..0056579887d 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -1,5 +1,6 @@ + * Copyright (C) 2021 Gauthier VERDOL * Copyright (C) 2021 SuperAdmin * * This program is free software: you can redistribute it and/or modify diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index cc5479410e3..e60ea3c330d 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2018-2019 Nicolas ZABOURI * Copyright (C) 2019-2020 Frédéric France * Copyright (C) 2021 SuperAdmin + * 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 diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index c2d595a026e..9f9edaadb7a 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2018 Frédéric France + * 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 diff --git a/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php b/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php index 60207efb650..a349f4f536e 100644 --- a/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php +++ b/htdocs/core/modules/stocktransfer/mod_stocktransfer_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) 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 diff --git a/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php b/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php index d4a06024136..77236ec0e40 100644 --- a/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php +++ b/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php @@ -1,6 +1,7 @@ * Copyright (C) 2005-2009 Regis Houssin + * 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 diff --git a/htdocs/core/modules/stocktransfer/modules_stocktransfer.php b/htdocs/core/modules/stocktransfer/modules_stocktransfer.php index 0394f8ac1f0..3da0a0ae644 100644 --- a/htdocs/core/modules/stocktransfer/modules_stocktransfer.php +++ b/htdocs/core/modules/stocktransfer/modules_stocktransfer.php @@ -6,6 +6,7 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2014 Marcos García + * 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 980528173393458f6db8d6f3d9ba68580f55d758 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 29 Jul 2021 14:20:50 +0000 Subject: [PATCH 003/128] Fixing style errors. --- htdocs/admin/stocktransfer.php | 111 +++---- htdocs/core/menus/standard/eldy.lib.php | 2 +- .../core/modules/modStockTransfer.class.php | 58 ++-- .../stocktransfer/doc/pdf_eagle.modules.php | 270 ++++++------------ .../mod_stocktransfer_advanced.php | 6 +- .../mod_stocktransfer_standard.php | 19 +- .../class/stocktransfer.class.php | 189 +++++------- .../class/stocktransferline.class.php | 181 ++++-------- .../lib/stocktransfer_stocktransfer.lib.php | 6 +- .../stocktransfer/stocktransfer_agenda.php | 35 +-- .../stocktransfer/stocktransfer_card.php | 205 ++++++------- .../stocktransfer/stocktransfer_contact.php | 133 ++++----- .../stocktransfer/stocktransfer_document.php | 10 +- .../stocktransfer/stocktransfer_list.php | 112 +++----- .../stocktransfer/stocktransfer_note.php | 3 +- 15 files changed, 478 insertions(+), 862 deletions(-) diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index 0056579887d..2f5892dd1c0 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -70,13 +70,11 @@ $setupnotempty = 0; * Actions */ -if ((float) DOL_VERSION >= 6) -{ +if ((float) DOL_VERSION >= 6) { include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; } -if ($action == 'updateMask') -{ +if ($action == 'updateMask') { $maskconststocktransfer = GETPOST('maskconststocktransfer', 'alpha'); $maskstocktransfer = GETPOST('maskStockTransfer', 'alpha'); @@ -84,14 +82,12 @@ if ($action == 'updateMask') if (!$res > 0) $error++; - if (!$error) - { + if (!$error) { setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } else { setEventMessages($langs->trans("Error"), null, 'errors'); } -} elseif ($action == 'specimen') -{ +} elseif ($action == 'specimen') { $modele = GETPOST('module', 'alpha'); $tmpobjectkey = GETPOST('object'); @@ -101,25 +97,21 @@ if ($action == 'updateMask') // Search template files $file = ''; $classname = ''; $filefound = 0; $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) - { + foreach ($dirmodels as $reldir) { $file = dol_buildpath($reldir."core/modules/stocktransfer/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0); - if (file_exists($file)) - { + if (file_exists($file)) { $filefound = 1; $classname = "pdf_".$modele; break; } } - if ($filefound) - { + if ($filefound) { require_once $file; $module = new $classname($db); - if ($module->write_file($tmpobject, $langs) > 0) - { + if ($module->write_file($tmpobject, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); return; } else { @@ -133,28 +125,23 @@ if ($action == 'updateMask') } // Activate a model -elseif ($action == 'set') -{ +elseif ($action == 'set') { $ret = addDocumentModel($value, 'stocktransfer', $label, $scandir); -} elseif ($action == 'del') -{ +} elseif ($action == 'del') { $tmpobjectkey = GETPOST('object'); $ret = delDocumentModel($value, $type); - if ($ret > 0) - { + 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') -{ +elseif ($action == 'setdoc') { $tmpobjectkey = GETPOST('object'); $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; - if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) - { + 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; @@ -162,12 +149,10 @@ elseif ($action == 'setdoc') // On active le modele $ret = delDocumentModel($value, $type); - if ($ret > 0) - { + if ($ret > 0) { $ret = addDocumentModel($value, $type, $label, $scandir); } -} elseif ($action == 'setmod') -{ +} elseif ($action == 'setmod') { // TODO Check if numbering module chosen can be activated // by calling method canBeActivated $tmpobjectkey = GETPOST('object'); @@ -279,19 +264,14 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { clearstatcache(); - foreach ($dirmodels as $reldir) - { + foreach ($dirmodels as $reldir) { $dir = dol_buildpath($reldir."core/modules/".$moduledir); - if (is_dir($dir)) - { + 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') - { + 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'; @@ -302,8 +282,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { 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()) - { + if ($module->isEnabled()) { dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php'); print ''.$module->name."\n"; @@ -320,8 +299,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) - { + if ($conf->global->$constforvar == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -380,12 +358,10 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $sql .= " WHERE type = '".$type."'"; $sql .= " AND entity = ".$conf->entity; $resql = $db->query($sql); - if ($resql) - { + if ($resql) { $i = 0; $num_rows = $db->num_rows($resql); - while ($i < $num_rows) - { + while ($i < $num_rows) { $array = $db->fetch_array($resql); array_push($def, $array[0]); $i++; @@ -406,31 +382,23 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { clearstatcache(); - foreach ($dirmodels as $reldir) - { - foreach (array('', '/doc') as $valdir) - { + foreach ($dirmodels as $reldir) { + foreach (array('', '/doc') as $valdir) { $realpath = $reldir."core/modules/".$moduledir.$valdir; $dir = dol_buildpath($realpath); - if (is_dir($dir)) - { + if (is_dir($dir)) { $handle = opendir($dir); - if (is_resource($handle)) - { - while (($file = readdir($handle)) !== false) - { + 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)) - { + 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); @@ -441,8 +409,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { 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) - { + if ($modulequalified) { print ''; print (empty($module->name) ? $name : $module->name); print "\n"; @@ -451,8 +418,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; // Active - if (in_array($name, $def)) - { + if (in_array($name, $def)) { print ''."\n"; print ''; print img_picto($langs->trans("Enabled"), 'switch_on'); @@ -467,8 +433,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) - { + 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').''; @@ -478,8 +443,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Info $htmltooltip = ''.$langs->trans("Name").': '.$module->name; $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); - if ($module->type == 'pdf') - { + 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; @@ -494,8 +458,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Preview print ''; - if ($module->type == 'pdf') - { + if ($module->type == 'pdf') { print ''.img_object($langs->trans("Preview"), 'generic').''; } else { print img_object($langs->trans("PreviewNotAvailable"), 'generic'); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 5c82d1237f6..25f46e6232a 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1641,7 +1641,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM } } - if($conf->stocktransfer->enabled) { + if ($conf->stocktransfer->enabled) { $newmenu->add('/product/stock/stocktransfer/stocktransfer_list.php', $langs->trans("ModuleStockTransferName"), 0, $user->rights->stocktransfer->stocktransfer->read, '', $mainmenu, 'stocktransfer', 0, '', '', '', img_picto('', 'stock', 'class="pictofixedwidth"')); $newmenu->add('/product/stock/stocktransfer/stocktransfer_card.php?action=create', $langs->trans('StockTransferNew'), 1, $user->rights->stocktransfer->stocktransfer->write); $newmenu->add('/product/stock/stocktransfer/stocktransfer_list.php', $langs->trans('List'), 1, $user->rights->stocktransfer->stocktransfer->read); diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index e60ea3c330d..d15e9797d13 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -348,26 +348,26 @@ class modStockTransfer extends DolibarrModules // 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=products,fk_leftmenu=stock', - // This is a Left menu entry - 'type'=>'left', - 'titre'=>$langs->trans('StockTransferList'), - 'mainmenu'=>'products', - 'leftmenu'=>'stocktransfer_stocktransferlist', - 'url'=>'/stocktransfer/stocktransfer_list.php', - // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'langs'=>'stocktransfer@stocktransfer', - 'position'=>1100+$r, - // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. - 'enabled'=>'$conf->stocktransfer->enabled', - // Use 'perms'=>'$user->rights->stocktransfer->level1->level2' if you want your menu with a permission rules - 'perms'=>'1', - '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=products,fk_leftmenu=stock', + // This is a Left menu entry + 'type'=>'left', + 'titre'=>$langs->trans('StockTransferList'), + 'mainmenu'=>'products', + 'leftmenu'=>'stocktransfer_stocktransferlist', + 'url'=>'/stocktransfer/stocktransfer_list.php', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'stocktransfer@stocktransfer', + 'position'=>1100+$r, + // Define condition to show or hide menu entry. Use '$conf->stocktransfer->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->stocktransfer->enabled', + // Use 'perms'=>'$user->rights->stocktransfer->level1->level2' if you want your menu with a permission rules + 'perms'=>'1', + 'target'=>'', + // 0=Menu for internal users, 1=external users, 2=both + 'user'=>2, + );*/ /* END MODULEBUILDER LEFTMENU STOCKTRANSFER */ @@ -464,13 +464,11 @@ class modStockTransfer extends DolibarrModules $dirodt=DOL_DATA_ROOT.'/doctemplates/stocktransfer'; $dest=$dirodt.'/template_stocktransfers.odt'; - if (file_exists($src) && ! file_exists($dest)) - { + 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) - { + if ($result < 0) { $langs->load("errors"); $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest); return 0; @@ -489,20 +487,21 @@ class modStockTransfer extends DolibarrModules // Rôles $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "internal"'); $res = $db->fetch_object($resql); - if(empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "internal", "STRESP", "Responsable du transfert de stocks", 1, NULL, 0)'); + if (empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "internal", "STRESP", "Responsable du transfert de stocks", 1, NULL, 0)'); $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STFROM" AND element = "StockTransfer" AND source = "external"'); $res = $db->fetch_object($resql); - if(empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STFROM", "Contact expéditeur transfert de stocks", 1, NULL, 0)'); + if (empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STFROM", "Contact expéditeur transfert de stocks", 1, NULL, 0)'); $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "external"'); $res = $db->fetch_object($resql); - if(empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STDEST", "Contact destinataire transfert de stocks", 1, NULL, 0)'); + if (empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STDEST", "Contact destinataire transfert de stocks", 1, NULL, 0)'); return $this->_init($sql, $options); } - function getNextId() { + function getNextId() + { global $db; @@ -510,8 +509,7 @@ class modStockTransfer extends DolibarrModules $newid = 0; $sql = "SELECT max(rowid) newid from ".MAIN_DB_PREFIX."c_type_contact"; $result = $db->query($sql); - if ($result) - { + if ($result) { $obj = $db->fetch_object($result); $newid = ($obj->newid + 1); } else { diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 9f9edaadb7a..2bffdf68b2d 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -209,23 +209,18 @@ class pdf_eagle extends ModelePdfStockTransfer // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); - if (!empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE)) - { + if (!empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE)) { $objphoto = new Product($this->db); - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { if (empty($object->lines[$i]->fk_product)) continue; $objphoto = new Product($this->db); $objphoto->fetch($object->lines[$i]->fk_product); - if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) - { + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/"; $dir = $conf->product->dir_output.'/'.$pdir; - } - else - { + } else { $pdir = get_exdir(0, 2, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; $dir = $conf->product->dir_output.'/'.$pdir; } @@ -235,17 +230,12 @@ class pdf_eagle extends ModelePdfStockTransfer foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo - if ($obj['photo_vignette']) - { + if ($obj['photo_vignette']) { $filename = $obj['photo_vignette']; - } - else - { + } else { $filename = $obj['photo']; } - } - else - { + } else { $filename = $obj['photo']; } @@ -259,35 +249,27 @@ class pdf_eagle extends ModelePdfStockTransfer if (count($realpatharray) == 0) $this->posxpicture = $this->posxqty; - if ($conf->stocktransfer->dir_output) - { + if ($conf->stocktransfer->dir_output) { // Definition de $dir et $file - if ($object->specimen) - { + if ($object->specimen) { $dir = $conf->stocktransfer->dir_output; $file = $dir."/SPECIMEN.pdf"; - } - else - { + } else { $stocktransferref = dol_sanitizeFileName($object->ref); $dir = $conf->stocktransfer->dir_output.'/'.$object->element."/".$stocktransferref; $file = $dir."/".$stocktransferref.".pdf"; } - if (!file_exists($dir)) - { - if (dol_mkdir($dir) < 0) - { + if (!file_exists($dir)) { + if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } - if (file_exists($dir)) - { + if (file_exists($dir)) { // Add pdfgeneration hook - if (!is_object($hookmanager)) - { + if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } @@ -307,15 +289,13 @@ class pdf_eagle extends ModelePdfStockTransfer if ($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS > 0) $heightforfooter += 6; $pdf->SetAutoPageBreak(1, 0); - if (class_exists('TCPDF')) - { + if (class_exists('TCPDF')) { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File - if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) - { + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } @@ -351,11 +331,9 @@ class pdf_eagle extends ModelePdfStockTransfer // Incoterm $height_incoterms = 0; - if ($conf->incoterm->enabled) - { + if ($conf->incoterm->enabled) { $desc_incoterms = $object->getIncotermsForPDF(); - if ($desc_incoterms) - { + if ($desc_incoterms) { $tab_top = 88; $pdf->SetFont('', '', $default_font_size - 1); @@ -372,8 +350,7 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if (!empty($object->note_public) || !empty($object->tracking_number)) - { + if (!empty($object->note_public) || !empty($object->tracking_number)) { $tab_top = 88 + $height_incoterms; $tab_top_alt = $tab_top; @@ -382,24 +359,20 @@ class pdf_eagle extends ModelePdfStockTransfer //$tab_top_alt += 1; // Tracking number - if (!empty($object->tracking_number)) - { + if (!empty($object->tracking_number)) { $pdf->writeHTMLCell(60, 4, $this->posxdesc - 1, $tab_top - 1, $outputlangs->transnoentities("TrackingNumber")." : ".$object->tracking_number, 0, 1, false, true, 'L'); $tab_top_alt = $pdf->GetY(); $object->getUrlTrackingStatus($object->tracking_number); - if (!empty($object->tracking_url)) - { - if ($object->shipping_method_id > 0) - { + if (!empty($object->tracking_url)) { + if ($object->shipping_method_id > 0) { // Get code using getLabelFromKey $code = $outputlangs->getLabelFromKey($this->db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); $label = ''; if ($object->tracking_url != $object->tracking_number) $label .= $outputlangs->trans("LinkToTrackYourPackage")."
"; $label .= $outputlangs->trans("SendingMethod").": ".$outputlangs->trans("SendingMethod".strtoupper($code)); //var_dump($object->tracking_url != $object->tracking_number);exit; - if ($object->tracking_url != $object->tracking_number) - { + if ($object->tracking_url != $object->tracking_number) { $label .= " : "; $label .= $object->tracking_url; } @@ -412,8 +385,7 @@ class pdf_eagle extends ModelePdfStockTransfer } // Notes - if (!empty($object->note_public)) - { + if (!empty($object->note_public)) { $pdf->SetFont('', '', $default_font_size - 1); // Dans boucle pour gerer multi-page $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1); } @@ -427,9 +399,7 @@ class pdf_eagle extends ModelePdfStockTransfer $tab_height = $tab_height - $height_note; $tab_top = $nexY + 6; - } - else - { + } else { $height_note = 0; } @@ -439,8 +409,7 @@ class pdf_eagle extends ModelePdfStockTransfer $TCacheEntrepots=array(); // Loop on each lines - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -458,8 +427,7 @@ class pdf_eagle extends ModelePdfStockTransfer $posYAfterDescription = 0; // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page - { + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); @@ -470,12 +438,10 @@ class pdf_eagle extends ModelePdfStockTransfer // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - if (isset($imglinesize['width']) && isset($imglinesize['height'])) - { + if (isset($imglinesize['width']) && isset($imglinesize['height'])) { $curX = $this->posxpicture - 1; $pdf->Image($realpatharray[$i], $curX + (($this->posxqty - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually @@ -486,7 +452,7 @@ class pdf_eagle extends ModelePdfStockTransfer $curX = $this->posxdesc - 1; $pdf->startTransaction(); - if(method_exists($object->lines[$i], 'fetch_product')) { + if (method_exists($object->lines[$i], 'fetch_product')) { $object->lines[$i]->fetch_product(); $object->lines[$i]->label = $object->lines[$i]->product->label; $object->lines[$i]->description = $object->lines[$i]->product->description; @@ -495,8 +461,7 @@ class pdf_eagle extends ModelePdfStockTransfer pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); - if ($pageposafter > $pageposbefore) // There is a pagebreak - { + if ($pageposafter > $pageposbefore) { // There is a pagebreak $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; @@ -506,28 +471,22 @@ class pdf_eagle extends ModelePdfStockTransfer $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text - { - if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text + if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $pdf->setPage($pageposafter + 1); } - } - else - { + } else { // We found a page break // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - } - else // No pagebreak + } else // No pagebreak { $pdf->commitTransaction(); } @@ -555,7 +514,7 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetXY($this->posxqty, $curY); // Lot / série - if(!empty($conf->productbatch->enabled)) { + if (!empty($conf->productbatch->enabled)) { $pdf->SetXY($this->posxlot, $curY); $pdf->MultiCell(($this->posxqty - $this->posxlot), 3, $object->lines[$i]->batch, '', 'C'); } @@ -567,7 +526,7 @@ class pdf_eagle extends ModelePdfStockTransfer // Warehouse source $wh_source = new Entrepot($db); - if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_source])) $wh_source = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source]; + if (!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_source])) $wh_source = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source]; else { $wh_source->fetch($object->lines[$i]->fk_warehouse_source); $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source] = $wh_source; @@ -577,7 +536,7 @@ class pdf_eagle extends ModelePdfStockTransfer // Warehouse destination $wh_destination = new Entrepot($db); - if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination])) $wh_destination = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination]; + if (!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination])) $wh_destination = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination]; else { $wh_destination->fetch($object->lines[$i]->fk_warehouse_destination); $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination] = $wh_destination; @@ -585,8 +544,7 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetXY($this->posxwarehousedestination, $curY); $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination), 3, $wh_destination->ref.(!empty($wh_destination->lieu) ? ' - '.$wh_destination->lieu : ''), '', 'C'); - if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) - { + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { $pdf->SetXY($this->posxpuht, $curY); $pdf->MultiCell(($this->posxtotalht - $this->posxpuht - 1), 3, price($object->lines[$i]->subprice, 0, $outputlangs), '', 'R'); @@ -598,8 +556,7 @@ class pdf_eagle extends ModelePdfStockTransfer if ($weighttxt && $voltxt) $nexY += 2; // Add line - if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) - { + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); @@ -608,15 +565,11 @@ class pdf_eagle extends ModelePdfStockTransfer } // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) - { + while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); - if ($pagenb == 1) - { + if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -625,14 +578,10 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) - { - if ($pagenb == 1) - { + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { + if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -645,13 +594,10 @@ class pdf_eagle extends ModelePdfStockTransfer } // Show square - if ($pagenb == 1) - { + if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } @@ -672,8 +618,7 @@ class pdf_eagle extends ModelePdfStockTransfer $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) - { + if ($reshook < 0) { $this->error = $hookmanager->error; $this->errors = $hookmanager->errors; } @@ -684,15 +629,11 @@ class pdf_eagle extends ModelePdfStockTransfer $this->result = array('fullpath'=>$file); return 1; // No error - } - else - { + } else { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } - } - else - { + } else { $this->error = $langs->transnoentities("ErrorConstantNotDefined", "EXP_OUTPUTDIR"); return 0; } @@ -745,8 +686,7 @@ class pdf_eagle extends ModelePdfStockTransfer $totalOrdered = $tmparray['ordered']; $totalToShip = $tmparray['toship']; // Set trueVolume and volume_units not currently stored into database - if ($object->trueWidth && $object->trueHeight && $object->trueDepth) - { + if ($object->trueWidth && $object->trueHeight && $object->trueDepth) { $object->trueVolume = price(($object->trueWidth * $object->trueHeight * $object->trueDepth), 0, $outputlangs, 0, 0); $object->volume_units = $object->size_units * 3; } @@ -760,20 +700,17 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Total"), 0, 'L', 1); - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) - { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) { $pdf->SetXY($this->posxwarehousesource, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($this->posxwarehousedestination - $this->posxwarehousesource, $tab2_hl, $totalOrdered, 0, 'C', 1); } - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_QTYTOSHIP)) - { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_QTYTOSHIP)) { $pdf->SetXY($this->posxwarehousedestination, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($this->posxpuht - $this->posxwarehousedestination, $tab2_hl, $totalToShip, 0, 'C', 1); } - if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) - { + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { $pdf->SetXY($this->posxpuht, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($this->posxtotalht - $this->posxpuht, $tab2_hl, '', 0, 'C', 1); @@ -781,18 +718,15 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxtotalht, $tab2_hl, price($object->total_ht, 0, $outputlangs), 0, 'C', 1); } - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) - { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) { // Total Weight - if ($totalWeighttoshow) - { + if ($totalWeighttoshow) { $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), $tab2_hl, $totalWeighttoshow, 0, 'C', 1); $index++; } - if ($totalVolumetoshow) - { + if ($totalVolumetoshow) { $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), $tab2_hl, $totalVolumetoshow, 0, 'C', 1); @@ -839,15 +773,14 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetDrawColor(128, 128, 128); $pdf->SetFont('', '', $default_font_size - 1); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5); $pdf->SetXY($this->posxdesc - 1, $tab_top + 1); $pdf->MultiCell($this->posxwarehousesource - $this->posxdesc, 2, $outputlangs->transnoentities("Description"), '', 'L'); } - if(!empty($conf->productbatch->enabled) && $this->atLeastOneBatch) { + if (!empty($conf->productbatch->enabled) && $this->atLeastOneBatch) { $pdf->line($this->posxlot - 1, $tab_top, $this->posxlot - 1, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxlot - 8, $tab_top + 1); @@ -856,23 +789,20 @@ class pdf_eagle extends ModelePdfStockTransfer } $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->SetXY($this->posxqty - 1, $tab_top + 1); $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), 2, $outputlangs->transnoentities("Qty"), '', 'C'); } $pdf->line($this->posxwarehousesource - 1, $tab_top, $this->posxwarehousesource - 1, $tab_top + $tab_height); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->SetXY($this->posxwarehousesource - 1, $tab_top + 1); $pdf->MultiCell(($this->posxwarehousedestination - $this->posxwarehousesource), 2, $outputlangs->transnoentities("WarehouseSource"), '', 'C'); } $pdf->line($this->posxwarehousedestination - 1, $tab_top, $this->posxwarehousedestination - 1, $tab_top + $tab_height); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->SetXY($this->posxwarehousedestination-2.5, $tab_top + 1); $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination+4), 2, $outputlangs->transnoentities("WarehouseTarget"), '', 'C'); } @@ -894,18 +824,18 @@ class pdf_eagle extends ModelePdfStockTransfer }*/ } - function atLeastOneBatch($object) { + function atLeastOneBatch($object) + { $atLeastOneBatch = false; foreach ($object->lines as $line) { - if(!empty($line->batch)) { + if (!empty($line->batch)) { return true; } } return false; - } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore @@ -929,8 +859,7 @@ class pdf_eagle extends ModelePdfStockTransfer pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); // Show Draft Watermark - if ($object->statut == 0 && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) - { + if ($object->statut == 0 && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) { pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->SHIPPING_DRAFT_WATERMARK); } @@ -947,47 +876,36 @@ class pdf_eagle extends ModelePdfStockTransfer // Logo $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; - if ($this->emetteur->logo) - { - if (is_readable($logo)) - { + if ($this->emetteur->logo) { + if (is_readable($logo)) { $height = pdf_getHeightForLogo($logo); $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) - } - else - { + } else { $pdf->SetTextColor(200, 0, 0); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } - } - else - { + } else { $text = $this->emetteur->name; $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); } // Show barcode - if (!empty($conf->barcode->enabled)) - { + if (!empty($conf->barcode->enabled)) { $posx = 105; - } - else - { + } else { $posx = $this->marge_gauche + 3; } //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); - if (!empty($conf->barcode->enabled)) - { + if (!empty($conf->barcode->enabled)) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); } $pdf->SetDrawColor(128, 128, 128); - if (!empty($conf->barcode->enabled)) - { + if (!empty($conf->barcode->enabled)) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); @@ -1012,8 +930,7 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->MultiCell($w, 4, $outputlangs->transnoentities("Ref")." : ".$object->ref, '', 'R'); // Date reelle depart - if (!empty($object->date_prevue_depart)) - { + if (!empty($object->date_prevue_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1021,8 +938,7 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date reelle arrivée - if (!empty($object->date_prevue_arrivee)) - { + if (!empty($object->date_prevue_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1030,8 +946,7 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date reelle depart - if (!empty($object->date_reelle_depart)) - { + if (!empty($object->date_reelle_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1039,16 +954,14 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date reelle arrivée - if (!empty($object->date_reelle_arrivee)) - { + if (!empty($object->date_reelle_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); } - if (!empty($object->thirdparty->code_client)) - { + if (!empty($object->thirdparty->code_client)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1064,15 +977,13 @@ class pdf_eagle extends ModelePdfStockTransfer $origin_id = $object->origin_id; // TODO move to external function - if (!empty($conf->$origin->enabled)) // commonly $origin='commande' - { + if (!empty($conf->$origin->enabled)) { // commonly $origin='commande' $outputlangs->load('orders'); $classname = ucfirst($origin); $linkedobject = new $classname($this->db); $result = $linkedobject->fetch($origin_id); - if ($result >= 0) - { + if ($result >= 0) { //$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects $pdf->SetFont('', '', $default_font_size - 2); @@ -1087,8 +998,7 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if ($showaddress) - { + if ($showaddress) { // Sender properties $carac_emetteur = ''; // Add internal contact of origin element if defined @@ -1096,8 +1006,7 @@ class pdf_eagle extends ModelePdfStockTransfer $arrayidcontact = $object->getIdContact('external', 'STFROM'); $usecontact = false; - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { /*$object->fetch_user(reset($arrayidcontact)); $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ $usecontact = true; @@ -1107,9 +1016,9 @@ class pdf_eagle extends ModelePdfStockTransfer if ($usecontact) $thirdparty = $object->contact; else $thirdparty = $this->emetteur; - if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + if ($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); // Show sender @@ -1146,8 +1055,7 @@ class pdf_eagle extends ModelePdfStockTransfer // If SHIPPING contact defined, we use it $usecontact = false; $arrayidcontact = $object->getIdContact('external', 'STDEST'); - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { $usecontact = true; $result = $object->fetch_contact($arrayidcontact[0]); } @@ -1160,7 +1068,7 @@ class pdf_eagle extends ModelePdfStockTransfer $thirdparty = $object->thirdparty; } - if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); diff --git a/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php b/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php index a349f4f536e..fab0952e894 100644 --- a/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php +++ b/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php @@ -114,8 +114,7 @@ class mod_stocktransfer_advanced extends ModeleNumRefStockTransfer /*$mysoc->code_client = $old_code_client; $mysoc->typent_code = $old_code_type;*/ - if (!$numExample) - { + if (!$numExample) { $numExample = $langs->trans('NotConfigured'); } return $numExample; @@ -136,8 +135,7 @@ class mod_stocktransfer_advanced extends ModeleNumRefStockTransfer // We get cursor rule $mask = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADVANCED_MASK; - if (!$mask) - { + if (!$mask) { $this->error = 'NotConfigured'; return 0; } diff --git a/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php b/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php index 77236ec0e40..6a6c7c556e6 100644 --- a/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php +++ b/htdocs/core/modules/stocktransfer/mod_stocktransfer_standard.php @@ -92,19 +92,16 @@ class mod_stocktransfer_standard extends ModeleNumRefStockTransfer $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; if ($object->ismultientitymanaged == 1) { $sql .= " AND entity = ".$conf->entity; - } - elseif ($object->ismultientitymanaged == 2) { + } elseif ($object->ismultientitymanaged == 2) { // TODO } $resql = $db->query($sql); - if ($resql) - { + 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)) - { + 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; @@ -130,20 +127,16 @@ class mod_stocktransfer_standard extends ModeleNumRefStockTransfer $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; if ($object->ismultientitymanaged == 1) { $sql .= " AND entity = ".$conf->entity; - } - elseif ($object->ismultientitymanaged == 2) { + } elseif ($object->ismultientitymanaged == 2) { // TODO } $resql = $db->query($sql); - if ($resql) - { + if ($resql) { $obj = $db->fetch_object($resql); if ($obj) $max = intval($obj->max); else $max = 0; - } - else - { + } else { dol_syslog("mod_stocktransfer_standard::getNextValue", LOG_DEBUG); return -1; } diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 7faf8d7c530..cdf999e3258 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -196,23 +196,17 @@ class StockTransfer extends CommonObject }*/ // Unset fields that are disabled - foreach ($this->fields as $key => $val) - { - if (isset($val['enabled']) && empty($val['enabled'])) - { + 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 (is_array($val['arrayofkeyval'])) - { - foreach ($val['arrayofkeyval'] as $key2 => $val2) - { + if (is_object($langs)) { + foreach ($this->fields as $key => $val) { + if (is_array($val['arrayofkeyval'])) { + foreach ($val['arrayofkeyval'] as $key2 => $val2) { $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); } } @@ -229,9 +223,9 @@ class StockTransfer extends CommonObject */ public function create(User $user, $notrigger = false) { - $this->status = (int)$this->status; - if($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0; - if($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0; + $this->status = (int) $this->status; + if ($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0; + if ($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0; return $this->createCommon($user, $notrigger); } @@ -277,14 +271,11 @@ class StockTransfer extends CommonObject $object->status = self::STATUS_DRAFT; // ... // Clear extrafields that are unique - if (is_array($object->array_options) && count($object->array_options) > 0) - { + 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) - { + foreach ($object->array_options as $key => $option) { $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) - { + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; unset($object->array_options[$key]); } @@ -300,20 +291,16 @@ class StockTransfer extends CommonObject $this->errors = $object->errors; } - if (!$error) - { + if (!$error) { // copy internal contacts - if ($this->copy_linked_contact($object, 'internal') < 0) - { + if ($this->copy_linked_contact($object, 'internal') < 0) { $error++; } } - if (!$error) - { + if (!$error) { // copy external contacts if same company - if (property_exists($this, 'socid') && $this->socid == $object->socid) - { + if (property_exists($this, 'socid') && $this->socid == $object->socid) { if ($this->copy_linked_contact($object, 'external') < 0) $error++; } @@ -368,17 +355,17 @@ class StockTransfer extends CommonObject return ($a->rang < $b->rang) ? -1 : 1; } - function getValorisationTotale() { + function getValorisationTotale() + { $total_pmp = 0; - if(empty($this->lines)) $this->fetchLines(); - if(!empty($this->lines)) { + if (empty($this->lines)) $this->fetchLines(); + if (!empty($this->lines)) { foreach ($this->lines as $l) $total_pmp+= ($l->pmp * $l->qty); } return $total_pmp; - } /** @@ -411,14 +398,11 @@ class StockTransfer extends CommonObject foreach ($filter as $key => $value) { if ($key == 't.rowid') { $sqlwhere[] = $key.'='.$value; - } - elseif (strpos($key, 'date') !== false) { + } elseif (strpos($key, 'date') !== false) { $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; - } - elseif ($key == 'customsql') { + } elseif ($key == 'customsql') { $sqlwhere[] = $value; - } - else { + } else { $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; } } @@ -438,8 +422,7 @@ class StockTransfer extends CommonObject if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < ($limit ? min($limit, $num) : $num)) - { + while ($i < ($limit ? min($limit, $num) : $num)) { $obj = $this->db->fetch_object($resql); $record = new self($this->db); @@ -481,8 +464,8 @@ class StockTransfer extends CommonObject */ public function delete(User $user, $notrigger = false) { - if(empty($this->lines)) $this->fetchLines(); - if(!empty($this->lines)) { + if (empty($this->lines)) $this->fetchLines(); + if (!empty($this->lines)) { foreach ($this->lines as $l) $res = $this->deleteLine($user, $l->id); } return $this->deleteCommon($user, $notrigger); @@ -500,8 +483,7 @@ class StockTransfer extends CommonObject public function deleteLine(User $user, $idline, $notrigger = false) { global $db; - if ($this->status < 0) - { + if ($this->status < 0) { $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; return -2; } @@ -528,8 +510,7 @@ class StockTransfer extends CommonObject $error = 0; // Protection - if ($this->status == self::STATUS_VALIDATED) - { + if ($this->status == self::STATUS_VALIDATED) { dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); return 0; } @@ -547,12 +528,9 @@ class StockTransfer extends CommonObject $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 - { + 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 - { + } else { $num = $this->ref; } $this->newref = $num; @@ -568,15 +546,13 @@ class StockTransfer extends CommonObject dol_syslog(get_class($this)."::validate()", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { dol_print_error($this->db); $this->error = $this->db->lasterror(); $error++; } - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('STOCKTRANSFER_VALIDATE', $user); if ($result < 0) $error++; @@ -584,13 +560,11 @@ class StockTransfer extends CommonObject } } - if (!$error) - { + if (!$error) { $this->oldref = $this->ref; // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->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 = 'stocktransfer/".$this->db->escape($this->newref)."'"; $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; @@ -602,17 +576,14 @@ class StockTransfer extends CommonObject $newref = dol_sanitizeFileName($num); $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref; $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref; - if (!$error && file_exists($dirsource)) - { + if (!$error && file_exists($dirsource)) { dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); - if (@rename($dirsource, $dirdest)) - { + if (@rename($dirsource, $dirdest)) { dol_syslog("Rename ok"); // Rename docs starting with $oldref with $newref $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); - foreach ($listoffiles as $fileentry) - { + foreach ($listoffiles as $fileentry) { $dirsource = $fileentry['name']; $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); $dirsource = $fileentry['path'].'/'.$dirsource; @@ -625,19 +596,15 @@ class StockTransfer extends CommonObject } // Set new ref and current status - if (!$error) - { + if (!$error) { $this->ref = $num; $this->status = self::STATUS_VALIDATED; } - if (!$error) - { + if (!$error) { $this->db->commit(); return 1; - } - else - { + } else { $this->db->rollback(); return -1; } @@ -654,8 +621,7 @@ class StockTransfer extends CommonObject public function setDraft($user, $notrigger = 0) { // Protection - if ($this->status <= self::STATUS_DRAFT) - { + if ($this->status <= self::STATUS_DRAFT) { return 0; } @@ -679,8 +645,7 @@ class StockTransfer extends CommonObject public function cancel($user, $notrigger = 0) { // Protection - if ($this->status != self::STATUS_VALIDATED) - { + if ($this->status != self::STATUS_VALIDATED) { return 0; } @@ -704,8 +669,7 @@ class StockTransfer extends CommonObject public function reopen($user, $notrigger = 0) { // Protection - if ($this->status != self::STATUS_CLOSED) - { + if ($this->status != self::STATUS_CLOSED) { return 0; } @@ -746,8 +710,7 @@ class StockTransfer extends CommonObject $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id; - if ($option != 'nolink') - { + 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; @@ -755,17 +718,14 @@ class StockTransfer extends CommonObject } $linkclose = ''; - if (empty($notooltip)) - { - if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowStockTransfer"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } - else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); $linkstart = ''; @@ -789,14 +749,12 @@ class StockTransfer extends CommonObject $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 { + } else { $result .= '
No photo
'; } $result .= ''; - } - else { + } 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); } } @@ -839,8 +797,7 @@ class StockTransfer extends CommonObject public function LibStatut($status, $mode = 0) { // phpcs:enable - if (empty($this->labelStatus) || empty($this->labelStatusShort)) - { + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("stocktransfer@stocktransfer"); $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); @@ -873,28 +830,23 @@ class StockTransfer extends CommonObject $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)) - { + if ($result) { + if ($this->db->num_rows($result)) { $obj = $this->db->fetch_object($result); $this->id = $obj->rowid; - if ($obj->fk_user_author) - { + 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) - { + 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) - { + if ($obj->fk_user_cloture) { $cluser = new User($this->db); $cluser->fetch($obj->fk_user_cloture); $this->user_cloture = $cluser; @@ -906,9 +858,7 @@ class StockTransfer extends CommonObject } $this->db->free($result); - } - else - { + } else { dol_print_error($this->db); } } @@ -936,14 +886,11 @@ class StockTransfer extends CommonObject $objectline = new StockTransferLine($this->db); $result = $objectline->fetchAll('ASC', 'rang', 0, 0, array('customsql'=>'fk_stocktransfer = '.$this->id)); - if (is_numeric($result)) - { + if (is_numeric($result)) { $this->error = $this->error; $this->errors = $this->errors; return $result; - } - else - { + } else { $this->lines = $result; return $this->lines; } @@ -963,8 +910,7 @@ class StockTransfer extends CommonObject $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard'; } - if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) - { + if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) { $mybool = false; $file = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON.".php"; @@ -972,16 +918,14 @@ class StockTransfer extends CommonObject // Include file with class $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) - { + foreach ($dirmodels as $reldir) { $dir = dol_buildpath($reldir."core/modules/stocktransfer/"); // Load file with numbering class (if found) $mybool |= @include_once $dir.$file; } - if ($mybool === false) - { + if ($mybool === false) { dol_print_error('', "Failed to include file ".$file); return ''; } @@ -990,12 +934,9 @@ class StockTransfer extends CommonObject $obj = new $classname(); $numref = $obj->getNextValue($this); - if ($numref != '' && $numref != '-1') - { + if ($numref != '' && $numref != '-1') { return $numref; - } - else - { + } else { $this->error = $obj->error; //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); return ""; @@ -1004,9 +945,7 @@ class StockTransfer extends CommonObject print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; return ""; } - } - else - { + } else { print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); return ""; } diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 35d79dda95d..46aeba5980e 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -174,23 +174,17 @@ class StockTransferLine extends CommonObject }*/ // Unset fields that are disabled - foreach ($this->fields as $key => $val) - { - if (isset($val['enabled']) && empty($val['enabled'])) - { + 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 (is_array($val['arrayofkeyval'])) - { - foreach ($val['arrayofkeyval'] as $key2 => $val2) - { + if (is_object($langs)) { + foreach ($this->fields as $key => $val) { + if (is_array($val['arrayofkeyval'])) { + foreach ($val['arrayofkeyval'] as $key2 => $val2) { $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); } } @@ -248,14 +242,11 @@ class StockTransferLine extends CommonObject $object->status = self::STATUS_DRAFT; // ... // Clear extrafields that are unique - if (is_array($object->array_options) && count($object->array_options) > 0) - { + 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) - { + foreach ($object->array_options as $key => $option) { $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) - { + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; unset($object->array_options[$key]); } @@ -271,20 +262,16 @@ class StockTransferLine extends CommonObject $this->errors = $object->errors; } - if (!$error) - { + if (!$error) { // copy internal contacts - if ($this->copy_linked_contact($object, 'internal') < 0) - { + if ($this->copy_linked_contact($object, 'internal') < 0) { $error++; } } - if (!$error) - { + if (!$error) { // copy external contacts if same company - if (property_exists($this, 'socid') && $this->socid == $object->socid) - { + if (property_exists($this, 'socid') && $this->socid == $object->socid) { if ($this->copy_linked_contact($object, 'external') < 0) $error++; } @@ -360,14 +347,11 @@ class StockTransferLine extends CommonObject foreach ($filter as $key => $value) { if ($key == 't.rowid') { $sqlwhere[] = $key.'='.$value; - } - elseif (strpos($key, 'date') !== false) { + } elseif (strpos($key, 'date') !== false) { $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; - } - elseif ($key == 'customsql') { + } elseif ($key == 'customsql') { $sqlwhere[] = $value; - } - else { + } else { $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; } } @@ -387,8 +371,7 @@ class StockTransferLine extends CommonObject if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < ($limit ? min($limit, $num) : $num)) - { + while ($i < ($limit ? min($limit, $num) : $num)) { $obj = $this->db->fetch_object($resql); $record = new self($this->db); @@ -444,8 +427,7 @@ class StockTransferLine extends CommonObject */ public function deleteLine(User $user, $idline, $notrigger = false) { - if ($this->status < 0) - { + if ($this->status < 0) { $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; return -2; } @@ -453,7 +435,8 @@ class StockTransferLine extends CommonObject return $this->deleteLineCommon($user, $idline, $notrigger); } - function doStockMovement($label, $fk_entrepot, $direction=1) { + function doStockMovement($label, $fk_entrepot, $direction = 1) + { global $db, $conf, $user, $langs; @@ -469,8 +452,7 @@ class StockTransferLine extends CommonObject $movementstock->origin = new StockTransfer($db); $movementstock->origin->id = $this->fk_stocktransfer; - if (empty($this->batch)) // no batch for line - { + if (empty($this->batch)) { // no batch for line /*$result = $p->correct_stock( $user, $fk_entrepot, @@ -489,8 +471,7 @@ class StockTransferLine extends CommonObject setEventMessages($p->errors, $p->errorss, 'errors'); return 0; } - } - else { + } else { if ($p->hasbatch()) { $arraybatchinfo = $p->loadBatchInfo($this->batch); if (count($arraybatchinfo) > 0) { @@ -529,7 +510,6 @@ class StockTransferLine extends CommonObject } return 1; - } /** @@ -548,8 +528,7 @@ class StockTransferLine extends CommonObject $error = 0; // Protection - if ($this->status == self::STATUS_VALIDATED) - { + if ($this->status == self::STATUS_VALIDATED) { dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); return 0; } @@ -567,12 +546,9 @@ class StockTransferLine extends CommonObject $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 - { + 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 - { + } else { $num = $this->ref; } $this->newref = $num; @@ -588,15 +564,13 @@ class StockTransferLine extends CommonObject dol_syslog(get_class($this)."::validate()", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { dol_print_error($this->db); $this->error = $this->db->lasterror(); $error++; } - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user); if ($result < 0) $error++; @@ -604,13 +578,11 @@ class StockTransferLine extends CommonObject } } - if (!$error) - { + if (!$error) { $this->oldref = $this->ref; // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->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 = 'stocktransferline/".$this->db->escape($this->newref)."'"; $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; @@ -622,17 +594,14 @@ class StockTransferLine extends CommonObject $newref = dol_sanitizeFileName($num); $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref; $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref; - if (!$error && file_exists($dirsource)) - { + if (!$error && file_exists($dirsource)) { dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); - if (@rename($dirsource, $dirdest)) - { + if (@rename($dirsource, $dirdest)) { dol_syslog("Rename ok"); // Rename docs starting with $oldref with $newref $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); - foreach ($listoffiles as $fileentry) - { + foreach ($listoffiles as $fileentry) { $dirsource = $fileentry['name']; $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); $dirsource = $fileentry['path'].'/'.$dirsource; @@ -645,19 +614,15 @@ class StockTransferLine extends CommonObject } // Set new ref and current status - if (!$error) - { + if (!$error) { $this->ref = $num; $this->status = self::STATUS_VALIDATED; } - if (!$error) - { + if (!$error) { $this->db->commit(); return 1; - } - else - { + } else { $this->db->rollback(); return -1; } @@ -674,8 +639,7 @@ class StockTransferLine extends CommonObject public function setDraft($user, $notrigger = 0) { // Protection - if ($this->status <= self::STATUS_DRAFT) - { + if ($this->status <= self::STATUS_DRAFT) { return 0; } @@ -699,8 +663,7 @@ class StockTransferLine extends CommonObject public function cancel($user, $notrigger = 0) { // Protection - if ($this->status != self::STATUS_VALIDATED) - { + if ($this->status != self::STATUS_VALIDATED) { return 0; } @@ -724,8 +687,7 @@ class StockTransferLine extends CommonObject public function reopen($user, $notrigger = 0) { // Protection - if ($this->status != self::STATUS_CANCELED) - { + if ($this->status != self::STATUS_CANCELED) { return 0; } @@ -766,8 +728,7 @@ class StockTransferLine extends CommonObject $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id; - if ($option != 'nolink') - { + 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; @@ -775,17 +736,14 @@ class StockTransferLine extends CommonObject } $linkclose = ''; - if (empty($notooltip)) - { - if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowStockTransferLine"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } - else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); $linkstart = '
'; @@ -809,14 +767,12 @@ class StockTransferLine extends CommonObject $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 { + } else { $result .= '
No photo
'; } $result .= ''; - } - else { + } 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); } } @@ -859,8 +815,7 @@ class StockTransferLine extends CommonObject public function LibStatut($status, $mode = 0) { // phpcs:enable - if (empty($this->labelStatus) || empty($this->labelStatusShort)) - { + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("stocktransfer@stocktransfer"); $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); @@ -891,28 +846,23 @@ class StockTransferLine extends CommonObject $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)) - { + if ($result) { + if ($this->db->num_rows($result)) { $obj = $this->db->fetch_object($result); $this->id = $obj->rowid; - if ($obj->fk_user_author) - { + 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) - { + 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) - { + if ($obj->fk_user_cloture) { $cluser = new User($this->db); $cluser->fetch($obj->fk_user_cloture); $this->user_cloture = $cluser; @@ -924,9 +874,7 @@ class StockTransferLine extends CommonObject } $this->db->free($result); - } - else - { + } else { dol_print_error($this->db); } } @@ -954,14 +902,11 @@ class StockTransferLine extends CommonObject $objectline = new StockTransferLineLine($this->db); $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.$this->id)); - if (is_numeric($result)) - { + if (is_numeric($result)) { $this->error = $this->error; $this->errors = $this->errors; return $result; - } - else - { + } else { $this->lines = $result; return $this->lines; } @@ -981,8 +926,7 @@ class StockTransferLine extends CommonObject $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard'; } - if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) - { + if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) { $mybool = false; $file = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON.".php"; @@ -990,16 +934,14 @@ class StockTransferLine extends CommonObject // Include file with class $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) - { + foreach ($dirmodels as $reldir) { $dir = dol_buildpath($reldir."core/modules/stocktransfer/"); // Load file with numbering class (if found) $mybool |= @include_once $dir.$file; } - if ($mybool === false) - { + if ($mybool === false) { dol_print_error('', "Failed to include file ".$file); return ''; } @@ -1008,12 +950,9 @@ class StockTransferLine extends CommonObject $obj = new $classname(); $numref = $obj->getNextValue($this); - if ($numref != '' && $numref != '-1') - { + if ($numref != '' && $numref != '-1') { return $numref; - } - else - { + } else { $this->error = $obj->error; //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); return ""; @@ -1022,9 +961,7 @@ class StockTransferLine extends CommonObject print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; return ""; } - } - else - { + } else { print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); return ""; } diff --git a/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php b/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php index 03999b712e6..232229a014d 100644 --- a/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php +++ b/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php @@ -42,8 +42,7 @@ function stocktransferPrepareHead($object) $head[$h][2] = 'card'; $h++; - if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) - { + if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) { $nbContact = count($object->liste_contact(-1, 'internal')) + count($object->liste_contact(-1, 'external')); $head[$h][0] = dol_buildpath('/product/stock/stocktransfer/stocktransfer_contact.php', 1).'?id='.$object->id; $head[$h][1] = $langs->trans('ContactsAddresses'); @@ -52,8 +51,7 @@ function stocktransferPrepareHead($object) $h++; } - if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) - { + 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++; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php index cc580d2ab4a..b260dfc8d76 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php @@ -55,13 +55,10 @@ $action = GETPOST('action', 'alpha'); $cancel = GETPOST('cancel', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); -if (GETPOST('actioncode', 'array')) -{ +if (GETPOST('actioncode', 'array')) { $actioncode = GETPOST('actioncode', 'array', 3); if (!count($actioncode)) $actioncode = '0'; -} -else -{ +} 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'); @@ -105,18 +102,15 @@ $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)) -{ +if (empty($reshook)) { // Cancel - if (GETPOST('cancel', 'alpha') && !empty($backtopage)) - { + 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 - { + 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 = ''; } @@ -130,8 +124,7 @@ if (empty($reshook)) $form = new Form($db); -if ($object->id > 0) -{ +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 = ''; @@ -209,8 +202,7 @@ if ($object->id > 0) $out = '&origin='.$object->element.'&originid='.$object->id; $permok = $user->rights->agenda->myactions->create; - if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) - { + if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) { //$out.='
'; - if (!empty($conf->agenda->enabled)) - { - if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) - { + if (!empty($conf->agenda->enabled)) { + if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { print ''.$langs->trans("AddAction").''; - } - else - { + } else { print ''.$langs->trans("AddAction").''; } } print ''; - if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) - { + 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); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index abc653d5e75..ca5c2ce7e83 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -101,8 +101,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Initialize array of search criterias $search_all = trim(GETPOST("search_all", 'alpha')); $search = array(); -foreach ($object->fields as $key => $val) -{ +foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha')) $search[$key] = GETPOST('search_'.$key, 'alpha'); } @@ -140,8 +139,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if (empty($reshook)) -{ +if (empty($reshook)) { $error = 0; $backurlforlist = dol_buildpath('/product/stock/stocktransfer/stocktransfer_list.php', 1); @@ -169,30 +167,27 @@ if (empty($reshook)) // Action to build doc include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - if ($action == 'set_thirdparty' && $permissiontoadd) - { + if ($action == 'set_thirdparty' && $permissiontoadd) { $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'STOCKTRANSFER_MODIFY'); } - if ($action == 'classin' && $permissiontoadd) - { + if ($action == 'classin' && $permissiontoadd) { $object->setProject(GETPOST('projectid', 'int')); } - if($action == 'addline' && $permissiontoadd) { - - if($qty <= 0) { + if ($action == 'addline' && $permissiontoadd) { + if ($qty <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); $action = 'view'; } - if($fk_warehouse_source <= 0) { + if ($fk_warehouse_source <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); $action = 'view'; } - if($fk_warehouse_destination <= 0) { + if ($fk_warehouse_destination <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); $action = 'view'; @@ -200,25 +195,23 @@ if (empty($reshook)) $prod = new Product($db); $prod->fetch($fk_product); - if ($prod->hasbatch()) - { - if (empty($batch)) - { + if ($prod->hasbatch()) { + if (empty($batch)) { $error++; $langs->load("errors"); setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); } } else { - if(!empty($batch)) { + if (!empty($batch)) { $error++; setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); } } - if(empty($error)) { + if (empty($error)) { $line = new StockTransferLine($db); $records = $line->fetchAll('', '', 0, 0, array('customsql'=>' fk_stocktransfer = '.$id.' AND fk_product = '.$fk_product.' AND fk_warehouse_source = '.$fk_warehouse_source.' AND fk_warehouse_destination = '.$fk_warehouse_destination.' AND ('.(empty($batch) ? 'batch = "" or batch IS NULL' : 'batch = "'.$batch.'"' ).')')); - if(!empty($records[key($records)])) $line = $records[key($records)]; + if (!empty($records[key($records)])) $line = $records[key($records)]; $line->fk_stocktransfer = $id; $line->qty += $qty; $line->fk_warehouse_source = $fk_warehouse_source; @@ -227,28 +220,27 @@ if (empty($reshook)) $line->batch = $batch; $line->pmp = $prod->pmp; - if($line->id > 0) $line->update($user); + if ($line->id > 0) $line->update($user); else { $line->rang = count($object->lines) + 1; $line->create($user); } $object->fetchLines(); } - } elseif($action === 'updateline' && $permissiontoadd) { - - if($qty <= 0) { + } elseif ($action === 'updateline' && $permissiontoadd) { + if ($qty <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); $action = 'editline'; } - if($fk_warehouse_source <= 0) { + if ($fk_warehouse_source <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); $action = 'editline'; } - if($fk_warehouse_destination <= 0) { + if ($fk_warehouse_destination <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); $action = 'editline'; @@ -256,24 +248,22 @@ if (empty($reshook)) $prod = new Product($db); $prod->fetch($fk_product); - if ($prod->hasbatch()) - { - if (empty($batch)) - { + if ($prod->hasbatch()) { + if (empty($batch)) { $error++; $langs->load("errors"); setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); $action = 'editline'; } } else { - if(!empty($batch)) { + if (!empty($batch)) { $error++; setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); $action = 'editline'; } } - if(empty($error)) { + if (empty($error)) { $line = new StockTransferLine($db); $line->fetch($lineid); $line->qty = $qty; @@ -287,18 +277,18 @@ if (empty($reshook)) } // Décrémentation - if($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { + if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_source); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_TRANSFERED, $id); $object->status = $object::STATUS_TRANSFERED; $object->date_reelle_depart = date('Y-m-d'); @@ -308,18 +298,18 @@ if (empty($reshook)) } // Annulation décrémentation - if($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_source, 0); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_VALIDATED, $id); $object->status = $object::STATUS_VALIDATED; $object->date_reelle_depart = null; @@ -329,18 +319,18 @@ if (empty($reshook)) } // Incrémentation - if($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_destination, 0); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_CLOSED, $id); $object->status = $object::STATUS_CLOSED; $object->date_reelle_arrivee = date('Y-m-d'); @@ -350,18 +340,18 @@ if (empty($reshook)) } // Annulation incrémentation - if($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { + if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_destination); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_TRANSFERED, $id); $object->status = $object::STATUS_TRANSFERED; $object->date_reelle_arrivee = null; @@ -399,8 +389,8 @@ jQuery(document).ready(function() {'; // Affichage alerte date prévue de départ si transfert concerné $date_prevue_depart = $object->date_prevue_depart; $date_prevue_depart_plus_delai = $date_prevue_depart; -if($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); -if(!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) { +if ($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); +if (!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) { print "$('.valuefield.fieldname_date_prevue_depart').append('"; print img_warning($langs->trans('Alert').' - '.$langs->trans('Late')); print "');"; @@ -411,8 +401,7 @@ print '}); // Part to create -if ($action == 'create') -{ +if ($action == 'create') { print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("StockTransfer")), '', 'object_'.$object->picto); print '
'; @@ -450,8 +439,7 @@ if ($action == 'create') } // Part to edit record -if (($id || $ref) && $action == 'edit') -{ +if (($id || $ref) && $action == 'edit') { //if($object->status < 3) { print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto); @@ -485,8 +473,7 @@ if (($id || $ref) && $action == 'edit') } // Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) -{ +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { $res = $object->fetch_optionals(); $head = stocktransferPrepareHead($object); @@ -495,13 +482,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formconfirm = ''; // Confirmation to delete - if ($action == 'delete') - { + if ($action == 'delete') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteStockTransfer'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); } // Confirmation to delete line - if ($action == 'deleteline') - { + if ($action == 'deleteline') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); } // Clone confirmation @@ -540,8 +525,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Confirmation of action xxxx - if ($action == 'xxx') - { + if ($action == 'xxx') { $formquestion = array(); /* $forcecombo=0; @@ -651,8 +635,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea * Lines */ - if (!empty($object->table_element_line)) - { + if (!empty($object->table_element_line)) { // Show object lines /*$result = $object->getLinesArray(); @@ -709,9 +692,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea '; - if($lineid > 0) print ''; + if ($lineid > 0) print ''; print ''; -//print '
'; + //print '
'; $param = ''; @@ -725,7 +708,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('PMPValue'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); - if(empty($object->status)) { + if (empty($object->status)) { print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); @@ -738,8 +721,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $warehousestatics = new Entrepot($db); $warehousestatict = new Entrepot($db); - foreach ($listofdata as $key => $line) - { + foreach ($listofdata as $key => $line) { $productstatic->fetch($line->fk_product); $warehousestatics->fetch($line->fk_warehouse_source); $warehousestatict->fetch($line->fk_warehouse_destination); @@ -752,25 +734,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; - if ($conf->productbatch->enabled) - { + if ($conf->productbatch->enabled) { print ''; } print ''; print ''; - if($action === 'editline' && $line->id == $lineid) print ''; + if ($action === 'editline' && $line->id == $lineid) print ''; else print ''; print ''; - if(empty($object->status)) { - - if($action === 'editline' && $line->id == $lineid) { + if (empty($object->status)) { + if ($action === 'editline' && $line->id == $lineid) { //print ''; print ''; @@ -819,9 +799,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; } - if(empty($object->status) && $action !== 'editline') { + if (empty($object->status) && $action !== 'editline') { print ''; -// Product + // Product print ''; print ''; - } print '
'; - if($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); + if ($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); else print $productstatic->getNomUrl(1).' - '.$productstatic->label; print ''; - if($action === 'editline' && $line->id == $lineid) print ''; + if ($action === 'editline' && $line->id == $lineid) print ''; else print $line->batch; print ''; - if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); + if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); else print $warehousestatics->getNomUrl(1); print ''; - if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination,'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); + if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); else print $warehousestatict->getNomUrl(1); print ''.$line->qty.''; print price($line->pmp, 0, '', 1, -1, -1, $conf->currency); @@ -778,9 +759,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency); print '
'; print '
'; $filtertype = 0; if (!empty($conf->global->STOCK_SUPPORTS_SERVICES)) $filtertype = ''; @@ -844,21 +824,21 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // On stock ceux qui ne doivent pas être proposés dans la liste $TExcludedWarehouseSource=array(); - if(!empty($object->fk_warehouse_source)) { + if (!empty($object->fk_warehouse_source)) { $source_ent = new Entrepot($db); $source_ent->fetch($object->fk_warehouse_source); foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { - if(strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id']; + if (strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id']; } } // On stock ceux qui ne doivent pas être proposés dans la liste $TExcludedWarehouseDestination=array(); - if(!empty($object->fk_warehouse_destination)) { + if (!empty($object->fk_warehouse_destination)) { $dest_ent = new Entrepot($db); $dest_ent->fetch($object->fk_warehouse_destination); foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { - if(strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id']; + if (strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id']; } } @@ -887,7 +867,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Grad and drop lines print '
'; @@ -902,25 +881,21 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $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)) - { + if (empty($reshook)) { // Send if (empty($user->socid)) { print ''.$langs->trans('SendMail').''."\n"; } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_VALIDATED) { + if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; } } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } /*else @@ -929,38 +904,26 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea }*/ // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { - if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { + if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; - } - else - { + } else { $langs->load("errors"); print ''.$langs->trans("Validate").''; } } - } - - elseif($object->status == $object::STATUS_VALIDATED) { + } elseif ($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("StockTransferDecrementation").''; - } - - elseif($object->status == $object::STATUS_TRANSFERED) { + } elseif ($object->status == $object::STATUS_TRANSFERED) { print ''.$langs->trans("StockTransferDecrementationCancel").''; print ''.$langs->trans("StockTransferIncrementation").''; - } - - elseif($object->status == $object::STATUS_CLOSED) { + } elseif ($object->status == $object::STATUS_CLOSED) { print ''.$langs->trans("StockTransferIncrementationCancel").''; } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } @@ -990,8 +953,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea */ // Delete (need delete permission, or if draft, just need create/modify permission) - if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) - { + if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) { print ''.$langs->trans('Delete').''."\n"; } /*else @@ -1008,8 +970,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $action = 'presend'; } - if ($action != 'presend') - { + if ($action != 'presend') { print '
'; print ''; // ancre diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php index 6dc808f206d..8e0eac4b4cb 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php @@ -52,27 +52,20 @@ $result = restrictedArea($user, 'stocktransfer', $id, '', 'stocktransfer'); $object = new StockTransfer($db); // Load object -if ($id > 0 || !empty($ref)) -{ +if ($id > 0 || !empty($ref)) { $ret = $object->fetch($id, $ref); - if ($ret == 0) - { + if ($ret == 0) { $langs->load("errors"); setEventMessages($langs->trans('ErrorRecordNotFound'), null, 'errors'); $error++; - } - elseif ($ret < 0) - { + } elseif ($ret < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; } } -if (!$error) -{ +if (!$error) { $object->fetch_thirdparty(); -} -else -{ +} else { header('Location: '.dol_buildpath('/stocktransfer/stocktransfer_list.php', 1)); exit; } @@ -82,54 +75,40 @@ else * Add a new contact */ -if ($action == 'addcontact' && $user->rights->stocktransfer->stocktransfer->write) -{ - if ($object->id > 0) - { - $contactid = (GETPOST('userid', 'int') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); - $result = $object->add_contact($contactid, !empty($_POST["typecontact"]) ? $_POST["typecontact"] : $_POST["type"], $_POST["source"]); - } +if ($action == 'addcontact' && $user->rights->stocktransfer->stocktransfer->write) { + if ($object->id > 0) { + $contactid = (GETPOST('userid', 'int') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); + $result = $object->add_contact($contactid, !empty($_POST["typecontact"]) ? $_POST["typecontact"] : $_POST["type"], $_POST["source"]); + } - if ($result >= 0) - { + if ($result >= 0) { header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; - } - else - { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') - { + } else { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { $langs->load("errors"); setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors'); - } - else - { + } else { setEventMessages($object->error, $object->errors, 'errors'); } } } // Toggle the status of a contact -elseif ($action == 'swapstatut' && $user->rights->stocktransfer->stocktransfer->write) -{ - if ($object->id > 0) - { - $result = $object->swapContactStatus(GETPOST('ligne')); +elseif ($action == 'swapstatut' && $user->rights->stocktransfer->stocktransfer->write) { + if ($object->id > 0) { + $result = $object->swapContactStatus(GETPOST('ligne')); } } // Deletes a contact -elseif ($action == 'deletecontact' && $user->rights->stocktransfer->stocktransfer->write) -{ +elseif ($action == 'deletecontact' && $user->rights->stocktransfer->stocktransfer->write) { $result = $object->delete_contact($lineid); - if ($result >= 0) - { + if ($result >= 0) { header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; - } - else - { + } else { dol_print_error($db); } } @@ -151,9 +130,8 @@ $form = new Form($db); $formcompany = new FormCompany($db); $formother = new FormOther($db); -if ($object->id > 0) -{ - $head = stocktransferPrepareHead($object); +if ($object->id > 0) { + $head = stocktransferPrepareHead($object); dol_fiche_head($head, 'contact', $langs->trans("StockTransfer"), -1, 'stock'); @@ -167,42 +145,40 @@ if ($object->id > 0) $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 - if(!empty($object->thirdparty)) { + if (!empty($object->thirdparty)) { $morehtmlref .= '
' . $langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'customer'); } // Project - if (!empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref .= '
'.$langs->trans('Project').' '; - if ($user->rights->stocktransfer->stocktransfer->write) - { - 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 .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; - } else { - $morehtmlref .= ''; - } - } + if (!empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
'.$langs->trans('Project').' '; + if ($user->rights->stocktransfer->stocktransfer->write) { + 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 .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } } $morehtmlref .= '
'; @@ -213,8 +189,7 @@ if ($object->id > 0) $user->rights->stocktransfer->write = $user->rights->stocktransfer->stocktransfer->write; // Contacts lines (modules that overwrite templates must declare this into descriptor) $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl')); - foreach ($dirtpls as $reldir) - { + foreach ($dirtpls as $reldir) { $res = @include dol_buildpath($reldir.'/contacts.tpl.php'); if ($res) break; } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_document.php b/htdocs/product/stock/stocktransfer/stocktransfer_document.php index bbde110ef0e..4fba0c3fea5 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_document.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_document.php @@ -108,8 +108,7 @@ $help_url = ''; //$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; llxHeader('', $title, $help_url); -if ($object->id) -{ +if ($object->id) { /* * Show tabs */ @@ -121,8 +120,7 @@ if ($object->id) // 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) - { + foreach ($filearray as $key => $file) { $totalsize += $file['size']; } @@ -200,9 +198,7 @@ if ($object->id) $relativepathwithnofile = 'stocktransfer/'.dol_sanitizeFileName($object->ref).'/'; include_once DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; -} -else -{ +} else { accessforbidden('', 0, 1); } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_list.php b/htdocs/product/stock/stocktransfer/stocktransfer_list.php index 10532fe889c..e7f910e6e22 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_list.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_list.php @@ -111,30 +111,25 @@ if (!$sortorder) $sortorder = "ASC"; // Initialize array of search criterias $search_all = GETPOST('search_all', 'alphanohtml') ? trim(GETPOST('search_all', 'alphanohtml')) : trim(GETPOST('sall', 'alphanohtml')); $search = array(); -foreach ($object->fields as $key => $val) -{ +foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') $search[$key] = GETPOST('search_'.$key, 'alpha'); } // List of fields to search into when doing a "search in all" $fieldstosearchall = array(); -foreach ($object->fields as $key => $val) -{ +foreach ($object->fields as $key => $val) { if ($val['searchall']) $fieldstosearchall['t.'.$key] = $val['label']; } // Definition of fields for list $arrayfields = array(); -foreach ($object->fields as $key => $val) -{ +foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']); } // Extra fields -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) -{ - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) - { +if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) { $arrayfields["ef.".$key] = array( 'label'=>$extrafields->attributes[$object->table_element]['label'][$key], @@ -156,8 +151,7 @@ $permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete; // Security check if (empty($conf->stocktransfer->enabled)) accessforbidden('Module not enabled'); $socid = 0; -if ($user->socid > 0) // Protection if external user -{ +if ($user->socid > 0) { // Protection if external user //$socid = $user->socid; accessforbidden(); } @@ -177,24 +171,20 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if (empty($reshook)) -{ +if (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) - { + 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')) - { + || 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 } @@ -223,8 +213,7 @@ $title = $langs->trans('StockTransferList'); // Build and execute select // -------------------------------------------------------------------- $sql = 'SELECT '; -foreach ($object->fields as $key => $val) -{ +foreach ($object->fields as $key => $val) { $sql .= 't.'.$key.', '; } // Add fields from extrafields @@ -240,8 +229,7 @@ $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 ($object->ismultientitymanaged == 1) $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; else $sql .= " WHERE 1 = 1"; -foreach ($search as $key => $val) -{ +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) { @@ -280,28 +268,22 @@ $sql .= $db->order($sortfield, $sortorder); // Count total nb of records $nbtotalofrecords = ''; -if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) -{ +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 - { + 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))) -{ +if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) { $num = $nbtotalofrecords; -} -else -{ +} else { if ($limit) $sql .= $db->plimit($limit + 1, $offset); $resql = $db->query($sql); - if (!$resql) - { + if (!$resql) { dol_print_error($db); exit; } @@ -310,8 +292,7 @@ else } // Direct jump if only one record found -if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) -{ +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('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$id); @@ -344,8 +325,7 @@ $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) -{ +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]); } @@ -385,8 +365,7 @@ $objecttmp = new StockTransfer($db); $trackid = 'xxxx'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; -if ($search_all) -{ +if ($search_all) { foreach ($fieldstosearchall as $key => $val) $fieldstosearchall[$key] = $langs->trans($val); print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'; } @@ -401,8 +380,7 @@ $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $ob if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; else $moreforfilter = $hookmanager->resPrint; -if (!empty($moreforfilter)) -{ +if (!empty($moreforfilter)) { print '
'; print $moreforfilter; print '
'; @@ -419,21 +397,18 @@ print ''; -foreach ($object->fields as $key => $val) -{ +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'])) - { + if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; } } @@ -455,15 +430,13 @@ print ''."\n"; // Fields title label // -------------------------------------------------------------------- print ''; -foreach ($object->fields as $key => $val) -{ +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'])) - { + 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"; } } @@ -480,10 +453,8 @@ 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 (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 } } @@ -493,8 +464,7 @@ if (is_array($extrafields->attributes[$object->table_element]['computed']) && co // -------------------------------------------------------------------- $i = 0; $totalarray = array(); -while ($i < ($limit ? min($num, $limit) : $num)) -{ +while ($i < ($limit ? min($num, $limit) : $num)) { $obj = $db->fetch_object($resql); if (empty($obj)) break; // Should not happen @@ -503,8 +473,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) // Show here line of result print ''; - foreach ($object->fields as $key => $val) - { + 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'; @@ -515,23 +484,21 @@ while ($i < ($limit ? min($num, $limit) : $num)) if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status') $cssforfield .= ($cssforfield ? ' ' : '').'right'; //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; - if (!empty($arrayfields['t.'.$key]['checked'])) - { + if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; if ($key == 'status') print $object->getLibStatut(5); else { print $object->showOutputField($val, $key, $object->$key, ''); - if($key === 'date_prevue_depart' && $object->lead_time_for_warning > 0 && $object->$key > 0) { + if ($key === 'date_prevue_depart' && $object->lead_time_for_warning > 0 && $object->$key > 0) { $date_prevue_depart = $object->$key; $date_prevue_depart_plus_delai = $date_prevue_depart; - if($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); - if($date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) print img_warning($langs->trans('Alert').' - '.$langs->trans('Late')); + if ($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); + if ($date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) print img_warning($langs->trans('Alert').' - '.$langs->trans('Late')); } } print ''; if (!$i) $totalarray['nbfield']++; - if (!empty($val['isameasure'])) - { + if (!empty($val['isameasure'])) { if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; $totalarray['val']['t.'.$key] += $object->$key; } @@ -545,8 +512,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) print $hookmanager->resPrint; // Action column print ''; @@ -582,8 +547,7 @@ print ''."\n"; print ''."\n"; -if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) -{ +if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) { $hidegeneratedfilelistifempty = 1; if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) $hidegeneratedfilelistifempty = 0; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_note.php b/htdocs/product/stock/stocktransfer/stocktransfer_note.php index 085914936b7..51ad1c32df3 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_note.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_note.php @@ -90,8 +90,7 @@ $form = new Form($db); $help_url = ''; llxHeader('', $langs->trans('ModuleStockTransferName'), $help_url); -if ($id > 0 || !empty($ref)) -{ +if ($id > 0 || !empty($ref)) { $object->fetch_thirdparty(); $head = stocktransferPrepareHead($object); From b7c552968533016c087b932a113dfa3fd482c992 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 30 Jul 2021 12:29:22 +0200 Subject: [PATCH 004/128] FIX : thirdparty and project in banner --- .../class/stocktransfer.class.php | 7 +- .../stocktransfer/stocktransfer_card.php | 66 +++++++++---------- .../stocktransfer/stocktransfer_list.php | 4 +- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 7faf8d7c530..dcdf46b75e6 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -101,7 +101,7 @@ class StockTransfer extends CommonObject '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'=>'minwidth200'/*, 'help'=>"Help text"*/, 'showoncombobox'=>'1',), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>3,), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>32, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'position'=>32, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1/*, 'help'=>"LinkToThirparty"*/,), 'fk_warehouse_source' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt source', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferSource',), 'fk_warehouse_destination' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt de destination', 'enabled'=>'1', 'position'=>51, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferDestination'), @@ -469,7 +469,10 @@ class StockTransfer extends CommonObject */ public function update(User $user, $notrigger = false) { - return $this->updateCommon($user, $notrigger); + $res = $this->updateCommon($user, $notrigger); + if($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty(); + if(empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty); + return $res; } /** diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index abc653d5e75..e16d2514661 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -577,42 +577,38 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $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) : ''); + if($conf->societe->enabled) { + // 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); + 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 .= ''; + } + } } - } else { - if (! empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref .= ': '.$proj->getNomUrl(); - } else { - $morehtmlref .= ''; - } - } - }*/ $morehtmlref .= '
'; @@ -629,6 +625,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //unset($object->fields['fk_project']); // Hide field already shown in banner //unset($object->fields['fk_soc']); // Hide field already shown in banner + $object->fields['fk_soc']['visible']=0; // Already available in banner + $object->fields['fk_project']['visible']=0; // Already available in banner include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; echo '
'; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_list.php b/htdocs/product/stock/stocktransfer/stocktransfer_list.php index 10532fe889c..15ce2790ca5 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_list.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_list.php @@ -60,6 +60,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.'/core/lib/functions.lib.php'; // load stocktransfer libraries require_once __DIR__.'/class/stocktransfer.class.php'; @@ -128,8 +129,9 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field - if (!empty($val['visible'])) $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']); + if (!empty($val['visible'])) $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>(verifCond($val['enabled']) && ($val['visible'] != 3)), 'position'=>$val['position']); } +//var_dump($object->fields); // Extra fields if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { From 3c717842723fd0a2f1546ae1367a7e81536e9ea0 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 30 Jul 2021 10:32:56 +0000 Subject: [PATCH 005/128] Fixing style errors. --- .../class/stocktransfer.class.php | 4 +- .../stocktransfer/stocktransfer_card.php | 56 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index e4754a1c301..f3a256d9532 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -453,8 +453,8 @@ class StockTransfer extends CommonObject public function update(User $user, $notrigger = false) { $res = $this->updateCommon($user, $notrigger); - if($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty(); - if(empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty); + if ($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty(); + if (empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty); return $res; } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index cf7f291ce18..e40d196dca0 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -561,38 +561,38 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; - if($conf->societe->enabled) { + if ($conf->societe->enabled) { // 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 .= ''; - } - } - } + 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 .= '
'; From 846f0366d3b8667da56fa4890f679098fe2cc086 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 30 Jul 2021 14:17:36 +0200 Subject: [PATCH 006/128] FIX : travis feedbacks --- htdocs/admin/stocktransfer.php | 10 ++-------- htdocs/core/modules/modStockTransfer.class.php | 6 +++++- .../stocktransfer/doc/pdf_eagle.modules.php | 6 ++++++ .../stocktransfer/class/stocktransfer.class.php | 12 ++++++++++++ .../class/stocktransferline.class.php | 8 ++++++++ .../stock/stocktransfer/stocktransfer_card.php | 16 ++++------------ .../stocktransfer/stocktransfer_contact.php | 10 ++-------- 7 files changed, 39 insertions(+), 29 deletions(-) diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index 2f5892dd1c0..64d759445bd 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -122,10 +122,7 @@ if ($action == 'updateMask') { setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); } -} - -// Activate a model -elseif ($action == 'set') { +} elseif ($action == 'set') { // Activate a model $ret = addDocumentModel($value, 'stocktransfer', $label, $scandir); } elseif ($action == 'del') { $tmpobjectkey = GETPOST('object'); @@ -135,10 +132,7 @@ elseif ($action == 'set') { $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity); } -} - -// Set default model -elseif ($action == 'setdoc') { +} elseif ($action == 'setdoc') { // Set default model $tmpobjectkey = GETPOST('object'); $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) { diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index d15e9797d13..c528f22b175 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -500,9 +500,12 @@ class modStockTransfer extends DolibarrModules return $this->_init($sql, $options); } + /** + * Returns next available id to insert new roles in llx_c_type_contact + * @return int > 0 if OK, < 0 if KO + */ function getNextId() { - global $db; // Get free id for insert @@ -514,6 +517,7 @@ class modStockTransfer extends DolibarrModules $newid = ($obj->newid + 1); } else { dol_print_error($db); + return -1; } return $newid; } diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 2bffdf68b2d..3f59e08bc80 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -824,6 +824,12 @@ class pdf_eagle extends ModelePdfStockTransfer }*/ } + /** + * Used to know if at least one line of Stock Transfer object has a batch set + * + * @param $object Stock Transfer object + * @return bool true if at least one line has batch set, false if not + */ function atLeastOneBatch($object) { diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index f3a256d9532..95c4f31b08a 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -347,6 +347,13 @@ class StockTransfer extends CommonObject return $result; } + /** + * Used to sort lines by rank + * + * @param $a 1st element to test + * @param $b 1st element to test + * @return int + */ function cmp($a, $b) { if ($a->rang == $b->rang) { @@ -355,6 +362,11 @@ class StockTransfer extends CommonObject return ($a->rang < $b->rang) ? -1 : 1; } + /** + * Used to get total PMP amount of all quantities of products of Stock Transfer + * + * @return float total amount of Stock Transfer + */ function getValorisationTotale() { diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 46aeba5980e..962186b5a13 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -435,6 +435,14 @@ class StockTransferLine extends CommonObject return $this->deleteLineCommon($user, $idline, $notrigger); } + /** + * Makes all stock movements (add quantity, remove quantity or cancel all actions) + * + * @param string $label label of stock movement + * @param int $fk_entrepot Warehouse concerned by stock movement + * @param int $direction add or remove qty + * @return int 1 if ok, <= 0 if ko + */ function doStockMovement($label, $fk_entrepot, $direction = 1) { diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index e40d196dca0..db746f4e581 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -494,30 +494,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // 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); - } - // Destock confirmation - elseif ($action == 'destock') { + } elseif ($action == 'destock') { // Destock confirmation // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1); - } - // Destock confirmation cancel - elseif ($action == 'destockcancel') { + } elseif ($action == 'destockcancel') { // Destock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1); - } - // Addstock confirmation - elseif ($action == 'addstock') { + } elseif ($action == 'addstock') { // Addstock confirmation // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1); - } - // Addstock confirmation cancel - elseif ($action == 'addstockcancel') { + } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40)); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php index 8e0eac4b4cb..97ac4c28a73 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php @@ -92,17 +92,11 @@ if ($action == 'addcontact' && $user->rights->stocktransfer->stocktransfer->writ setEventMessages($object->error, $object->errors, 'errors'); } } -} - -// Toggle the status of a contact -elseif ($action == 'swapstatut' && $user->rights->stocktransfer->stocktransfer->write) { +} elseif ($action == 'swapstatut' && $user->rights->stocktransfer->stocktransfer->write) { // Toggle the status of a contact if ($object->id > 0) { $result = $object->swapContactStatus(GETPOST('ligne')); } -} - -// Deletes a contact -elseif ($action == 'deletecontact' && $user->rights->stocktransfer->stocktransfer->write) { +} elseif ($action == 'deletecontact' && $user->rights->stocktransfer->stocktransfer->write) { // Deletes a contact $result = $object->delete_contact($lineid); if ($result >= 0) { From 142f93e50cb72f9e27929fd124eca8e8df025bac Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 30 Jul 2021 15:35:31 +0200 Subject: [PATCH 007/128] FIX : functions visibility --- htdocs/core/modules/modStockTransfer.class.php | 2 +- htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 2 +- .../product/stock/stocktransfer/class/stocktransfer.class.php | 4 ++-- .../stock/stocktransfer/class/stocktransferline.class.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index c528f22b175..86dc451cfac 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -504,7 +504,7 @@ class modStockTransfer extends DolibarrModules * Returns next available id to insert new roles in llx_c_type_contact * @return int > 0 if OK, < 0 if KO */ - function getNextId() + public function getNextId() { global $db; diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 3f59e08bc80..a5245b3bff5 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -830,7 +830,7 @@ class pdf_eagle extends ModelePdfStockTransfer * @param $object Stock Transfer object * @return bool true if at least one line has batch set, false if not */ - function atLeastOneBatch($object) + public function atLeastOneBatch($object) { $atLeastOneBatch = false; diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 95c4f31b08a..b6ccf3f9d8b 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -354,7 +354,7 @@ class StockTransfer extends CommonObject * @param $b 1st element to test * @return int */ - function cmp($a, $b) + public function cmp($a, $b) { if ($a->rang == $b->rang) { return 0; @@ -367,7 +367,7 @@ class StockTransfer extends CommonObject * * @return float total amount of Stock Transfer */ - function getValorisationTotale() + public function getValorisationTotale() { $total_pmp = 0; diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 962186b5a13..8a7432c4317 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -443,7 +443,7 @@ class StockTransferLine extends CommonObject * @param int $direction add or remove qty * @return int 1 if ok, <= 0 if ko */ - function doStockMovement($label, $fk_entrepot, $direction = 1) + public function doStockMovement($label, $fk_entrepot, $direction = 1) { global $db, $conf, $user, $langs; From 256c3863b870d7fc78c102d5754b16744c7b50b8 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 30 Jul 2021 17:01:54 +0200 Subject: [PATCH 008/128] FIX : travis feedbacks + debug conf page --- htdocs/admin/stocktransfer.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index 64d759445bd..7ca8ab641c6 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -89,7 +89,7 @@ if ($action == 'updateMask') { } } elseif ($action == 'specimen') { $modele = GETPOST('module', 'alpha'); - $tmpobjectkey = GETPOST('object'); + $tmpobjectkey = 'StockTransfer'; $tmpobject = new $tmpobjectkey($db); $tmpobject->initAsSpecimen(); @@ -98,7 +98,7 @@ if ($action == 'updateMask') { $file = ''; $classname = ''; $filefound = 0; $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); foreach ($dirmodels as $reldir) { - $file = dol_buildpath($reldir."core/modules/stocktransfer/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0); + $file = dol_buildpath($reldir."core/modules/stocktransfer/doc/pdf_".$modele.".modules.php", 0); if (file_exists($file)) { $filefound = 1; $classname = "pdf_".$modele; @@ -127,7 +127,7 @@ if ($action == 'updateMask') { } elseif ($action == 'del') { $tmpobjectkey = GETPOST('object'); - $ret = delDocumentModel($value, $type); + $ret = delDocumentModel($value, 'stocktransfer'); if ($ret > 0) { $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity); @@ -142,9 +142,9 @@ if ($action == 'updateMask') { } // On active le modele - $ret = delDocumentModel($value, $type); + $ret = delDocumentModel($value, 'stocktransfer'); if ($ret > 0) { - $ret = addDocumentModel($value, $type, $label, $scandir); + $ret = addDocumentModel($value, 'stocktransfer', $label, $scandir); } } elseif ($action == 'setmod') { // TODO Check if numbering module chosen can be activated @@ -349,7 +349,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $def = array(); $sql = "SELECT nom"; $sql .= " FROM ".MAIN_DB_PREFIX."document_model"; - $sql .= " WHERE type = '".$type."'"; + $sql .= " WHERE type = '".$db->escape($type)."'"; $sql .= " AND entity = ".$conf->entity; $resql = $db->query($sql); if ($resql) { @@ -426,11 +426,11 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print '
'; From 1c2ed1b22f61da1eed6fcb2073b80a1c2644b5ac Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 2 Aug 2021 10:00:53 +0200 Subject: [PATCH 009/128] FIX : column titles truncated --- htdocs/product/stock/stocktransfer/stocktransfer_card.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index db746f4e581..4fbeeb60c9c 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -199,12 +199,12 @@ if (empty($reshook)) { if (empty($batch)) { $error++; $langs->load("errors"); - setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); + setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->getNomUrl()), null, 'errors'); } } else { if (!empty($batch)) { $error++; - setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); + setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); } } @@ -688,6 +688,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $param = ''; + $conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE=true; // Full display needed to see all column title details + print ''; print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); if ($conf->productbatch->enabled) { @@ -697,7 +699,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); - print getTitleFieldOfList($langs->trans('PMPValue'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); + print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); if (empty($object->status)) { print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); From b83b77beb5615e3121eaa92c5bb9798569da756c Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 2 Aug 2021 17:28:41 +0200 Subject: [PATCH 010/128] NEW : stock transfer sheet proforma + default model system like cmd invoice, etc... --- htdocs/admin/stocktransfer.php | 6 +- .../doc/pdf_eagle_proforma.modules.php | 1753 +++++++++++++++++ .../install/mysql/migration/14.0.0-15.0.0.sql | 1 + .../llx_stocktransfer_stocktransfer.sql | 1 + htdocs/langs/en_US/stocks.lang | 1 + htdocs/langs/fr_FR/stocks.lang | 1 + .../class/stocktransfer.class.php | 2 + .../stocktransfer/stocktransfer_card.php | 11 + 8 files changed, 1773 insertions(+), 3 deletions(-) create mode 100644 htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index 7ca8ab641c6..e0ce72eeb25 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -125,7 +125,7 @@ if ($action == 'updateMask') { } elseif ($action == 'set') { // Activate a model $ret = addDocumentModel($value, 'stocktransfer', $label, $scandir); } elseif ($action == 'del') { - $tmpobjectkey = GETPOST('object'); + $tmpobjectkey = 'StockTransfer'; $ret = delDocumentModel($value, 'stocktransfer'); if ($ret > 0) { @@ -133,7 +133,7 @@ if ($action == 'updateMask') { if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity); } } elseif ($action == 'setdoc') { // Set default model - $tmpobjectkey = GETPOST('object'); + $tmpobjectkey = 'StockTransfer'; $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 @@ -149,7 +149,7 @@ if ($action == 'updateMask') { } elseif ($action == 'setmod') { // TODO Check if numbering module chosen can be activated // by calling method canBeActivated - $tmpobjectkey = GETPOST('object'); + $tmpobjectkey = 'StockTransfer'; $constforval = 'STOCKTRANSFER_'.strtoupper($tmpobjectkey)."_ADDON"; dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity); } diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php new file mode 100644 index 00000000000..4bce13e949a --- /dev/null +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -0,0 +1,1753 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2013 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018-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/commande/doc/pdf_eratosthene.modules.php + * \ingroup commande + * \brief File of Class to generate PDF orders with template Eratosthène + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; + + +/** + * Class to generate PDF orders with template Eratosthene + */ +class pdf_eagle_proforma extends ModelePDFCommandes +{ + /** + * @var DoliDb Database handler + */ + public $db; + + /** + * @var string model name + */ + public $name; + + /** + * @var string model description (short text) + */ + public $description; + + /** + * @var int Save the name of generated file as the main doc when generating a doc with this template + */ + public $update_main_doc_field; + + /** + * @var string document type + */ + public $type; + + /** + * @var array Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.5 = array(5, 5) + */ + public $phpmin = array(5, 5); + + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; + + /** + * @var int page_largeur + */ + public $page_largeur; + + /** + * @var int page_hauteur + */ + public $page_hauteur; + + /** + * @var array format + */ + public $format; + + /** + * @var int marge_gauche + */ + public $marge_gauche; + + /** + * @var int marge_droite + */ + public $marge_droite; + + /** + * @var int marge_haute + */ + public $marge_haute; + + /** + * @var int marge_basse + */ + public $marge_basse; + + /** + * Issuer + * @var Societe Object that emits + */ + public $emetteur; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf, $langs, $mysoc; + + // Translations + $langs->loadLangs(array("main", "bills", "products")); + + $this->db = $db; + $this->name = $langs->trans("StockTransferSheetProforma"); + $this->description = $langs->trans('StockTransferSheetProforma'); + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + + // Dimension page + $this->type = 'pdf'; + $formatarray = pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur, $this->page_hauteur); + $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10; + $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10; + $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10; + $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10; + + $this->option_logo = 1; // Display logo + $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION + $this->option_modereg = 1; // Display payment mode + $this->option_condreg = 1; // Display payment terms + $this->option_codeproduitservice = 1; // Display product-service code + $this->option_multilang = 1; // Available in several languages + $this->option_escompte = 0; // Displays if there has been a discount + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 1; // Support add of a watermark on drafts + + // Get source company + $this->emetteur = $mysoc; + if (empty($this->emetteur->country_code)) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined + + // Define position of columns + $this->posxdesc = $this->marge_gauche + 1; + + + $this->tabTitleHeight = 5; // default height + + $this->tva = array(); + $this->localtax1 = array(); + $this->localtax2 = array(); + $this->atleastoneratenotnull = 0; + $this->atleastonediscount = 0; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + // phpcs:enable + global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines; + + if (!is_object($outputlangs)) $outputlangs = $langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (!empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output = 'ISO-8859-1'; + + // Load translation files required by the page + $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries")); + + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) { + global $outputlangsbis; + $outputlangsbis = new Translate('', $conf); + $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE); + $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries")); + } + + $nblines = count($object->lines); + + $hidetop = 0; + if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) { + $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE; + } + + // Loop on each lines to detect if there is at least one image to show + $realpatharray = array(); + $this->atleastonephoto = false; + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) + { + $objphoto = new Product($this->db); + + for ($i = 0; $i < $nblines; $i++) + { + if (empty($object->lines[$i]->fk_product)) continue; + + $objphoto->fetch($object->lines[$i]->fk_product); + //var_dump($objphoto->ref);exit; + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; + $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; + } + else + { + $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default + $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative + } + + $arephoto = false; + foreach ($pdir as $midir) + { + if (!$arephoto) + { + $dir = $conf->product->dir_output.'/'.$midir; + + foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) + { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + { + if ($obj['photo_vignette']) + { + $filename = $obj['photo_vignette']; + } + else + { + $filename = $obj['photo']; + } + } + else + { + $filename = $obj['photo']; + } + + $realpath = $dir.$filename; + $arephoto = true; + $this->atleastonephoto = true; + } + } + } + + if ($realpath && $arephoto) $realpatharray[$i] = $realpath; + } + } + + + + if ($conf->stocktransfer->dir_output) + { + $object->fetch_thirdparty(); + + $deja_regle = 0; + + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->stocktransfer->multidir_output[$conf->entity]; + $file = $dir."/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->stocktransfer->multidir_output[$conf->entity]."/".$object->element."/".$objectref; + $file = $dir."/".$objectref.".pdf"; + } + + if (!file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (!is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + + // Create pdf instance + $pdf = pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance + $pdf->SetAutoPageBreak(1, 0); + + $heightforinfotot = 40; // Height reserved to output the info and total part + $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin) + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + // Set path to the background PDF File + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb = 0; + $pdf->SetDrawColor(128, 128, 128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("PdfOrderTitle")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfOrderTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + /// Does we have at least one line with discount $this->atleastonediscount + foreach ($object->lines as $line) { + if ($line->remise_percent) { + $this->atleastonediscount = true; + break; + } + } + + + // New page + $pdf->AddPage(); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0, 0, 0); + + + $tab_top = 90 + $top_shift; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10); + + // Incoterm + if ($conf->incoterm->enabled) + { + $desc_incoterms = $object->getIncotermsForPDF(); + if ($desc_incoterms) + { + $tab_top -= 2; + + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1); + $nexY = $pdf->GetY(); + $height_incoterms = $nexY - $tab_top; + + // Rect takes a length in 3rd parameter + $pdf->SetDrawColor(192, 192, 192); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1); + + $tab_top = $nexY + 6; + } + } + + // Displays notes + $notetoshow = empty($object->note_public) ? '' : $object->note_public; + if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) + { + // Get first sale rep + if (is_object($object->thirdparty)) + { + $salereparray = $object->thirdparty->getSalesRepresentatives($user); + $salerepobj = new User($this->db); + $salerepobj->fetch($salereparray[0]['id']); + if (!empty($salerepobj->signature)) $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature); + } + } + + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + + $pagenb = $pdf->getPage(); + if ($notetoshow) + { + $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite; + $pageposbeforenote = $pagenb; + + $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); + $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow); + + $tab_top -= 2; + + $pdf->startTransaction(); + + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + // Description + $pageposafternote = $pdf->getPage(); + $posyafter = $pdf->GetY(); + + if ($pageposafternote > $pageposbeforenote) + { + $pdf->rollbackTransaction(true); + + // prepare pages to receive notes + while ($pagenb < $pageposafternote) { + $pdf->AddPage(); + $pagenb++; + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + // $this->_pagefoot($pdf,$object,$outputlangs,1); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + } + + // back to start + $pdf->setPage($pageposbeforenote); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + $pageposafternote = $pdf->getPage(); + + $posyafter = $pdf->GetY(); + + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) // There is no space left for total+free text + { + $pdf->AddPage('', '', true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + //$posyafter = $tab_top_newpage; + } + + + // apply note frame to previous pages + $i = $pageposbeforenote; + while ($i < $pageposafternote) { + $pdf->setPage($i); + + + $pdf->SetDrawColor(128, 128, 128); + // Draw note frame + if ($i > $pageposbeforenote) { + $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); + } + else { + $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + } + + // Add footer + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $this->_pagefoot($pdf, $object, $outputlangs, 1); + + $i++; + } + + // apply note frame to last page + $pdf->setPage($pageposafternote); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $height_note = $posyafter - $tab_top_newpage; + $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); + } + else // No pagebreak + { + $pdf->commitTransaction(); + $posyafter = $pdf->GetY(); + $height_note = $posyafter - $tab_top; + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + + + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) + { + // not enough space, need to add page + $pdf->AddPage('', '', true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + + $posyafter = $tab_top_newpage; + } + } + + $tab_height = $tab_height - $height_note; + $tab_top = $posyafter + 6; + } + else + { + $height_note = 0; + } + + + // Use new auto column system + $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); + + // tab simulation to know line height + $pdf->startTransaction(); + $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); + $pdf->rollbackTransaction(true); + + $nexY = $tab_top + $this->tabTitleHeight; + + // Loop on each lines + $pageposbeforeprintlines = $pdf->getPage(); + $pagenb = $pageposbeforeprintlines; + for ($i = 0; $i < $nblines; $i++) + { + $curY = $nexY; + $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0, 0, 0); + + // Define size of image if we need it + $imglinesize = array(); + if (!empty($realpatharray[$i])) $imglinesize = pdf_getSizeForImage($realpatharray[$i]); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore = $pdf->getPage(); + + + $showpricebeforepagebreak = 1; + $posYAfterImage = 0; + + if ($this->getColumnStatus('photo')) + { + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page + { + $pdf->AddPage('', '', true); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pdf->setPage($pageposbefore + 1); + + $curY = $tab_top_newpage; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; + } + + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) + { + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage = $curY + $imglinesize['height']; + } + } + + if ($this->getColumnStatus('desc')) + { + $pdf->startTransaction(); + + if(method_exists($object->lines[$i], 'fetch_product')) { + $object->lines[$i]->fetch_product(); + $object->lines[$i]->label = $object->lines[$i]->product->label; + $object->lines[$i]->description = $object->lines[$i]->product->description; + } + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + + $pageposafter = $pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter = $pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + $pageposafter = $pdf->getPage(); + $posyafter = $pdf->GetY(); + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page + { + $pdf->AddPage('', '', true); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + //if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pageposafter + 1); + } + } + else + { + // We found a page break + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + } + + + + $nexY = max($pdf->GetY(), $posYAfterImage); + + + $pageposafter = $pdf->getPage(); + + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description is moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font + + // VAT Rate + if ($this->getColumnStatus('vat')) + { + $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); + $nexY = max($pdf->GetY(), $nexY); + } + + // Unit price before discount + if ($this->getColumnStatus('subprice')) + { + $pmp = $object->lines[$i]->pmp; + $this->printStdColumnContent($pdf, $curY, 'subprice', price($pmp)); + $nexY = max($pdf->GetY(), $nexY); + } + + // Quantity + // Enough for 6 chars + if ($this->getColumnStatus('qty')) + { + $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'qty', $qty); + $nexY = max($pdf->GetY(), $nexY); + } + + + // Unit + if ($this->getColumnStatus('unit')) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $this->printStdColumnContent($pdf, $curY, 'unit', $unit); + $nexY = max($pdf->GetY(), $nexY); + } + + // Discount on line + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) + { + $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); + $nexY = max($pdf->GetY(), $nexY); + } + + // Total HT line + if ($this->getColumnStatus('totalexcltax')) + { + $pmp_qty = $pmp * $object->lines[$i]->qty; + $this->printStdColumnContent($pdf, $curY, 'totalexcltax', price($pmp_qty)); + $nexY = max($pdf->GetY(), $nexY); + } + + // Extrafields + if (!empty($object->lines[$i]->array_options)) { + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) { + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } + + $parameters = array( + 'object' => $object, + 'i' => $i, + 'pdf' =>& $pdf, + 'curY' =>& $curY, + 'nexY' =>& $nexY, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails + ); + $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook + + + // Collection of totals by value of vat in $this->tva["rate"] = total_tva + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $object->lines[$i]->multicurrency_total_tva; + else $tvaligne = $object->lines[$i]->total_tva; + + $localtax1ligne = $object->lines[$i]->total_localtax1; + $localtax2ligne = $object->lines[$i]->total_localtax2; + $localtax1_rate = $object->lines[$i]->localtax1_tx; + $localtax2_rate = $object->lines[$i]->localtax2_tx; + $localtax1_type = $object->lines[$i]->localtax1_type; + $localtax2_type = $object->lines[$i]->localtax2_type; + + if ($object->remise_percent) $tvaligne -= ($tvaligne * $object->remise_percent) / 100; + if ($object->remise_percent) $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100; + if ($object->remise_percent) $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100; + + $vatrate = (string) $object->lines[$i]->tva_tx; + + // Retrieve type from database for backward compatibility with old records + if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined + && (!empty($localtax1_rate) || !empty($localtax2_rate))) // and there is local tax + { + $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); + $localtax1_type = $localtaxtmp_array[0]; + $localtax2_type = $localtaxtmp_array[2]; + } + + // retrieve global local tax + if ($localtax1_type && $localtax1ligne != 0) + $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne; + if ($localtax2_type && $localtax2ligne != 0) + $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne; + + if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate .= '*'; + if (!isset($this->tva[$vatrate])) $this->tva[$vatrate] = 0; + $this->tva[$vatrate] += $tvaligne; + + // Add line + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) + { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); + $pdf->SetLineStyle(array('dash'=>0)); + } + + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) + { + $pdf->setPage($pagenb); + if ($pagenb == $pageposbeforeprintlines) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) + { + if ($pagenb == $pageposafter) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + // New page + $pdf->AddPage(); + if (!empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + + // Show square + if ($pagenb == $pageposbeforeprintlines) + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code); + else + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + + // Affiche zone infos + $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs); + + // Affiche zone totaux + $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); + + // Affiche zone versements + /* + if ($deja_regle) + { + $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs); + } + */ + + // Pied de page + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file, 'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) + { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + } + + if (!empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $this->result = array('fullpath'=>$file); + + return 1; // No error + } + else + { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } + else + { + $this->error = $langs->transnoentities("ErrorConstantNotDefined", "STOCKTRANSFER_OUTPUTDIR"); + return 0; + } + } + + /** + * Show payments table + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object order + * @param int $posy Position y in PDF + * @param Translate $outputlangs Object langs for output + * @return int <0 if KO, >0 if OK + */ + protected function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs) + { + } + + /** + * Show miscellaneous information (payment mode, payment term, ...) + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object to show + * @param int $posy Y + * @param Translate $outputlangs Langs object + * @return int Pos y + */ + protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs) + { + global $conf, $mysoc; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $pdf->SetFont('', '', $default_font_size - 1); + + // If France, show VAT mention if not applicable + if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) + { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + + $posy = $pdf->GetY() + 4; + } + + $posxval = 52; + + // Show payments conditions + if ($object->cond_reglement_code || $object->cond_reglement) + { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentConditions").':'; + $pdf->MultiCell(43, 4, $titre, 0, 'L'); + + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc); + $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); + $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L'); + + $posy = $pdf->GetY() + 3; + } + + // Check a payment mode is defined + /* Not used with orders + if (empty($object->mode_reglement_code) + && ! $conf->global->FACTURE_CHQ_NUMBER + && ! $conf->global->FACTURE_RIB_NUMBER) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0); + $pdf->SetTextColor(0,0,0); + + $posy=$pdf->GetY()+1; + } + */ + /* TODO + else if (! empty($object->availability_code)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); + $pdf->SetTextColor(0,0,0); + + $posy=$pdf->GetY()+1; + }*/ + + // Show planed date of delivery + if (!empty($object->date_livraison)) + { + $outputlangs->load("sendings"); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':'; + $pdf->MultiCell(80, 4, $titre, 0, 'L'); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $dlp = dol_print_date($object->date_livraison, "daytext", false, $outputlangs, true); + $pdf->MultiCell(80, 4, $dlp, 0, 'L'); + + $posy = $pdf->GetY() + 1; + } + elseif ($object->availability_code || $object->availability) // Show availability conditions + { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("AvailabilityPeriod").':'; + $pdf->MultiCell(80, 4, $titre, 0, 'L'); + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_availability = $outputlangs->transnoentities("AvailabilityType".$object->availability_code) != ('AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset(isset($object->availability) ? $object->availability : ''); + $lib_availability = str_replace('\n', "\n", $lib_availability); + $pdf->MultiCell(80, 4, $lib_availability, 0, 'L'); + + $posy = $pdf->GetY() + 1; + } + + // Show payment mode + if ($object->mode_reglement_code + && $object->mode_reglement_code != 'CHQ' + && $object->mode_reglement_code != 'VIR') { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentMode").':'; + $pdf->MultiCell(80, 5, $titre, 0, 'L'); + + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); + $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L'); + + $posy = $pdf->GetY() + 2; + } + + // Show payment mode CHQ + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') + { + // Si mode reglement non force ou si force a CHQ + if (!empty($conf->global->FACTURE_CHQ_NUMBER)) + { + if ($conf->global->FACTURE_CHQ_NUMBER > 0) + { + $account = new Account($this->db); + $account->fetch($conf->global->FACTURE_CHQ_NUMBER); + + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('', 'B', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); + $posy = $pdf->GetY() + 1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('', '', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); + $posy = $pdf->GetY() + 2; + } + } + if ($conf->global->FACTURE_CHQ_NUMBER == -1) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('', 'B', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); + $posy = $pdf->GetY() + 1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('', '', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); + $posy = $pdf->GetY() + 2; + } + } + } + } + + // If payment mode not forced or forced to VIR, show payment with BAN + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') + { + if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) + { + $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); + if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank + $account = new Account($this->db); + $account->fetch($bankid); + + $curx = $this->marge_gauche; + $cury = $posy; + + $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size); + + $posy += 2; + } + } + + return $posy; + } + + + /** + * Show total to pay + * + * @param TCPDF $pdf Object PDF + * @param Facture $object Object invoice + * @param int $deja_regle Montant deja regle + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs) + { + global $conf, $mysoc; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $tab2_top = $posy; + $tab2_hl = 4; + $pdf->SetFont('', '', $default_font_size - 1); + + // Tableau total + $col1x = 120; $col2x = 170; + if ($this->page_largeur < 210) // To work with US executive format + { + $col2x -= 20; + } + $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); + $useborder = 0; + $index = 0; + + $outputlangsbis = null; + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) { + $outputlangsbis = new Translate('', $conf); + $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE); + $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal")); + } + + // Total HT + /*$pdf->SetFillColor(255, 255, 255); + $pdf->SetXY($col1x, $tab2_top + 0); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1); + $total_ht = (($conf->multicurrency->enabled && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht); + $pdf->SetXY($col2x, $tab2_top + 0); + $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1);*/ + + // Show VAT by rates and total + $pdf->SetFillColor(248, 248, 248); + + $total_ttc = $object->getValorisationTotale(); + + $this->atleastoneratenotnull = 0; + + // Total TTC + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFillColor(224, 224, 224); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalTTC", $mysoc->country_code) : ''), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1); + + $pdf->SetTextColor(0, 0, 0); + + $creditnoteamount = 0; + $depositsamount = 0; + //$creditnoteamount=$object->getSumCreditNotesUsed(); + //$depositsamount=$object->getSumDepositsUsed(); + //print "x".$creditnoteamount."-".$depositsamount;exit; + $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'); + if (!empty($object->paye)) $resteapayer = 0; + + if ($deja_regle > 0) + { + // Already paid + Deposits + $index++; + + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), 0, 'L', 0); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0); + + $index++; + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFillColor(224, 224, 224); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1); + + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->SetTextColor(0, 0, 0); + } + + $index++; + return ($tab2_top + ($tab2_hl * $index)); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show table for lines + * + * @param TCPDF $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y (not used) + * @param Translate $outputlangs Langs object + * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title + * @param int $hidebottom Hide bottom bar of array + * @param string $currency Currency code + * @return void + */ + protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '') + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom = 0; + if ($hidetop) $hidetop = -1; + + $currency = !empty($currency) ? $currency : $conf->currency; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + + if (empty($hidetop)) + { + $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; + if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) { + $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)); + } + } + + $pdf->SetDrawColor(128, 128, 128); + $pdf->SetFont('', '', $default_font_size - 1); + + // Output Rect + $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter + + + $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); + + if (empty($hidetop)) { + $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show top header of page. + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @param string $titlekey Translation key to show as title of document + * @return int Return topshift value + */ + protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey = "StockTransferSheetProforma") + { + // phpcs:enable + global $conf, $langs, $hookmanager; + + // Load traductions files required by page + $outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies")); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); + + // Show Draft Watermark + if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) + { + pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->COMMANDE_DRAFT_WATERMARK); + } + + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFont('', 'B', $default_font_size + 3); + + $posy = $this->marge_haute; + $posx = $this->page_largeur - $this->marge_droite - 100; + + $pdf->SetXY($this->marge_gauche, $posy); + + // Logo + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) + { + if ($this->emetteur->logo) + { + $logodir = $conf->mycompany->dir_output; + if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity]; + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) + { + $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; + } + else { + $logo = $logodir.'/logos/'.$this->emetteur->logo; + } + if (is_readable($logo)) + { + $height = pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } + else + { + $text = $this->emetteur->name; + $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + } + + $pdf->SetFont('', 'B', $default_font_size + 3); + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $title = $outputlangs->transnoentities($titlekey); + $pdf->MultiCell(100, 3, $title, '', 'R'); + + $pdf->SetFont('', 'B', $default_font_size); + + $posy += 5; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); + + $posy += 1; + $pdf->SetFont('', '', $default_font_size - 1); + + // Date prévue depart + if (!empty($object->date_prevue_depart)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DatePrevueDepart")." : ".dol_print_date($object->date_prevue_depart, "day", false, $outputlangs, true), '', 'R'); + } + + // Date prévue arrivée + if (!empty($object->date_prevue_arrivee)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DatePrevueArrivee")." : ".dol_print_date($object->date_prevue_arrivee, "day", false, $outputlangs, true), '', 'R'); + } + + // Date reelle depart + if (!empty($object->date_reelle_depart)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleDepart")." : ".dol_print_date($object->date_reelle_depart, "day", false, $outputlangs, true), '', 'R'); + } + + // Date reelle arrivée + if (!empty($object->date_reelle_arrivee)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); + } + + if ($object->ref_client) + { + $posy += 5; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); + } + + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R'); + } + } + + if (!empty($conf->global->PDF_SHOW_PROJECT)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R'); + } + } + + if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) + { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); + } + + // Get contact + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) + { + $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $usertmp = new User($this->db); + $usertmp->fetch($arrayidcontact[0]); + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R'); + } + } + + $posy += 2; + + $top_shift = 0; + // Show list of linked objects + $current_y = $pdf->getY(); + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); + if ($current_y < $pdf->getY()) + { + $top_shift = $pdf->getY() - $current_y; + } + + if ($showaddress) + { + // Sender properties + $carac_emetteur = ''; + // Add internal contact of origin element if defined + $arrayidcontact = array(); + $arrayidcontact = $object->getIdContact('external', 'STFROM'); + + $usecontact = false; + if (count($arrayidcontact) > 0) + { + /*$object->fetch_user(reset($arrayidcontact)); + $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ + $usecontact = true; + $result = $object->fetch_contact($arrayidcontact[0]); + } + + if ($usecontact) $thirdparty = $object->contact; + else $thirdparty = $this->emetteur; + + if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + + if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); + + // Show sender + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posx = $this->marge_gauche; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->page_largeur - $this->marge_droite - 80; + + $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40; + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82; + + // Show sender frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx, $posy - 5); + $pdf->MultiCell(66, 5, $outputlangs->transnoentities("Sender").":", 0, 'L'); + $pdf->SetXY($posx, $posy); + $pdf->SetFillColor(230, 230, 230); + $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFillColor(255, 255, 255); + + // Show sender name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($carac_emetteur_name), 0, 'L'); + $posy = $pdf->getY(); + + // Show sender information + $pdf->SetXY($posx + 2, $posy); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L'); + + + // If SHIPPING contact defined, we use it + $usecontact = false; + $arrayidcontact = $object->getIdContact('external', 'STDEST'); + if (count($arrayidcontact) > 0) + { + $usecontact = true; + $result = $object->fetch_contact($arrayidcontact[0]); + } + + //Recipient name + // On peut utiliser le nom de la societe du contact + if ($usecontact/* && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)*/) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); + + // Show recipient + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100; + if ($this->page_largeur < 210) $widthrecbox = 84; // To work with US executive format + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posx = $this->page_largeur - $this->marge_droite - $widthrecbox; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->marge_gauche; + + // Show recipient frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx + 2, $posy - 5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("Recipient").":", 0, 'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->SetXY($posx + 2, $posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0, 0, 0); + return $top_shift; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show footer of page. Need this->emetteur object + * + * @param TCPDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0) + { + // phpcs:enable + global $conf; + $showdetails = $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf, $outputlangs, 'ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext); + } + + + + /** + * Define Array Column Field + * + * @param object $object common object + * @param Translate $outputlangs langs + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return null + */ + public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + global $conf, $hookmanager; + + // Default field style for content + $this->defaultContentsFieldsStyle = array( + 'align' => 'R', // R,C,L + 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + // Default field style for content + $this->defaultTitlesFieldsStyle = array( + 'align' => 'C', // R,C,L + 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + /* + * For exemple + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ + + $rank = 0; // do not use negative rank + $this->cols['desc'] = array( + 'rank' => $rank, + 'width' => false, // only for desc + 'status' => true, + 'title' => array( + 'textkey' => 'Designation', // use lang key is usefull in somme case with module + 'align' => 'L', + // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + // 'label' => ' ', // the final label + 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', + 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + + $rank = $rank + 10; + $this->cols['photo'] = array( + 'rank' => $rank, + 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Photo', + 'label' => ' ' + ), + 'content' => array( + 'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'border-left' => false, // remove left line separator + ); + + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) + { + $this->cols['photo']['status'] = true; + } + + + $rank = $rank + 10; + $this->cols['vat'] = array( + 'rank' => $rank, + 'status' => false, + 'width' => 16, // in mm + 'title' => array( + 'textkey' => 'VAT' + ), + 'border-left' => true, // add left line separator + ); + + /*if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) + { + $this->cols['vat']['status'] = true; + }*/ + + $rank = $rank + 10; + $this->cols['subprice'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'PriceUHT' + ), + 'border-left' => true, // add left line separator + ); + + // Adapt dynamically the width of subprice, if text is too long. + $tmpwidth = 0; + $nblines = count($object->lines); + for ($i = 0; $i < $nblines; $i++) { + $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails))); + $tmpwidth = max($tmpwidth, $tmpwidth2); + } + if ($tmpwidth > 10) { + $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10)); + } + + $rank = $rank + 10; + $this->cols['qty'] = array( + 'rank' => $rank, + 'width' => 16, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'Qty' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['unit'] = array( + 'rank' => $rank, + 'width' => 11, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Unit' + ), + 'border-left' => true, // add left line separator + ); + if ($conf->global->PRODUCT_USE_UNITS) { + $this->cols['unit']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['discount'] = array( + 'rank' => $rank, + 'width' => 13, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'ReductionShort' + ), + 'border-left' => true, // add left line separator + ); + if ($this->atleastonediscount) { + $this->cols['discount']['status'] = true; + } + + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 + $this->cols['totalexcltax'] = array( + 'rank' => $rank, + 'width' => 26, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'TotalHT' + ), + 'border-left' => true, // add left line separator + ); + + // Add extrafields cols + if (!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } + + $parameters = array( + 'object' => $object, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails, + 'hidedesc' => $hidedesc, + 'hideref' => $hideref + ); + + $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook + if ($reshook < 0) + { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + elseif (empty($reshook)) + { + $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys + } + else + { + $this->cols = $hookmanager->resArray; + } + } +} diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 9b285f99a10..d0bcd17acd1 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -65,6 +65,7 @@ CREATE TABLE llx_stocktransfer_stocktransfer( fk_user_modif integer, import_key varchar(14), model_pdf varchar(255), + last_main_doc varchar(255), status smallint NOT NULL -- END MODULEBUILDER FIELDS ) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql index 31bd144ef5e..6b0607d66c2 100644 --- a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql @@ -38,6 +38,7 @@ CREATE TABLE llx_stocktransfer_stocktransfer( fk_user_modif integer, import_key varchar(14), model_pdf varchar(255), + last_main_doc varchar(255), status smallint NOT NULL -- END MODULEBUILDER FIELDS ) ENGINE=innodb; diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 63f6b5b082f..f396c31d0ed 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -286,6 +286,7 @@ TypeContact_stocktransfer_internal_STFROM=Sender of stocks transfer TypeContact_stocktransfer_internal_STDEST=Recipient of stocks transfer TypeContact_stocktransfer_internal_STRESP=Responsible of stocks transfer StockTransferSheet=Stocks transfer sheet +StockTransferSheetProforma=Proforma stocks transfer sheet StockTransferDecrementation=Decrease source warehouses StockTransferIncrementation=Increase destination warehouses StockTransferDecrementationCancel=Cancel decrease of source warehouses diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index d832b160d02..84686cd675a 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -281,6 +281,7 @@ TypeContact_stocktransfer_internal_STFROM=Contact expéditeur transfert de stock TypeContact_stocktransfer_internal_STDEST=Contact destinataire transfert de stocks TypeContact_stocktransfer_internal_STRESP=Responsable du transfert de stocks StockTransferSheet=Bon de transfert +StockTransferSheetProforma=Bon de transfert proforma StockTransferDecrementation=Décrémenter les entrepôts sources StockTransferIncrementation=Incrémenter les entrepôts de destination StockTransferDecrementationCancel=Annuler décrémentation des entrepôts sources diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index b6ccf3f9d8b..69128a65b93 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -223,6 +223,8 @@ class StockTransfer extends CommonObject */ public function create(User $user, $notrigger = false) { + $model_pdf = GETPOST('model'); + if(!empty($model_pdf)) $this->model_pdf = $model_pdf; $this->status = (int) $this->status; if ($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0; if ($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 4fbeeb60c9c..a1c1cd930cd 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -66,6 +66,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/stocktransfer/modules_stocktransfer.php'; // Load translation files required by the page $langs->loadLangs(array("stocks", "other", "productbatch", "companies")); @@ -420,6 +421,16 @@ if ($action == 'create') { // Common attributes include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; + // Template to use by default + print ''; + print '"; + // Other attributes include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; From 042e2f989303a742f1f7b6cd8f5f153b60feb40e Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 2 Aug 2021 15:31:24 +0000 Subject: [PATCH 011/128] Fixing style errors. --- .../doc/pdf_eagle_proforma.modules.php | 353 ++++++------------ .../class/stocktransfer.class.php | 2 +- 2 files changed, 117 insertions(+), 238 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php index 4bce13e949a..7f9feb7eafe 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -218,49 +218,35 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); $this->atleastonephoto = false; - if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) - { + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) { $objphoto = new Product($this->db); - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { if (empty($object->lines[$i]->fk_product)) continue; $objphoto->fetch($object->lines[$i]->fk_product); //var_dump($objphoto->ref);exit; - if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) - { + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; - } - else - { + } else { $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative } $arephoto = false; - foreach ($pdir as $midir) - { - if (!$arephoto) - { + foreach ($pdir as $midir) { + if (!$arephoto) { $dir = $conf->product->dir_output.'/'.$midir; - foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) - { - if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo - { - if ($obj['photo_vignette']) - { + foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + if ($obj['photo_vignette']) { $filename = $obj['photo_vignette']; - } - else - { + } else { $filename = $obj['photo']; } - } - else - { + } else { $filename = $obj['photo']; } @@ -277,39 +263,31 @@ class pdf_eagle_proforma extends ModelePDFCommandes - if ($conf->stocktransfer->dir_output) - { + if ($conf->stocktransfer->dir_output) { $object->fetch_thirdparty(); $deja_regle = 0; // Definition of $dir and $file - if ($object->specimen) - { + if ($object->specimen) { $dir = $conf->stocktransfer->multidir_output[$conf->entity]; $file = $dir."/SPECIMEN.pdf"; - } - else - { + } else { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->stocktransfer->multidir_output[$conf->entity]."/".$object->element."/".$objectref; $file = $dir."/".$objectref.".pdf"; } - if (!file_exists($dir)) - { - if (dol_mkdir($dir) < 0) - { + if (!file_exists($dir)) { + if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } - if (file_exists($dir)) - { + if (file_exists($dir)) { // Add pdfgeneration hook - if (!is_object($hookmanager)) - { + if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } @@ -327,15 +305,13 @@ class pdf_eagle_proforma extends ModelePDFCommandes $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin) - if (class_exists('TCPDF')) - { + if (class_exists('TCPDF')) { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File - if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) - { + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } @@ -376,11 +352,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10); // Incoterm - if ($conf->incoterm->enabled) - { + if ($conf->incoterm->enabled) { $desc_incoterms = $object->getIncotermsForPDF(); - if ($desc_incoterms) - { + if ($desc_incoterms) { $tab_top -= 2; $pdf->SetFont('', '', $default_font_size - 1); @@ -398,11 +372,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Displays notes $notetoshow = empty($object->note_public) ? '' : $object->note_public; - if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) - { + if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) { // Get first sale rep - if (is_object($object->thirdparty)) - { + if (is_object($object->thirdparty)) { $salereparray = $object->thirdparty->getSalesRepresentatives($user); $salerepobj = new User($this->db); $salerepobj->fetch($salereparray[0]['id']); @@ -412,14 +384,12 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Extrafields in note $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); - if (!empty($extranote)) - { + if (!empty($extranote)) { $notetoshow = dol_concatdesc($notetoshow, $extranote); } $pagenb = $pdf->getPage(); - if ($notetoshow) - { + if ($notetoshow) { $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite; $pageposbeforenote = $pagenb; @@ -438,8 +408,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pageposafternote = $pdf->getPage(); $posyafter = $pdf->GetY(); - if ($pageposafternote > $pageposbeforenote) - { + if ($pageposafternote > $pageposbeforenote) { $pdf->rollbackTransaction(true); // prepare pages to receive notes @@ -463,8 +432,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $posyafter = $pdf->GetY(); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) // There is no space left for total+free text - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text $pdf->AddPage('', '', true); $pagenb++; $pageposafternote++; @@ -487,8 +455,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes if ($i > $pageposbeforenote) { $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); - } - else { + } else { $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); } @@ -506,8 +473,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $height_note = $posyafter - $tab_top_newpage; $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); - } - else // No pagebreak + } else // No pagebreak { $pdf->commitTransaction(); $posyafter = $pdf->GetY(); @@ -515,8 +481,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // not enough space, need to add page $pdf->AddPage('', '', true); $pagenb++; @@ -531,9 +496,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $tab_height = $tab_height - $height_note; $tab_top = $posyafter + 6; - } - else - { + } else { $height_note = 0; } @@ -551,8 +514,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Loop on each lines $pageposbeforeprintlines = $pdf->getPage(); $pagenb = $pageposbeforeprintlines; - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -569,11 +531,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes $showpricebeforepagebreak = 1; $posYAfterImage = 0; - if ($this->getColumnStatus('photo')) - { + if ($this->getColumnStatus('photo')) { // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page - { + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); $pdf->setPage($pageposbefore + 1); @@ -583,23 +543,20 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) - { + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } } - if ($this->getColumnStatus('desc')) - { + if ($this->getColumnStatus('desc')) { $pdf->startTransaction(); - if(method_exists($object->lines[$i], 'fetch_product')) { + if (method_exists($object->lines[$i], 'fetch_product')) { $object->lines[$i]->fetch_product(); $object->lines[$i]->label = $object->lines[$i]->product->label; $object->lines[$i]->description = $object->lines[$i]->product->description; @@ -608,8 +565,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); - if ($pageposafter > $pageposbefore) // There is a pagebreak - { + if ($pageposafter > $pageposbefore) { // There is a pagebreak $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; @@ -618,27 +574,21 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text - { - if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text + if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); //if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $pdf->setPage($pageposafter + 1); } - } - else - { + } else { // We found a page break // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - } - else // No pagebreak + } else // No pagebreak { $pdf->commitTransaction(); } @@ -663,16 +613,14 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font // VAT Rate - if ($this->getColumnStatus('vat')) - { + if ($this->getColumnStatus('vat')) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); $nexY = max($pdf->GetY(), $nexY); } // Unit price before discount - if ($this->getColumnStatus('subprice')) - { + if ($this->getColumnStatus('subprice')) { $pmp = $object->lines[$i]->pmp; $this->printStdColumnContent($pdf, $curY, 'subprice', price($pmp)); $nexY = max($pdf->GetY(), $nexY); @@ -680,8 +628,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Quantity // Enough for 6 chars - if ($this->getColumnStatus('qty')) - { + if ($this->getColumnStatus('qty')) { $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'qty', $qty); $nexY = max($pdf->GetY(), $nexY); @@ -689,24 +636,21 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Unit - if ($this->getColumnStatus('unit')) - { + if ($this->getColumnStatus('unit')) { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); $this->printStdColumnContent($pdf, $curY, 'unit', $unit); $nexY = max($pdf->GetY(), $nexY); } // Discount on line - if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) - { + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) { $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); $nexY = max($pdf->GetY(), $nexY); } // Total HT line - if ($this->getColumnStatus('totalexcltax')) - { + if ($this->getColumnStatus('totalexcltax')) { $pmp_qty = $pmp * $object->lines[$i]->qty; $this->printStdColumnContent($pdf, $curY, 'totalexcltax', price($pmp_qty)); $nexY = max($pdf->GetY(), $nexY); @@ -715,8 +659,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Extrafields if (!empty($object->lines[$i]->array_options)) { foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) { - if ($this->getColumnStatus($extrafieldColKey)) - { + if ($this->getColumnStatus($extrafieldColKey)) { $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); $nexY = max($pdf->GetY(), $nexY); @@ -755,8 +698,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Retrieve type from database for backward compatibility with old records if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined - && (!empty($localtax1_rate) || !empty($localtax2_rate))) // and there is local tax - { + && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); $localtax1_type = $localtaxtmp_array[0]; $localtax2_type = $localtaxtmp_array[2]; @@ -773,8 +715,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->tva[$vatrate] += $tvaligne; // Add line - if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) - { + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); @@ -784,15 +725,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) - { + while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); - if ($pagenb == $pageposbeforeprintlines) - { + if ($pagenb == $pageposbeforeprintlines) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -801,14 +738,10 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) - { - if ($pagenb == $pageposafter) - { + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { + if ($pagenb == $pageposafter) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -823,8 +756,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Show square if ($pagenb == $pageposbeforeprintlines) $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code); - else - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + else $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; // Affiche zone infos @@ -854,8 +786,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) - { + if ($reshook < 0) { $this->error = $hookmanager->error; $this->errors = $hookmanager->errors; } @@ -866,15 +797,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->result = array('fullpath'=>$file); return 1; // No error - } - else - { + } else { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } - } - else - { + } else { $this->error = $langs->transnoentities("ErrorConstantNotDefined", "STOCKTRANSFER_OUTPUTDIR"); return 0; } @@ -910,8 +837,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // If France, show VAT mention if not applicable - if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) - { + if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); @@ -922,8 +848,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $posxval = 52; // Show payments conditions - if ($object->cond_reglement_code || $object->cond_reglement) - { + if ($object->cond_reglement_code || $object->cond_reglement) { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("PaymentConditions").':'; @@ -956,18 +881,17 @@ class pdf_eagle_proforma extends ModelePDFCommandes /* TODO else if (! empty($object->availability_code)) { - $pdf->SetXY($this->marge_gauche, $posy); - $pdf->SetTextColor(200,0,0); - $pdf->SetFont('','B', $default_font_size - 2); - $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); - $pdf->SetTextColor(0,0,0); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); + $pdf->SetTextColor(0,0,0); - $posy=$pdf->GetY()+1; + $posy=$pdf->GetY()+1; }*/ // Show planed date of delivery - if (!empty($object->date_livraison)) - { + if (!empty($object->date_livraison)) { $outputlangs->load("sendings"); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); @@ -979,9 +903,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->MultiCell(80, 4, $dlp, 0, 'L'); $posy = $pdf->GetY() + 1; - } - elseif ($object->availability_code || $object->availability) // Show availability conditions - { + } elseif ($object->availability_code || $object->availability) { // Show availability conditions $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("AvailabilityPeriod").':'; @@ -1014,13 +936,10 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Show payment mode CHQ - if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') - { + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { // Si mode reglement non force ou si force a CHQ - if (!empty($conf->global->FACTURE_CHQ_NUMBER)) - { - if ($conf->global->FACTURE_CHQ_NUMBER > 0) - { + if (!empty($conf->global->FACTURE_CHQ_NUMBER)) { + if ($conf->global->FACTURE_CHQ_NUMBER > 0) { $account = new Account($this->db); $account->fetch($conf->global->FACTURE_CHQ_NUMBER); @@ -1029,23 +948,20 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); $posy = $pdf->GetY() + 1; - if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) - { + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); $posy = $pdf->GetY() + 2; } } - if ($conf->global->FACTURE_CHQ_NUMBER == -1) - { + if ($conf->global->FACTURE_CHQ_NUMBER == -1) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); $posy = $pdf->GetY() + 1; - if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) - { + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); @@ -1056,10 +972,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // If payment mode not forced or forced to VIR, show payment with BAN - if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') - { - if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) - { + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') { + if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) { $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank $account = new Account($this->db); @@ -1100,8 +1014,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Tableau total $col1x = 120; $col2x = 170; - if ($this->page_largeur < 210) // To work with US executive format - { + if ($this->page_largeur < 210) { // To work with US executive format $col2x -= 20; } $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); @@ -1150,8 +1063,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'); if (!empty($object->paye)) $resteapayer = 0; - if ($deja_regle > 0) - { + if ($deja_regle > 0) { // Already paid + Deposits $index++; @@ -1206,8 +1118,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetTextColor(0, 0, 0); $pdf->SetFont('', '', $default_font_size - 2); - if (empty($hidetop)) - { + if (empty($hidetop)) { $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); @@ -1257,8 +1168,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); // Show Draft Watermark - if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) - { + if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) { pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->COMMANDE_DRAFT_WATERMARK); } @@ -1271,34 +1181,25 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetXY($this->marge_gauche, $posy); // Logo - if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) - { - if ($this->emetteur->logo) - { + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) { + if ($this->emetteur->logo) { $logodir = $conf->mycompany->dir_output; if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity]; - if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) - { + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; - } - else { + } else { $logo = $logodir.'/logos/'.$this->emetteur->logo; } - if (is_readable($logo)) - { + if (is_readable($logo)) { $height = pdf_getHeightForLogo($logo); $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) - } - else - { + } else { $pdf->SetTextColor(200, 0, 0); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } - } - else - { + } else { $text = $this->emetteur->name; $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); } @@ -1321,8 +1222,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // Date prévue depart - if (!empty($object->date_prevue_depart)) - { + if (!empty($object->date_prevue_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1330,8 +1230,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date prévue arrivée - if (!empty($object->date_prevue_arrivee)) - { + if (!empty($object->date_prevue_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1339,8 +1238,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date reelle depart - if (!empty($object->date_reelle_depart)) - { + if (!empty($object->date_reelle_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1348,27 +1246,23 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date reelle arrivée - if (!empty($object->date_reelle_arrivee)) - { + if (!empty($object->date_reelle_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); } - if ($object->ref_client) - { + if ($object->ref_client) { $posy += 5; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); } - if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) - { + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) { $object->fetch_projet(); - if (!empty($object->project->ref)) - { + if (!empty($object->project->ref)) { $posy += 3; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1376,11 +1270,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes } } - if (!empty($conf->global->PDF_SHOW_PROJECT)) - { + if (!empty($conf->global->PDF_SHOW_PROJECT)) { $object->fetch_projet(); - if (!empty($object->project->ref)) - { + if (!empty($object->project->ref)) { $posy += 3; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1388,8 +1280,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes } } - if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) - { + if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1397,11 +1288,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Get contact - if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) - { + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) { $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL'); - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { $usertmp = new User($this->db); $usertmp->fetch($arrayidcontact[0]); $posy += 4; @@ -1417,13 +1306,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Show list of linked objects $current_y = $pdf->getY(); $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); - if ($current_y < $pdf->getY()) - { + if ($current_y < $pdf->getY()) { $top_shift = $pdf->getY() - $current_y; } - if ($showaddress) - { + if ($showaddress) { // Sender properties $carac_emetteur = ''; // Add internal contact of origin element if defined @@ -1431,8 +1318,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $arrayidcontact = $object->getIdContact('external', 'STFROM'); $usecontact = false; - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { /*$object->fetch_user(reset($arrayidcontact)); $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ $usecontact = true; @@ -1442,9 +1328,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes if ($usecontact) $thirdparty = $object->contact; else $thirdparty = $this->emetteur; - if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + if ($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); // Show sender @@ -1481,8 +1367,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // If SHIPPING contact defined, we use it $usecontact = false; $arrayidcontact = $object->getIdContact('external', 'STDEST'); - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { $usecontact = true; $result = $object->fetch_contact($arrayidcontact[0]); } @@ -1495,7 +1380,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $thirdparty = $object->thirdparty; } - if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); @@ -1628,8 +1513,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes 'border-left' => false, // remove left line separator ); - if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) - { + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) { $this->cols['photo']['status'] = true; } @@ -1737,16 +1621,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes ); $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook - if ($reshook < 0) - { + if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - } - elseif (empty($reshook)) - { + } elseif (empty($reshook)) { $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys - } - else - { + } else { $this->cols = $hookmanager->resArray; } } diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 69128a65b93..54fcbfc32e5 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -224,7 +224,7 @@ class StockTransfer extends CommonObject public function create(User $user, $notrigger = false) { $model_pdf = GETPOST('model'); - if(!empty($model_pdf)) $this->model_pdf = $model_pdf; + if (!empty($model_pdf)) $this->model_pdf = $model_pdf; $this->status = (int) $this->status; if ($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0; if ($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0; From 335dca7fc36e340328a738f9f42d1935c3a6b751 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Tue, 3 Aug 2021 09:41:10 +0200 Subject: [PATCH 012/128] FIX : No paiement information for pdf eagle proforma --- .../modules/stocktransfer/doc/pdf_eagle_proforma.modules.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php index 7f9feb7eafe..9618d86139b 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -760,7 +760,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; // Affiche zone infos - $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs); + // ! No paiement information for this model ! + //$posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs); // Affiche zone totaux $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); From 1d2527b9913ed263f2193a17589d5d58d96a50d6 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Tue, 3 Aug 2021 16:00:32 +0200 Subject: [PATCH 013/128] FIX : weight and units display --- .../stocktransfer/doc/pdf_eagle.modules.php | 388 ++++++++++++------ .../doc/pdf_eagle_proforma.modules.php | 359 ++++++++++------ .../class/stocktransferline.class.php | 4 +- .../stocktransfer/stocktransfer_card.php | 316 ++++++++------ 4 files changed, 697 insertions(+), 370 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index a5245b3bff5..2c1d647f659 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2018 Frédéric France - * Copyright (C) 2021 Gauthier VERDOL + * 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 @@ -144,10 +144,11 @@ class pdf_eagle extends ModelePdfStockTransfer // Define position of columns $this->posxdesc = $this->marge_gauche + 1; - $this->posxlot = $this->page_largeur - $this->marge_droite - 125; - $this->posxqty = $this->page_largeur - $this->marge_droite - 105; - $this->posxwarehousesource = $this->page_largeur - $this->marge_droite - 90; - $this->posxwarehousedestination = $this->page_largeur - $this->marge_droite - 45; + $this->posxlot = $this->page_largeur - $this->marge_droite - 135; + $this->posxweightvol = $this->page_largeur - $this->marge_droite - 115; + $this->posxqty = $this->page_largeur - $this->marge_droite - 95; + $this->posxwarehousesource = $this->page_largeur - $this->marge_droite - 70; + $this->posxwarehousedestination = $this->page_largeur - $this->marge_droite - 35; $this->posxpuht = $this->page_largeur - $this->marge_droite; /*if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { // Show also the prices @@ -158,9 +159,10 @@ class pdf_eagle extends ModelePdfStockTransfer $this->posxtotalht = $this->page_largeur - $this->marge_droite - 20; }*/ - //if (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) $this->posxqty = $this->posxwarehousesource; + if (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) $this->posxweightvol = $this->posxqty; - $this->posxpicture = $this->posxqty - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images + $this->posxpicture = $this->posxweightvol - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images + //var_dump($this->posxpicture, $this->posxweightvol);exit; // To work with US executive format if ($this->page_largeur < 210) { @@ -170,11 +172,11 @@ class pdf_eagle extends ModelePdfStockTransfer $this->posxwarehousedestination -= 20; } - if (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) { + /*if (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) { $this->posxqty += ($this->posxwarehousedestination - $this->posxwarehousesource); $this->posxpicture += ($this->posxwarehousedestination - $this->posxwarehousesource); $this->posxwarehousesource = $this->posxwarehousedestination; - } + }*/ } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -209,18 +211,23 @@ class pdf_eagle extends ModelePdfStockTransfer // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); - if (!empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE)) { + if (!empty($conf->global->MAIN_GENERATE_STOCKTRANSFER_WITH_PICTURE)) + { $objphoto = new Product($this->db); - for ($i = 0; $i < $nblines; $i++) { + for ($i = 0; $i < $nblines; $i++) + { if (empty($object->lines[$i]->fk_product)) continue; $objphoto = new Product($this->db); $objphoto->fetch($object->lines[$i]->fk_product); - if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/"; $dir = $conf->product->dir_output.'/'.$pdir; - } else { + } + else + { $pdir = get_exdir(0, 2, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; $dir = $conf->product->dir_output.'/'.$pdir; } @@ -230,12 +237,17 @@ class pdf_eagle extends ModelePdfStockTransfer foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo - if ($obj['photo_vignette']) { + if ($obj['photo_vignette']) + { $filename = $obj['photo_vignette']; - } else { + } + else + { $filename = $obj['photo']; } - } else { + } + else + { $filename = $obj['photo']; } @@ -247,29 +259,43 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if (count($realpatharray) == 0) $this->posxpicture = $this->posxqty; + if (count($realpatharray) == 0) $this->posxpicture = $this->posxweightvol; - if ($conf->stocktransfer->dir_output) { + + if(!empty($this->atLeastOneBatch)) { + $this->posxpicture = $this->posxlot; + if(!empty($conf->global->MAIN_GENERATE_STOCKTRANSFER_WITH_PICTURE)) $this->posxpicture -= (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images + } + + if ($conf->stocktransfer->dir_output) + { // Definition de $dir et $file - if ($object->specimen) { + if ($object->specimen) + { $dir = $conf->stocktransfer->dir_output; $file = $dir."/SPECIMEN.pdf"; - } else { + } + else + { $stocktransferref = dol_sanitizeFileName($object->ref); $dir = $conf->stocktransfer->dir_output.'/'.$object->element."/".$stocktransferref; $file = $dir."/".$stocktransferref.".pdf"; } - if (!file_exists($dir)) { - if (dol_mkdir($dir) < 0) { + if (!file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } - if (file_exists($dir)) { + if (file_exists($dir)) + { // Add pdfgeneration hook - if (!is_object($hookmanager)) { + if (!is_object($hookmanager)) + { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } @@ -289,13 +315,15 @@ class pdf_eagle extends ModelePdfStockTransfer if ($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS > 0) $heightforfooter += 6; $pdf->SetAutoPageBreak(1, 0); - if (class_exists('TCPDF')) { + if (class_exists('TCPDF')) + { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File - if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } @@ -331,9 +359,11 @@ class pdf_eagle extends ModelePdfStockTransfer // Incoterm $height_incoterms = 0; - if ($conf->incoterm->enabled) { + if ($conf->incoterm->enabled) + { $desc_incoterms = $object->getIncotermsForPDF(); - if ($desc_incoterms) { + if ($desc_incoterms) + { $tab_top = 88; $pdf->SetFont('', '', $default_font_size - 1); @@ -350,7 +380,8 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if (!empty($object->note_public) || !empty($object->tracking_number)) { + if (!empty($object->note_public) || !empty($object->tracking_number)) + { $tab_top = 88 + $height_incoterms; $tab_top_alt = $tab_top; @@ -359,20 +390,24 @@ class pdf_eagle extends ModelePdfStockTransfer //$tab_top_alt += 1; // Tracking number - if (!empty($object->tracking_number)) { + if (!empty($object->tracking_number)) + { $pdf->writeHTMLCell(60, 4, $this->posxdesc - 1, $tab_top - 1, $outputlangs->transnoentities("TrackingNumber")." : ".$object->tracking_number, 0, 1, false, true, 'L'); $tab_top_alt = $pdf->GetY(); $object->getUrlTrackingStatus($object->tracking_number); - if (!empty($object->tracking_url)) { - if ($object->shipping_method_id > 0) { + if (!empty($object->tracking_url)) + { + if ($object->shipping_method_id > 0) + { // Get code using getLabelFromKey $code = $outputlangs->getLabelFromKey($this->db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); $label = ''; if ($object->tracking_url != $object->tracking_number) $label .= $outputlangs->trans("LinkToTrackYourPackage")."
"; $label .= $outputlangs->trans("SendingMethod").": ".$outputlangs->trans("SendingMethod".strtoupper($code)); //var_dump($object->tracking_url != $object->tracking_number);exit; - if ($object->tracking_url != $object->tracking_number) { + if ($object->tracking_url != $object->tracking_number) + { $label .= " : "; $label .= $object->tracking_url; } @@ -385,7 +420,8 @@ class pdf_eagle extends ModelePdfStockTransfer } // Notes - if (!empty($object->note_public)) { + if (!empty($object->note_public)) + { $pdf->SetFont('', '', $default_font_size - 1); // Dans boucle pour gerer multi-page $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1); } @@ -399,7 +435,9 @@ class pdf_eagle extends ModelePdfStockTransfer $tab_height = $tab_height - $height_note; $tab_top = $nexY + 6; - } else { + } + else + { $height_note = 0; } @@ -409,7 +447,8 @@ class pdf_eagle extends ModelePdfStockTransfer $TCacheEntrepots=array(); // Loop on each lines - for ($i = 0; $i < $nblines; $i++) { + for ($i = 0; $i < $nblines; $i++) + { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -427,7 +466,8 @@ class pdf_eagle extends ModelePdfStockTransfer $posYAfterDescription = 0; // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page + { $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); @@ -438,12 +478,15 @@ class pdf_eagle extends ModelePdfStockTransfer // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else $showpricebeforepagebreak = 0; + else + $showpricebeforepagebreak = 0; } - if (isset($imglinesize['width']) && isset($imglinesize['height'])) { + if (isset($imglinesize['width']) && isset($imglinesize['height'])) + { $curX = $this->posxpicture - 1; - $pdf->Image($realpatharray[$i], $curX + (($this->posxqty - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $curX + (($this->posxqty - $this->posxweightvol - $imglinesize['width'] + + (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME) ? (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) : 0)) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } @@ -452,16 +495,27 @@ class pdf_eagle extends ModelePdfStockTransfer $curX = $this->posxdesc - 1; $pdf->startTransaction(); - if (method_exists($object->lines[$i], 'fetch_product')) { + if(method_exists($object->lines[$i], 'fetch_product')) { $object->lines[$i]->fetch_product(); $object->lines[$i]->label = $object->lines[$i]->product->label; $object->lines[$i]->description = $object->lines[$i]->product->description; + $object->lines[$i]->weight = $object->lines[$i]->product->weight; + $object->lines[$i]->weight_units = $object->lines[$i]->product->weight_units; + $object->lines[$i]->length = $object->lines[$i]->product->length; + $object->lines[$i]->length_units = $object->lines[$i]->product->length_units; + $object->lines[$i]->surface = $object->lines[$i]->product->surface; + $object->lines[$i]->surface_units = $object->lines[$i]->product->surface_units; + $object->lines[$i]->volume = $object->lines[$i]->product->volume; + $object->lines[$i]->volume_units = $object->lines[$i]->product->volume_units; + $object->lines[$i]->fk_unit = $object->lines[$i]->product->fk_unit; + //var_dump($object->lines[$i]);exit; } - //var_dump($object->lines[$i]->product);exit; + pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); - if ($pageposafter > $pageposbefore) { // There is a pagebreak + if ($pageposafter > $pageposbefore) // There is a pagebreak + { $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; @@ -471,22 +525,28 @@ class pdf_eagle extends ModelePdfStockTransfer $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text - if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page + { $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $pdf->setPage($pageposafter + 1); } - } else { + } + else + { // We found a page break // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else $showpricebeforepagebreak = 0; + else + $showpricebeforepagebreak = 0; } - } else // No pagebreak + } + else // No pagebreak { $pdf->commitTransaction(); } @@ -511,12 +571,30 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut - - $pdf->SetXY($this->posxqty, $curY); // Lot / série - if (!empty($conf->productbatch->enabled)) { + if(!empty($conf->productbatch->enabled)) { $pdf->SetXY($this->posxlot, $curY); - $pdf->MultiCell(($this->posxqty - $this->posxlot), 3, $object->lines[$i]->batch, '', 'C'); + $pdf->MultiCell(($this->posxweightvol - $this->posxlot), 3, $object->lines[$i]->batch, '', 'C'); + } + + // Weight + $pdf->SetXY($this->posxweightvol, $curY); + $weighttxt = ''; + if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight) + { + $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1); + } + $voltxt = ''; + if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume) + { + $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1); + } + + // Weight + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) + { + $pdf->writeHTMLCell($this->posxqty - $this->posxweightvol + 2, 3, $this->posxweightvol - 1, $curY, $weighttxt.(($weighttxt && $voltxt) ? '
' : '').$voltxt, 0, 0, false, true, 'C'); + //$pdf->MultiCell(($this->posxqtyordered - $this->posxweightvol), 3, $weighttxt.(($weighttxt && $voltxt)?'
':'').$voltxt,'','C'); } // Qty @@ -526,7 +604,7 @@ class pdf_eagle extends ModelePdfStockTransfer // Warehouse source $wh_source = new Entrepot($db); - if (!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_source])) $wh_source = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source]; + if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_source])) $wh_source = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source]; else { $wh_source->fetch($object->lines[$i]->fk_warehouse_source); $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source] = $wh_source; @@ -536,7 +614,7 @@ class pdf_eagle extends ModelePdfStockTransfer // Warehouse destination $wh_destination = new Entrepot($db); - if (!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination])) $wh_destination = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination]; + if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination])) $wh_destination = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination]; else { $wh_destination->fetch($object->lines[$i]->fk_warehouse_destination); $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination] = $wh_destination; @@ -544,7 +622,8 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetXY($this->posxwarehousedestination, $curY); $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination), 3, $wh_destination->ref.(!empty($wh_destination->lieu) ? ' - '.$wh_destination->lieu : ''), '', 'C'); - if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) + { $pdf->SetXY($this->posxpuht, $curY); $pdf->MultiCell(($this->posxtotalht - $this->posxpuht - 1), 3, price($object->lines[$i]->subprice, 0, $outputlangs), '', 'R'); @@ -556,7 +635,8 @@ class pdf_eagle extends ModelePdfStockTransfer if ($weighttxt && $voltxt) $nexY += 2; // Add line - if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) + { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); @@ -565,11 +645,15 @@ class pdf_eagle extends ModelePdfStockTransfer } // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) { + while ($pagenb < $pageposafter) + { $pdf->setPage($pagenb); - if ($pagenb == 1) { + if ($pagenb == 1) + { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); - } else { + } + else + { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -578,10 +662,14 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { - if ($pagenb == 1) { + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) + { + if ($pagenb == 1) + { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); - } else { + } + else + { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -594,16 +682,19 @@ class pdf_eagle extends ModelePdfStockTransfer } // Show square - if ($pagenb == 1) { + if ($pagenb == 1) + { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; - } else { + } + else + { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } // Affiche zone totaux - //$posy = $this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); + $posy = $this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); // Pied de page $this->_pagefoot($pdf, $object, $outputlangs); @@ -618,7 +709,8 @@ class pdf_eagle extends ModelePdfStockTransfer $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) { + if ($reshook < 0) + { $this->error = $hookmanager->error; $this->errors = $hookmanager->errors; } @@ -629,11 +721,15 @@ class pdf_eagle extends ModelePdfStockTransfer $this->result = array('fullpath'=>$file); return 1; // No error - } else { + } + else + { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } - } else { + } + else + { $this->error = $langs->transnoentities("ErrorConstantNotDefined", "EXP_OUTPUTDIR"); return 0; } @@ -683,10 +779,14 @@ class pdf_eagle extends ModelePdfStockTransfer $tmparray = $object->getTotalWeightVolume(); $totalWeight = $tmparray['weight']; $totalVolume = $tmparray['volume']; - $totalOrdered = $tmparray['ordered']; - $totalToShip = $tmparray['toship']; + $totalQty = 0; + if(!empty($object->lines)) + foreach ($object->lines as $line) { + $totalQty+=$line->qty; + } // Set trueVolume and volume_units not currently stored into database - if ($object->trueWidth && $object->trueHeight && $object->trueDepth) { + if ($object->trueWidth && $object->trueHeight && $object->trueDepth) + { $object->trueVolume = price(($object->trueWidth * $object->trueHeight * $object->trueDepth), 0, $outputlangs, 0, 0); $object->volume_units = $object->size_units * 3; } @@ -700,17 +800,14 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Total"), 0, 'L', 1); - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) { - $pdf->SetXY($this->posxwarehousesource, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($this->posxwarehousedestination - $this->posxwarehousesource, $tab2_hl, $totalOrdered, 0, 'C', 1); + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) + { + $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->posxwarehousesource - $this->posxqty, $tab2_hl, $totalQty, 0, 'C', 1); } - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_QTYTOSHIP)) { - $pdf->SetXY($this->posxwarehousedestination, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($this->posxpuht - $this->posxwarehousedestination, $tab2_hl, $totalToShip, 0, 'C', 1); - } - - if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) + { $pdf->SetXY($this->posxpuht, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($this->posxtotalht - $this->posxpuht, $tab2_hl, '', 0, 'C', 1); @@ -718,17 +815,20 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxtotalht, $tab2_hl, price($object->total_ht, 0, $outputlangs), 0, 'C', 1); } - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) + { // Total Weight - if ($totalWeighttoshow) { - $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), $tab2_hl, $totalWeighttoshow, 0, 'C', 1); + if ($totalWeighttoshow) + { + $pdf->SetXY($this->posxweightvol, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell(($this->posxqty - $this->posxweightvol), $tab2_hl, $totalWeighttoshow, 0, 'C', 1); $index++; } - if ($totalVolumetoshow) { - $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), $tab2_hl, $totalVolumetoshow, 0, 'C', 1); + if ($totalVolumetoshow) + { + $pdf->SetXY($this->posxweightvol, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell(($this->posxqty - $this->posxweightvol), $tab2_hl, $totalVolumetoshow, 0, 'C', 1); $index++; } @@ -773,36 +873,48 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetDrawColor(128, 128, 128); $pdf->SetFont('', '', $default_font_size - 1); - if (empty($hidetop)) { + if (empty($hidetop)) + { $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5); $pdf->SetXY($this->posxdesc - 1, $tab_top + 1); - $pdf->MultiCell($this->posxwarehousesource - $this->posxdesc, 2, $outputlangs->transnoentities("Description"), '', 'L'); + $pdf->MultiCell($this->posxlot - $this->posxdesc, 2, $outputlangs->transnoentities("Description"), '', 'L'); } - if (!empty($conf->productbatch->enabled) && $this->atLeastOneBatch) { + if(!empty($conf->productbatch->enabled) && $this->atLeastOneBatch) { $pdf->line($this->posxlot - 1, $tab_top, $this->posxlot - 1, $tab_top + $tab_height); if (empty($hidetop)) { - $pdf->SetXY($this->posxlot - 8, $tab_top + 1); - $pdf->MultiCell(($this->posxwarehousesource - $this->posxlot), 2, $outputlangs->transnoentities("Batch"), '', 'C'); + $pdf->SetXY($this->posxlot, $tab_top + 1); + $pdf->MultiCell(($this->posxweightvol - $this->posxlot), 2, $outputlangs->transnoentities("Batch"), '', 'C'); + } + } + + if(empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) { + $pdf->line($this->posxweightvol - 1, $tab_top, $this->posxweightvol - 1, $tab_top + $tab_height); + if (empty($hidetop)) { + $pdf->SetXY($this->posxweightvol - 1, $tab_top + 1); + $pdf->MultiCell(($this->posxqty - $this->posxweightvol), 2, $outputlangs->transnoentities("WeightVolShort"), '', 'C'); } } $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height); - if (empty($hidetop)) { + if (empty($hidetop)) + { $pdf->SetXY($this->posxqty - 1, $tab_top + 1); $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), 2, $outputlangs->transnoentities("Qty"), '', 'C'); } $pdf->line($this->posxwarehousesource - 1, $tab_top, $this->posxwarehousesource - 1, $tab_top + $tab_height); - if (empty($hidetop)) { + if (empty($hidetop)) + { $pdf->SetXY($this->posxwarehousesource - 1, $tab_top + 1); $pdf->MultiCell(($this->posxwarehousedestination - $this->posxwarehousesource), 2, $outputlangs->transnoentities("WarehouseSource"), '', 'C'); } $pdf->line($this->posxwarehousedestination - 1, $tab_top, $this->posxwarehousedestination - 1, $tab_top + $tab_height); - if (empty($hidetop)) { + if (empty($hidetop)) + { $pdf->SetXY($this->posxwarehousedestination-2.5, $tab_top + 1); $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination+4), 2, $outputlangs->transnoentities("WarehouseTarget"), '', 'C'); } @@ -824,24 +936,22 @@ class pdf_eagle extends ModelePdfStockTransfer }*/ } - /** - * Used to know if at least one line of Stock Transfer object has a batch set - * - * @param $object Stock Transfer object - * @return bool true if at least one line has batch set, false if not - */ - public function atLeastOneBatch($object) - { + function atLeastOneBatch($object) { + + global $conf; $atLeastOneBatch = false; + if(empty($conf->productbatch->enabled)) return false; + foreach ($object->lines as $line) { - if (!empty($line->batch)) { + if(!empty($line->batch)) { return true; } } return false; + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore @@ -865,7 +975,8 @@ class pdf_eagle extends ModelePdfStockTransfer pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); // Show Draft Watermark - if ($object->statut == 0 && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) { + if ($object->statut == 0 && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) + { pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->SHIPPING_DRAFT_WATERMARK); } @@ -882,36 +993,47 @@ class pdf_eagle extends ModelePdfStockTransfer // Logo $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; - if ($this->emetteur->logo) { - if (is_readable($logo)) { + if ($this->emetteur->logo) + { + if (is_readable($logo)) + { $height = pdf_getHeightForLogo($logo); $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) - } else { + } + else + { $pdf->SetTextColor(200, 0, 0); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } - } else { + } + else + { $text = $this->emetteur->name; $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); } // Show barcode - if (!empty($conf->barcode->enabled)) { + if (!empty($conf->barcode->enabled)) + { $posx = 105; - } else { + } + else + { $posx = $this->marge_gauche + 3; } //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); - if (!empty($conf->barcode->enabled)) { + if (!empty($conf->barcode->enabled)) + { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); } $pdf->SetDrawColor(128, 128, 128); - if (!empty($conf->barcode->enabled)) { + if (!empty($conf->barcode->enabled)) + { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); @@ -935,16 +1057,18 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("Ref")." : ".$object->ref, '', 'R'); - // Date reelle depart - if (!empty($object->date_prevue_depart)) { + // Date prévue depart + if (!empty($object->date_prevue_depart)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DatePrevueDepart")." : ".dol_print_date($object->date_prevue_depart, "day", false, $outputlangs, true), '', 'R'); } - // Date reelle arrivée - if (!empty($object->date_prevue_arrivee)) { + // Date prévue arrivée + if (!empty($object->date_prevue_arrivee)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -952,7 +1076,8 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date reelle depart - if (!empty($object->date_reelle_depart)) { + if (!empty($object->date_reelle_depart)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -960,14 +1085,16 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date reelle arrivée - if (!empty($object->date_reelle_arrivee)) { + if (!empty($object->date_reelle_arrivee)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); } - if (!empty($object->thirdparty->code_client)) { + if (!empty($object->thirdparty->code_client)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -983,13 +1110,15 @@ class pdf_eagle extends ModelePdfStockTransfer $origin_id = $object->origin_id; // TODO move to external function - if (!empty($conf->$origin->enabled)) { // commonly $origin='commande' + if (!empty($conf->$origin->enabled)) // commonly $origin='commande' + { $outputlangs->load('orders'); $classname = ucfirst($origin); $linkedobject = new $classname($this->db); $result = $linkedobject->fetch($origin_id); - if ($result >= 0) { + if ($result >= 0) + { //$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects $pdf->SetFont('', '', $default_font_size - 2); @@ -1004,7 +1133,8 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if ($showaddress) { + if ($showaddress) + { // Sender properties $carac_emetteur = ''; // Add internal contact of origin element if defined @@ -1012,7 +1142,8 @@ class pdf_eagle extends ModelePdfStockTransfer $arrayidcontact = $object->getIdContact('external', 'STFROM'); $usecontact = false; - if (count($arrayidcontact) > 0) { + if (count($arrayidcontact) > 0) + { /*$object->fetch_user(reset($arrayidcontact)); $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ $usecontact = true; @@ -1022,9 +1153,9 @@ class pdf_eagle extends ModelePdfStockTransfer if ($usecontact) $thirdparty = $object->contact; else $thirdparty = $this->emetteur; - if (!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - if ($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); // Show sender @@ -1061,7 +1192,8 @@ class pdf_eagle extends ModelePdfStockTransfer // If SHIPPING contact defined, we use it $usecontact = false; $arrayidcontact = $object->getIdContact('external', 'STDEST'); - if (count($arrayidcontact) > 0) { + if (count($arrayidcontact) > 0) + { $usecontact = true; $result = $object->fetch_contact($arrayidcontact[0]); } @@ -1074,7 +1206,7 @@ class pdf_eagle extends ModelePdfStockTransfer $thirdparty = $object->thirdparty; } - if (!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php index 9618d86139b..9ba4d869ec0 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -8,6 +8,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2018-2019 Frédéric France + * 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 @@ -218,35 +219,49 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); $this->atleastonephoto = false; - if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) { + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) + { $objphoto = new Product($this->db); - for ($i = 0; $i < $nblines; $i++) { + for ($i = 0; $i < $nblines; $i++) + { if (empty($object->lines[$i]->fk_product)) continue; $objphoto->fetch($object->lines[$i]->fk_product); //var_dump($objphoto->ref);exit; - if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; - } else { + } + else + { $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative } $arephoto = false; - foreach ($pdir as $midir) { - if (!$arephoto) { + foreach ($pdir as $midir) + { + if (!$arephoto) + { $dir = $conf->product->dir_output.'/'.$midir; - foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { - if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo - if ($obj['photo_vignette']) { + foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) + { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + { + if ($obj['photo_vignette']) + { $filename = $obj['photo_vignette']; - } else { + } + else + { $filename = $obj['photo']; } - } else { + } + else + { $filename = $obj['photo']; } @@ -263,31 +278,39 @@ class pdf_eagle_proforma extends ModelePDFCommandes - if ($conf->stocktransfer->dir_output) { + if ($conf->stocktransfer->dir_output) + { $object->fetch_thirdparty(); $deja_regle = 0; // Definition of $dir and $file - if ($object->specimen) { + if ($object->specimen) + { $dir = $conf->stocktransfer->multidir_output[$conf->entity]; $file = $dir."/SPECIMEN.pdf"; - } else { + } + else + { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->stocktransfer->multidir_output[$conf->entity]."/".$object->element."/".$objectref; $file = $dir."/".$objectref.".pdf"; } - if (!file_exists($dir)) { - if (dol_mkdir($dir) < 0) { + if (!file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } - if (file_exists($dir)) { + if (file_exists($dir)) + { // Add pdfgeneration hook - if (!is_object($hookmanager)) { + if (!is_object($hookmanager)) + { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } @@ -305,13 +328,15 @@ class pdf_eagle_proforma extends ModelePDFCommandes $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin) - if (class_exists('TCPDF')) { + if (class_exists('TCPDF')) + { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File - if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } @@ -352,9 +377,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10); // Incoterm - if ($conf->incoterm->enabled) { + if ($conf->incoterm->enabled) + { $desc_incoterms = $object->getIncotermsForPDF(); - if ($desc_incoterms) { + if ($desc_incoterms) + { $tab_top -= 2; $pdf->SetFont('', '', $default_font_size - 1); @@ -372,9 +399,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Displays notes $notetoshow = empty($object->note_public) ? '' : $object->note_public; - if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) { + if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) + { // Get first sale rep - if (is_object($object->thirdparty)) { + if (is_object($object->thirdparty)) + { $salereparray = $object->thirdparty->getSalesRepresentatives($user); $salerepobj = new User($this->db); $salerepobj->fetch($salereparray[0]['id']); @@ -384,12 +413,14 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Extrafields in note $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); - if (!empty($extranote)) { + if (!empty($extranote)) + { $notetoshow = dol_concatdesc($notetoshow, $extranote); } $pagenb = $pdf->getPage(); - if ($notetoshow) { + if ($notetoshow) + { $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite; $pageposbeforenote = $pagenb; @@ -408,7 +439,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pageposafternote = $pdf->getPage(); $posyafter = $pdf->GetY(); - if ($pageposafternote > $pageposbeforenote) { + if ($pageposafternote > $pageposbeforenote) + { $pdf->rollbackTransaction(true); // prepare pages to receive notes @@ -432,7 +464,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $posyafter = $pdf->GetY(); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) // There is no space left for total+free text + { $pdf->AddPage('', '', true); $pagenb++; $pageposafternote++; @@ -455,7 +488,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes if ($i > $pageposbeforenote) { $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); - } else { + } + else { $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); } @@ -473,7 +507,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $height_note = $posyafter - $tab_top_newpage; $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); - } else // No pagebreak + } + else // No pagebreak { $pdf->commitTransaction(); $posyafter = $pdf->GetY(); @@ -481,7 +516,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) + { // not enough space, need to add page $pdf->AddPage('', '', true); $pagenb++; @@ -496,7 +532,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes $tab_height = $tab_height - $height_note; $tab_top = $posyafter + 6; - } else { + } + else + { $height_note = 0; } @@ -514,7 +552,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Loop on each lines $pageposbeforeprintlines = $pdf->getPage(); $pagenb = $pageposbeforeprintlines; - for ($i = 0; $i < $nblines; $i++) { + for ($i = 0; $i < $nblines; $i++) + { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -531,9 +570,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes $showpricebeforepagebreak = 1; $posYAfterImage = 0; - if ($this->getColumnStatus('photo')) { + if ($this->getColumnStatus('photo')) + { // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page + { $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); $pdf->setPage($pageposbefore + 1); @@ -543,29 +584,34 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else $showpricebeforepagebreak = 0; + else + $showpricebeforepagebreak = 0; } - if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) + { $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } } - if ($this->getColumnStatus('desc')) { + if ($this->getColumnStatus('desc')) + { $pdf->startTransaction(); - if (method_exists($object->lines[$i], 'fetch_product')) { + if(method_exists($object->lines[$i], 'fetch_product')) { $object->lines[$i]->fetch_product(); $object->lines[$i]->label = $object->lines[$i]->product->label; $object->lines[$i]->description = $object->lines[$i]->product->description; + $object->lines[$i]->fk_unit = $object->lines[$i]->product->fk_unit; } $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); - if ($pageposafter > $pageposbefore) { // There is a pagebreak + if ($pageposafter > $pageposbefore) // There is a pagebreak + { $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; @@ -574,21 +620,27 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text - if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page + { $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); //if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $pdf->setPage($pageposafter + 1); } - } else { + } + else + { // We found a page break // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else $showpricebeforepagebreak = 0; + else + $showpricebeforepagebreak = 0; } - } else // No pagebreak + } + else // No pagebreak { $pdf->commitTransaction(); } @@ -613,14 +665,16 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font // VAT Rate - if ($this->getColumnStatus('vat')) { + if ($this->getColumnStatus('vat')) + { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); $nexY = max($pdf->GetY(), $nexY); } // Unit price before discount - if ($this->getColumnStatus('subprice')) { + if ($this->getColumnStatus('subprice')) + { $pmp = $object->lines[$i]->pmp; $this->printStdColumnContent($pdf, $curY, 'subprice', price($pmp)); $nexY = max($pdf->GetY(), $nexY); @@ -628,7 +682,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Quantity // Enough for 6 chars - if ($this->getColumnStatus('qty')) { + if ($this->getColumnStatus('qty')) + { $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'qty', $qty); $nexY = max($pdf->GetY(), $nexY); @@ -636,21 +691,24 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Unit - if ($this->getColumnStatus('unit')) { + if ($this->getColumnStatus('unit')) + { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); $this->printStdColumnContent($pdf, $curY, 'unit', $unit); $nexY = max($pdf->GetY(), $nexY); } // Discount on line - if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) { + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) + { $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); $nexY = max($pdf->GetY(), $nexY); } // Total HT line - if ($this->getColumnStatus('totalexcltax')) { + if ($this->getColumnStatus('totalexcltax')) + { $pmp_qty = $pmp * $object->lines[$i]->qty; $this->printStdColumnContent($pdf, $curY, 'totalexcltax', price($pmp_qty)); $nexY = max($pdf->GetY(), $nexY); @@ -659,7 +717,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Extrafields if (!empty($object->lines[$i]->array_options)) { foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) { - if ($this->getColumnStatus($extrafieldColKey)) { + if ($this->getColumnStatus($extrafieldColKey)) + { $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); $nexY = max($pdf->GetY(), $nexY); @@ -698,7 +757,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Retrieve type from database for backward compatibility with old records if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined - && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax + && (!empty($localtax1_rate) || !empty($localtax2_rate))) // and there is local tax + { $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); $localtax1_type = $localtaxtmp_array[0]; $localtax2_type = $localtaxtmp_array[2]; @@ -715,7 +775,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->tva[$vatrate] += $tvaligne; // Add line - if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) + { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); @@ -725,11 +786,15 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) { + while ($pagenb < $pageposafter) + { $pdf->setPage($pagenb); - if ($pagenb == $pageposbeforeprintlines) { + if ($pagenb == $pageposbeforeprintlines) + { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); - } else { + } + else + { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -738,10 +803,14 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { - if ($pagenb == $pageposafter) { + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) + { + if ($pagenb == $pageposafter) + { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); - } else { + } + else + { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -756,7 +825,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Show square if ($pagenb == $pageposbeforeprintlines) $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code); - else $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + else + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; // Affiche zone infos @@ -787,7 +857,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) { + if ($reshook < 0) + { $this->error = $hookmanager->error; $this->errors = $hookmanager->errors; } @@ -798,11 +869,15 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->result = array('fullpath'=>$file); return 1; // No error - } else { + } + else + { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } - } else { + } + else + { $this->error = $langs->transnoentities("ErrorConstantNotDefined", "STOCKTRANSFER_OUTPUTDIR"); return 0; } @@ -838,7 +913,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // If France, show VAT mention if not applicable - if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) { + if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) + { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); @@ -849,7 +925,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $posxval = 52; // Show payments conditions - if ($object->cond_reglement_code || $object->cond_reglement) { + if ($object->cond_reglement_code || $object->cond_reglement) + { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("PaymentConditions").':'; @@ -882,17 +959,18 @@ class pdf_eagle_proforma extends ModelePDFCommandes /* TODO else if (! empty($object->availability_code)) { - $pdf->SetXY($this->marge_gauche, $posy); - $pdf->SetTextColor(200,0,0); - $pdf->SetFont('','B', $default_font_size - 2); - $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); - $pdf->SetTextColor(0,0,0); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); + $pdf->SetTextColor(0,0,0); - $posy=$pdf->GetY()+1; + $posy=$pdf->GetY()+1; }*/ // Show planed date of delivery - if (!empty($object->date_livraison)) { + if (!empty($object->date_livraison)) + { $outputlangs->load("sendings"); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); @@ -904,7 +982,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->MultiCell(80, 4, $dlp, 0, 'L'); $posy = $pdf->GetY() + 1; - } elseif ($object->availability_code || $object->availability) { // Show availability conditions + } + elseif ($object->availability_code || $object->availability) // Show availability conditions + { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("AvailabilityPeriod").':'; @@ -937,10 +1017,13 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Show payment mode CHQ - if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') + { // Si mode reglement non force ou si force a CHQ - if (!empty($conf->global->FACTURE_CHQ_NUMBER)) { - if ($conf->global->FACTURE_CHQ_NUMBER > 0) { + if (!empty($conf->global->FACTURE_CHQ_NUMBER)) + { + if ($conf->global->FACTURE_CHQ_NUMBER > 0) + { $account = new Account($this->db); $account->fetch($conf->global->FACTURE_CHQ_NUMBER); @@ -949,20 +1032,23 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); $posy = $pdf->GetY() + 1; - if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); $posy = $pdf->GetY() + 2; } } - if ($conf->global->FACTURE_CHQ_NUMBER == -1) { + if ($conf->global->FACTURE_CHQ_NUMBER == -1) + { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); $posy = $pdf->GetY() + 1; - if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); @@ -973,8 +1059,10 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // If payment mode not forced or forced to VIR, show payment with BAN - if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') { - if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) { + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') + { + if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) + { $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank $account = new Account($this->db); @@ -1015,7 +1103,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Tableau total $col1x = 120; $col2x = 170; - if ($this->page_largeur < 210) { // To work with US executive format + if ($this->page_largeur < 210) // To work with US executive format + { $col2x -= 20; } $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); @@ -1064,7 +1153,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'); if (!empty($object->paye)) $resteapayer = 0; - if ($deja_regle > 0) { + if ($deja_regle > 0) + { // Already paid + Deposits $index++; @@ -1119,7 +1209,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetTextColor(0, 0, 0); $pdf->SetFont('', '', $default_font_size - 2); - if (empty($hidetop)) { + if (empty($hidetop)) + { $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); @@ -1169,7 +1260,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); // Show Draft Watermark - if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) { + if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) + { pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->COMMANDE_DRAFT_WATERMARK); } @@ -1182,25 +1274,34 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetXY($this->marge_gauche, $posy); // Logo - if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) { - if ($this->emetteur->logo) { + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) + { + if ($this->emetteur->logo) + { $logodir = $conf->mycompany->dir_output; if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity]; - if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) + { $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; - } else { + } + else { $logo = $logodir.'/logos/'.$this->emetteur->logo; } - if (is_readable($logo)) { + if (is_readable($logo)) + { $height = pdf_getHeightForLogo($logo); $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) - } else { + } + else + { $pdf->SetTextColor(200, 0, 0); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } - } else { + } + else + { $text = $this->emetteur->name; $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); } @@ -1223,7 +1324,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // Date prévue depart - if (!empty($object->date_prevue_depart)) { + if (!empty($object->date_prevue_depart)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1231,7 +1333,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date prévue arrivée - if (!empty($object->date_prevue_arrivee)) { + if (!empty($object->date_prevue_arrivee)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1239,7 +1342,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date reelle depart - if (!empty($object->date_reelle_depart)) { + if (!empty($object->date_reelle_depart)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1247,23 +1351,27 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date reelle arrivée - if (!empty($object->date_reelle_arrivee)) { + if (!empty($object->date_reelle_arrivee)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); } - if ($object->ref_client) { + if ($object->ref_client) + { $posy += 5; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); } - if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) { + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) + { $object->fetch_projet(); - if (!empty($object->project->ref)) { + if (!empty($object->project->ref)) + { $posy += 3; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1271,9 +1379,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes } } - if (!empty($conf->global->PDF_SHOW_PROJECT)) { + if (!empty($conf->global->PDF_SHOW_PROJECT)) + { $object->fetch_projet(); - if (!empty($object->project->ref)) { + if (!empty($object->project->ref)) + { $posy += 3; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1281,7 +1391,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes } } - if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) { + if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) + { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1289,9 +1400,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Get contact - if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) { + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) + { $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL'); - if (count($arrayidcontact) > 0) { + if (count($arrayidcontact) > 0) + { $usertmp = new User($this->db); $usertmp->fetch($arrayidcontact[0]); $posy += 4; @@ -1307,11 +1420,13 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Show list of linked objects $current_y = $pdf->getY(); $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); - if ($current_y < $pdf->getY()) { + if ($current_y < $pdf->getY()) + { $top_shift = $pdf->getY() - $current_y; } - if ($showaddress) { + if ($showaddress) + { // Sender properties $carac_emetteur = ''; // Add internal contact of origin element if defined @@ -1319,7 +1434,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes $arrayidcontact = $object->getIdContact('external', 'STFROM'); $usecontact = false; - if (count($arrayidcontact) > 0) { + if (count($arrayidcontact) > 0) + { /*$object->fetch_user(reset($arrayidcontact)); $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ $usecontact = true; @@ -1329,9 +1445,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes if ($usecontact) $thirdparty = $object->contact; else $thirdparty = $this->emetteur; - if (!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - if ($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); // Show sender @@ -1368,7 +1484,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes // If SHIPPING contact defined, we use it $usecontact = false; $arrayidcontact = $object->getIdContact('external', 'STDEST'); - if (count($arrayidcontact) > 0) { + if (count($arrayidcontact) > 0) + { $usecontact = true; $result = $object->fetch_contact($arrayidcontact[0]); } @@ -1381,7 +1498,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $thirdparty = $object->thirdparty; } - if (!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); @@ -1514,7 +1631,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes 'border-left' => false, // remove left line separator ); - if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) { + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) + { $this->cols['photo']['status'] = true; } @@ -1541,7 +1659,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes 'width' => 19, // in mm 'status' => true, 'title' => array( - 'textkey' => 'PriceUHT' + 'textkey' => 'PMPValueShort' ), 'border-left' => true, // add left line separator ); @@ -1602,7 +1720,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes 'width' => 26, // in mm 'status' => true, 'title' => array( - 'textkey' => 'TotalHT' + 'textkey' => 'PMPValue' ), 'border-left' => true, // add left line separator ); @@ -1622,11 +1740,16 @@ class pdf_eagle_proforma extends ModelePDFCommandes ); $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook - if ($reshook < 0) { + if ($reshook < 0) + { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - } elseif (empty($reshook)) { + } + elseif (empty($reshook)) + { $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys - } else { + } + else + { $this->cols = $hookmanager->resArray; } } diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 8a7432c4317..ea869635e56 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -24,14 +24,14 @@ */ // Put here all includes required by your class file -require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; /** * Class for StockTransferLine */ -class StockTransferLine extends CommonObject +class StockTransferLine extends CommonObjectLine { /** * @var string ID to identify managed object. diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index a1c1cd930cd..e801209ea84 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -1,6 +1,5 @@ - * Copyright (C) 2021 Gauthier VERDOL * Copyright (C) ---Put here your own copyright and developer email--- * * This program is free software; you can redistribute it and/or modify @@ -62,6 +61,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php'; @@ -102,7 +102,8 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Initialize array of search criterias $search_all = trim(GETPOST("search_all", 'alpha')); $search = array(); -foreach ($object->fields as $key => $val) { +foreach ($object->fields as $key => $val) +{ if (GETPOST('search_'.$key, 'alpha')) $search[$key] = GETPOST('search_'.$key, 'alpha'); } @@ -140,15 +141,16 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if (empty($reshook)) { +if (empty($reshook)) +{ $error = 0; - $backurlforlist = dol_buildpath('/product/stock/stocktransfer/stocktransfer_list.php', 1); + $backurlforlist = dol_buildpath('/stocktransfer/stocktransfer_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('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + else $backtopage = dol_buildpath('/stocktransfer/stocktransfer_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); } } $triggermodname = 'STOCKTRANSFER_STOCKTRANSFER_MODIFY'; // Name of trigger action code to execute when we modify record @@ -168,27 +170,30 @@ if (empty($reshook)) { // Action to build doc include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - if ($action == 'set_thirdparty' && $permissiontoadd) { + if ($action == 'set_thirdparty' && $permissiontoadd) + { $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'STOCKTRANSFER_MODIFY'); } - if ($action == 'classin' && $permissiontoadd) { + if ($action == 'classin' && $permissiontoadd) + { $object->setProject(GETPOST('projectid', 'int')); } - if ($action == 'addline' && $permissiontoadd) { - if ($qty <= 0) { + if($action == 'addline' && $permissiontoadd) { + + if($qty <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); $action = 'view'; } - if ($fk_warehouse_source <= 0) { + if($fk_warehouse_source <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); $action = 'view'; } - if ($fk_warehouse_destination <= 0) { + if($fk_warehouse_destination <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); $action = 'view'; @@ -196,23 +201,25 @@ if (empty($reshook)) { $prod = new Product($db); $prod->fetch($fk_product); - if ($prod->hasbatch()) { - if (empty($batch)) { + if ($prod->hasbatch()) + { + if (empty($batch)) + { $error++; $langs->load("errors"); - setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->getNomUrl()), null, 'errors'); + setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); } } else { - if (!empty($batch)) { + if(!empty($batch)) { $error++; - setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); + setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); } } - if (empty($error)) { + if(empty($error)) { $line = new StockTransferLine($db); $records = $line->fetchAll('', '', 0, 0, array('customsql'=>' fk_stocktransfer = '.$id.' AND fk_product = '.$fk_product.' AND fk_warehouse_source = '.$fk_warehouse_source.' AND fk_warehouse_destination = '.$fk_warehouse_destination.' AND ('.(empty($batch) ? 'batch = "" or batch IS NULL' : 'batch = "'.$batch.'"' ).')')); - if (!empty($records[key($records)])) $line = $records[key($records)]; + if(!empty($records[key($records)])) $line = $records[key($records)]; $line->fk_stocktransfer = $id; $line->qty += $qty; $line->fk_warehouse_source = $fk_warehouse_source; @@ -221,27 +228,28 @@ if (empty($reshook)) { $line->batch = $batch; $line->pmp = $prod->pmp; - if ($line->id > 0) $line->update($user); + if($line->id > 0) $line->update($user); else { $line->rang = count($object->lines) + 1; $line->create($user); } $object->fetchLines(); } - } elseif ($action === 'updateline' && $permissiontoadd) { - if ($qty <= 0) { + } elseif($action === 'updateline' && $permissiontoadd) { + + if($qty <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); $action = 'editline'; } - if ($fk_warehouse_source <= 0) { + if($fk_warehouse_source <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); $action = 'editline'; } - if ($fk_warehouse_destination <= 0) { + if($fk_warehouse_destination <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); $action = 'editline'; @@ -249,22 +257,24 @@ if (empty($reshook)) { $prod = new Product($db); $prod->fetch($fk_product); - if ($prod->hasbatch()) { - if (empty($batch)) { + if ($prod->hasbatch()) + { + if (empty($batch)) + { $error++; $langs->load("errors"); setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); $action = 'editline'; } } else { - if (!empty($batch)) { + if(!empty($batch)) { $error++; setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); $action = 'editline'; } } - if (empty($error)) { + if(empty($error)) { $line = new StockTransferLine($db); $line->fetch($lineid); $line->qty = $qty; @@ -278,18 +288,18 @@ if (empty($reshook)) { } // Décrémentation - if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { + if($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { $lines = $object->getLinesArray(); - if (!empty($lines)) { + if(!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_source); - if ($res <= 0) $error++; + if($res <= 0) $error++; } - if (empty($error)) $db->commit(); + if(empty($error)) $db->commit(); else $db->rollback(); } - if (empty($error)) { + if(empty($error)) { $object->setStatut($object::STATUS_TRANSFERED, $id); $object->status = $object::STATUS_TRANSFERED; $object->date_reelle_depart = date('Y-m-d'); @@ -299,18 +309,18 @@ if (empty($reshook)) { } // Annulation décrémentation - if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + if($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { $lines = $object->getLinesArray(); - if (!empty($lines)) { + if(!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_source, 0); - if ($res <= 0) $error++; + if($res <= 0) $error++; } - if (empty($error)) $db->commit(); + if(empty($error)) $db->commit(); else $db->rollback(); } - if (empty($error)) { + if(empty($error)) { $object->setStatut($object::STATUS_VALIDATED, $id); $object->status = $object::STATUS_VALIDATED; $object->date_reelle_depart = null; @@ -320,18 +330,18 @@ if (empty($reshook)) { } // Incrémentation - if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + if($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { $lines = $object->getLinesArray(); - if (!empty($lines)) { + if(!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_destination, 0); - if ($res <= 0) $error++; + if($res <= 0) $error++; } - if (empty($error)) $db->commit(); + if(empty($error)) $db->commit(); else $db->rollback(); } - if (empty($error)) { + if(empty($error)) { $object->setStatut($object::STATUS_CLOSED, $id); $object->status = $object::STATUS_CLOSED; $object->date_reelle_arrivee = date('Y-m-d'); @@ -341,18 +351,18 @@ if (empty($reshook)) { } // Annulation incrémentation - if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { + if($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { $lines = $object->getLinesArray(); - if (!empty($lines)) { + if(!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_destination); - if ($res <= 0) $error++; + if($res <= 0) $error++; } - if (empty($error)) $db->commit(); + if(empty($error)) $db->commit(); else $db->rollback(); } - if (empty($error)) { + if(empty($error)) { $object->setStatut($object::STATUS_TRANSFERED, $id); $object->status = $object::STATUS_TRANSFERED; $object->date_reelle_arrivee = null; @@ -390,8 +400,8 @@ jQuery(document).ready(function() {'; // Affichage alerte date prévue de départ si transfert concerné $date_prevue_depart = $object->date_prevue_depart; $date_prevue_depart_plus_delai = $date_prevue_depart; -if ($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); -if (!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) { +if($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); +if(!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) { print "$('.valuefield.fieldname_date_prevue_depart').append('"; print img_warning($langs->trans('Alert').' - '.$langs->trans('Late')); print "');"; @@ -402,7 +412,8 @@ print '}); // Part to create -if ($action == 'create') { +if ($action == 'create') +{ print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("StockTransfer")), '', 'object_'.$object->picto); print '
'; @@ -450,41 +461,43 @@ if ($action == 'create') { } // Part to edit record -if (($id || $ref) && $action == 'edit') { +if (($id || $ref) && $action == 'edit') +{ //if($object->status < 3) { - print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto); + print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto); - print ''; - print ''; - print ''; - print ''; - if ($backtopage) print ''; - if ($backtopageforcancel) print ''; + print ''; + print ''; + print ''; + print ''; + if ($backtopage) print ''; + if ($backtopageforcancel) print ''; - dol_fiche_head(); + dol_fiche_head(); - print '
'; if (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth75'); elseif (strpos($val['type'], 'integer:') === 0) { print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth150', 1); - } - elseif (!preg_match('/^(date|timestamp)/', $val['type'])) print ''; + } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) print ''; print '
'; - if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - { + 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 ''; @@ -563,8 +529,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; // If no record found -if ($num == 0) -{ +if ($num == 0) { $colspan = 1; foreach ($arrayfields as $key => $val) { if (!empty($val['checked'])) $colspan++; } print '
'.$langs->trans("NoRecordFound").'
'; - $constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON'; + $constforvar = strtoupper($myTmpObjectKey).'_ADDON_PDF'; 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 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print '
'.$langs->trans('DefaultModel').''; + print img_picto('', 'pdf', 'class="pictofixedwidth"'); + include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php'; + $liste = ModelePDFStockTransfer::liste_modeles($db); + $preselected = $conf->global->STOCKTRANSFER_ADDON_PDF; + print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1); + print "
' . "\n"; + print '
' . "\n"; - // Common attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php'; + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php'; - // Other attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php'; - print '
'; + print ''; - dol_fiche_end(); + dol_fiche_end(); - print '
'; - print '   '; - print '
'; + print '
'; + print '   '; + print '
'; - print ''; + print ''; //} else $action = 'view'; } // Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) +{ $res = $object->fetch_optionals(); $head = stocktransferPrepareHead($object); @@ -493,11 +506,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formconfirm = ''; // Confirmation to delete - if ($action == 'delete') { + if ($action == 'delete') + { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteStockTransfer'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); } // Confirmation to delete line - if ($action == 'deleteline') { + if ($action == 'deleteline') + { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); } // Clone confirmation @@ -505,22 +520,30 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // 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); - } elseif ($action == 'destock') { // Destock confirmation + } + // Destock confirmation + elseif ($action == 'destock') { // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1); - } elseif ($action == 'destockcancel') { // Destock confirmation cancel + } + // Destock confirmation cancel + elseif ($action == 'destockcancel') { // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1); - } elseif ($action == 'addstock') { // Addstock confirmation + } + // Addstock confirmation + elseif ($action == 'addstock') { // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1); - } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel + } + // Addstock confirmation cancel + elseif ($action == 'addstockcancel') { // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40)); @@ -528,7 +551,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Confirmation of action xxxx - if ($action == 'xxx') { + if ($action == 'xxx') + { $formquestion = array(); /* $forcecombo=0; @@ -546,7 +570,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($action == 'valid' && $permissiontoadd) { $nextref=$object->getNextNumRef(); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->transnoentities('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->trans('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2); } // Call Hook formConfirm @@ -561,18 +585,20 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; - if ($conf->societe->enabled) { - // Thirdparty + + // Thirdparty + if($conf->societe->enabled) { $morehtmlref .= $langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '').'
'; } - // Project + // Project if (! empty($conf->projet->enabled)) { $langs->load("projects"); $morehtmlref.=$langs->trans('Project') . ' '; - if ($permissiontoadd) { + if ($permissiontoadd) + { //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; $morehtmlref.=' : '; if ($action == 'classify') { @@ -636,7 +662,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea * Lines */ - if (!empty($object->table_element_line)) { + if (!empty($object->table_element_line)) + { // Show object lines /*$result = $object->getLinesArray(); @@ -693,14 +720,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea '; - if ($lineid > 0) print ''; + if($lineid > 0) print ''; print ''; - //print '
'; +//print '
'; $param = ''; - $conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE=true; // Full display needed to see all column title details - print '
'; print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); if ($conf->productbatch->enabled) { @@ -709,9 +734,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print getTitleFieldOfList($langs->trans('WarehouseSource'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); + if ($conf->global->PRODUCT_USE_UNITS) { + print getTitleFieldOfList($langs->trans('Unit'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); + } print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); - print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); - if (empty($object->status)) { + print getTitleFieldOfList($langs->trans('PMPValue'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); + if(empty($object->status)) { print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); @@ -724,7 +752,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $warehousestatics = new Entrepot($db); $warehousestatict = new Entrepot($db); - foreach ($listofdata as $key => $line) { + foreach ($listofdata as $key => $line) + { $productstatic->fetch($line->fk_product); $warehousestatics->fetch($line->fk_warehouse_source); $warehousestatict->fetch($line->fk_warehouse_destination); @@ -737,33 +766,53 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; - if ($conf->productbatch->enabled) { + if ($conf->productbatch->enabled) + { print ''; } + print ''; print ''; - if ($action === 'editline' && $line->id == $lineid) print ''; + if($action === 'editline' && $line->id == $lineid) print ''; else print ''; + + if ($conf->global->PRODUCT_USE_UNITS) + { + print ''; + } + print ''; print ''; - if (empty($object->status)) { - if ($action === 'editline' && $line->id == $lineid) { + if(empty($object->status)) { + + if($action === 'editline' && $line->id == $lineid) { //print ''; print ''; @@ -802,9 +851,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; } - if (empty($object->status) && $action !== 'editline') { + if(empty($object->status) && $action !== 'editline') { print ''; - // Product +// Product print ''; // PMP print ''; + if($conf->global->PRODUCT_USE_UNITS) { + // Unité + print ''; + } // PMP * Qty print ''; // Button to add line @@ -870,6 +923,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Grad and drop lines print ''; print ''; + } print '
'; - if ($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); + if($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); else print $productstatic->getNomUrl(1).' - '.$productstatic->label; print ''; - if ($action === 'editline' && $line->id == $lineid) print ''; - else print $line->batch; + if($action === 'editline' && $line->id == $lineid) print ''; + else { + $productlot = new Productlot($db); + if($productlot->fetch(0, $line->fk_product, $line->batch) > 0) { + print $productlot->getNomUrl(1); + } elseif(!empty($line->batch)) print $line->batch.' '.img_warning($langs->trans('BatchNotFound'));; + } print ''; - if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); + + if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); else print $warehousestatics->getNomUrl(1); print ''; - if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); + if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination,'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); else print $warehousestatict->getNomUrl(1); print ''.$line->qty.''; + $label = $productstatic->getLabelOfUnit('short'); + if ($label !== '') { + print $langs->trans($label); + } + print ''; print price($line->pmp, 0, '', 1, -1, -1, $conf->currency); print ''; print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency); print '
'; print '
'; $filtertype = 0; if (!empty($conf->global->STOCK_SUPPORTS_SERVICES)) $filtertype = ''; @@ -827,21 +876,21 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // On stock ceux qui ne doivent pas être proposés dans la liste $TExcludedWarehouseSource=array(); - if (!empty($object->fk_warehouse_source)) { + if(!empty($object->fk_warehouse_source)) { $source_ent = new Entrepot($db); $source_ent->fetch($object->fk_warehouse_source); foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { - if (strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id']; + if(strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id']; } } // On stock ceux qui ne doivent pas être proposés dans la liste $TExcludedWarehouseDestination=array(); - if (!empty($object->fk_warehouse_destination)) { + if(!empty($object->fk_warehouse_destination)) { $dest_ent = new Entrepot($db); $dest_ent->fetch($object->fk_warehouse_destination); foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { - if (strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id']; + if(strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id']; } } @@ -863,6 +912,10 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; @@ -884,21 +938,25 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $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)) { + if (empty($reshook)) + { // Send if (empty($user->socid)) { print ''.$langs->trans('SendMail').''."\n"; } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) { - if ($permissiontoadd) { + if ($object->status == $object::STATUS_VALIDATED) + { + if ($permissiontoadd) + { print ''.$langs->trans("SetToDraft").''; } } // Modify - if ($permissiontoadd) { + if ($permissiontoadd) + { print ''.$langs->trans("Modify").''."\n"; } /*else @@ -907,26 +965,38 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea }*/ // Validate - if ($object->status == $object::STATUS_DRAFT) { - if ($permissiontoadd) { - if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { + if ($object->status == $object::STATUS_DRAFT) + { + if ($permissiontoadd) + { + if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) + { print ''.$langs->trans("Validate").''; - } else { + } + else + { $langs->load("errors"); print ''.$langs->trans("Validate").''; } } - } elseif ($object->status == $object::STATUS_VALIDATED) { + } + + elseif($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("StockTransferDecrementation").''; - } elseif ($object->status == $object::STATUS_TRANSFERED) { + } + + elseif($object->status == $object::STATUS_TRANSFERED) { print ''.$langs->trans("StockTransferDecrementationCancel").''; print ''.$langs->trans("StockTransferIncrementation").''; - } elseif ($object->status == $object::STATUS_CLOSED) { + } + + elseif($object->status == $object::STATUS_CLOSED) { print ''.$langs->trans("StockTransferIncrementationCancel").''; } // Clone - if ($permissiontoadd) { + if ($permissiontoadd) + { print ''.$langs->trans("ToClone").''."\n"; } @@ -956,7 +1026,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea */ // Delete (need delete permission, or if draft, just need create/modify permission) - if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) { + if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) + { print ''.$langs->trans('Delete').''."\n"; } /*else @@ -973,7 +1044,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $action = 'presend'; } - if ($action != 'presend') { + if ($action != 'presend') + { print '
'; print ''; // ancre @@ -999,7 +1071,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $MAXEVENT = 10; - $morehtmlright = ''; + $morehtmlright = ''; $morehtmlright .= $langs->trans("SeeAll"); $morehtmlright .= ''; From ee52fc162c480989d17432c10135b5404cd29c0e Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Tue, 3 Aug 2021 16:36:27 +0200 Subject: [PATCH 014/128] FIX : tms on update current timestamp + wrong links --- .../install/mysql/migration/14.0.0-15.0.0.sql | 2 +- .../llx_stocktransfer_stocktransfer.sql | 2 +- .../class/stocktransfer.class.php | 1 + .../stocktransfer/stocktransfer_card.php | 20 ++++++++++--------- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index d0bcd17acd1..b7dc8b1f64d 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -54,7 +54,7 @@ CREATE TABLE llx_stocktransfer_stocktransfer( description text, note_public text, note_private text, - tms timestamp, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, date_creation datetime NOT NULL, date_prevue_depart date DEFAULT NULL, date_reelle_depart date DEFAULT NULL, diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql index 6b0607d66c2..a891fdc2f5d 100644 --- a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql @@ -27,7 +27,7 @@ CREATE TABLE llx_stocktransfer_stocktransfer( description text, note_public text, note_private text, - tms timestamp, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, date_creation datetime NOT NULL, date_prevue_depart date DEFAULT NULL, date_reelle_depart date DEFAULT NULL, diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 54fcbfc32e5..d34666b7cb2 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -466,6 +466,7 @@ class StockTransfer extends CommonObject */ public function update(User $user, $notrigger = false) { + $this->tms = ''; // Will be done automatically because tms field is on update cascade $res = $this->updateCommon($user, $notrigger); if ($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty(); if (empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index e801209ea84..ae80b55b51d 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -145,12 +145,12 @@ if (empty($reshook)) { $error = 0; - $backurlforlist = dol_buildpath('/stocktransfer/stocktransfer_list.php', 1); + $backurlforlist = dol_buildpath('/product/stock/stocktransfer/stocktransfer_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('/stocktransfer/stocktransfer_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + else $backtopage = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); } } $triggermodname = 'STOCKTRANSFER_STOCKTRANSFER_MODIFY'; // Name of trigger action code to execute when we modify record @@ -207,12 +207,12 @@ if (empty($reshook)) { $error++; $langs->load("errors"); - setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); + setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); } } else { if(!empty($batch)) { $error++; - setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); + setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); } } @@ -508,7 +508,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Confirmation to delete if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteStockTransfer'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Delete'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); } // Confirmation to delete line if ($action == 'deleteline') @@ -570,7 +570,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($action == 'valid' && $permissiontoadd) { $nextref=$object->getNextNumRef(); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->trans('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->transnoentities('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2); } // Call Hook formConfirm @@ -585,7 +585,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; @@ -726,6 +726,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $param = ''; + $conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE=true; // Full display needed to see all column title details + print ''; print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); if ($conf->productbatch->enabled) { @@ -738,7 +740,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print getTitleFieldOfList($langs->trans('Unit'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone '); } print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); - print getTitleFieldOfList($langs->trans('PMPValue'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); + print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); if(empty($object->status)) { print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); @@ -1071,7 +1073,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $MAXEVENT = 10; - $morehtmlright = ''; + $morehtmlright = ''; $morehtmlright .= $langs->trans("SeeAll"); $morehtmlright .= ''; From 257793667074ec5bbbcbe6152cb0a6a65e182902 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 3 Aug 2021 14:39:28 +0000 Subject: [PATCH 015/128] Fixing style errors. --- .../stocktransfer/doc/pdf_eagle.modules.php | 292 +++++---------- .../doc/pdf_eagle_proforma.modules.php | 353 ++++++------------ .../stocktransfer/stocktransfer_card.php | 219 +++++------ 3 files changed, 304 insertions(+), 560 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 2c1d647f659..ccdfee026d0 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -211,23 +211,18 @@ class pdf_eagle extends ModelePdfStockTransfer // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); - if (!empty($conf->global->MAIN_GENERATE_STOCKTRANSFER_WITH_PICTURE)) - { + if (!empty($conf->global->MAIN_GENERATE_STOCKTRANSFER_WITH_PICTURE)) { $objphoto = new Product($this->db); - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { if (empty($object->lines[$i]->fk_product)) continue; $objphoto = new Product($this->db); $objphoto->fetch($object->lines[$i]->fk_product); - if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) - { + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/"; $dir = $conf->product->dir_output.'/'.$pdir; - } - else - { + } else { $pdir = get_exdir(0, 2, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; $dir = $conf->product->dir_output.'/'.$pdir; } @@ -237,17 +232,12 @@ class pdf_eagle extends ModelePdfStockTransfer foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo - if ($obj['photo_vignette']) - { + if ($obj['photo_vignette']) { $filename = $obj['photo_vignette']; - } - else - { + } else { $filename = $obj['photo']; } - } - else - { + } else { $filename = $obj['photo']; } @@ -262,40 +252,32 @@ class pdf_eagle extends ModelePdfStockTransfer if (count($realpatharray) == 0) $this->posxpicture = $this->posxweightvol; - if(!empty($this->atLeastOneBatch)) { + if (!empty($this->atLeastOneBatch)) { $this->posxpicture = $this->posxlot; - if(!empty($conf->global->MAIN_GENERATE_STOCKTRANSFER_WITH_PICTURE)) $this->posxpicture -= (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images + if (!empty($conf->global->MAIN_GENERATE_STOCKTRANSFER_WITH_PICTURE)) $this->posxpicture -= (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images } - if ($conf->stocktransfer->dir_output) - { + if ($conf->stocktransfer->dir_output) { // Definition de $dir et $file - if ($object->specimen) - { + if ($object->specimen) { $dir = $conf->stocktransfer->dir_output; $file = $dir."/SPECIMEN.pdf"; - } - else - { + } else { $stocktransferref = dol_sanitizeFileName($object->ref); $dir = $conf->stocktransfer->dir_output.'/'.$object->element."/".$stocktransferref; $file = $dir."/".$stocktransferref.".pdf"; } - if (!file_exists($dir)) - { - if (dol_mkdir($dir) < 0) - { + if (!file_exists($dir)) { + if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } - if (file_exists($dir)) - { + if (file_exists($dir)) { // Add pdfgeneration hook - if (!is_object($hookmanager)) - { + if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } @@ -315,15 +297,13 @@ class pdf_eagle extends ModelePdfStockTransfer if ($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS > 0) $heightforfooter += 6; $pdf->SetAutoPageBreak(1, 0); - if (class_exists('TCPDF')) - { + if (class_exists('TCPDF')) { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File - if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) - { + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } @@ -359,11 +339,9 @@ class pdf_eagle extends ModelePdfStockTransfer // Incoterm $height_incoterms = 0; - if ($conf->incoterm->enabled) - { + if ($conf->incoterm->enabled) { $desc_incoterms = $object->getIncotermsForPDF(); - if ($desc_incoterms) - { + if ($desc_incoterms) { $tab_top = 88; $pdf->SetFont('', '', $default_font_size - 1); @@ -380,8 +358,7 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if (!empty($object->note_public) || !empty($object->tracking_number)) - { + if (!empty($object->note_public) || !empty($object->tracking_number)) { $tab_top = 88 + $height_incoterms; $tab_top_alt = $tab_top; @@ -390,24 +367,20 @@ class pdf_eagle extends ModelePdfStockTransfer //$tab_top_alt += 1; // Tracking number - if (!empty($object->tracking_number)) - { + if (!empty($object->tracking_number)) { $pdf->writeHTMLCell(60, 4, $this->posxdesc - 1, $tab_top - 1, $outputlangs->transnoentities("TrackingNumber")." : ".$object->tracking_number, 0, 1, false, true, 'L'); $tab_top_alt = $pdf->GetY(); $object->getUrlTrackingStatus($object->tracking_number); - if (!empty($object->tracking_url)) - { - if ($object->shipping_method_id > 0) - { + if (!empty($object->tracking_url)) { + if ($object->shipping_method_id > 0) { // Get code using getLabelFromKey $code = $outputlangs->getLabelFromKey($this->db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); $label = ''; if ($object->tracking_url != $object->tracking_number) $label .= $outputlangs->trans("LinkToTrackYourPackage")."
"; $label .= $outputlangs->trans("SendingMethod").": ".$outputlangs->trans("SendingMethod".strtoupper($code)); //var_dump($object->tracking_url != $object->tracking_number);exit; - if ($object->tracking_url != $object->tracking_number) - { + if ($object->tracking_url != $object->tracking_number) { $label .= " : "; $label .= $object->tracking_url; } @@ -420,8 +393,7 @@ class pdf_eagle extends ModelePdfStockTransfer } // Notes - if (!empty($object->note_public)) - { + if (!empty($object->note_public)) { $pdf->SetFont('', '', $default_font_size - 1); // Dans boucle pour gerer multi-page $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1); } @@ -435,9 +407,7 @@ class pdf_eagle extends ModelePdfStockTransfer $tab_height = $tab_height - $height_note; $tab_top = $nexY + 6; - } - else - { + } else { $height_note = 0; } @@ -447,8 +417,7 @@ class pdf_eagle extends ModelePdfStockTransfer $TCacheEntrepots=array(); // Loop on each lines - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -466,8 +435,7 @@ class pdf_eagle extends ModelePdfStockTransfer $posYAfterDescription = 0; // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page - { + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); @@ -478,12 +446,10 @@ class pdf_eagle extends ModelePdfStockTransfer // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - if (isset($imglinesize['width']) && isset($imglinesize['height'])) - { + if (isset($imglinesize['width']) && isset($imglinesize['height'])) { $curX = $this->posxpicture - 1; $pdf->Image($realpatharray[$i], $curX + (($this->posxqty - $this->posxweightvol - $imglinesize['width'] + (!empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME) ? (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) : 0)) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi @@ -495,7 +461,7 @@ class pdf_eagle extends ModelePdfStockTransfer $curX = $this->posxdesc - 1; $pdf->startTransaction(); - if(method_exists($object->lines[$i], 'fetch_product')) { + if (method_exists($object->lines[$i], 'fetch_product')) { $object->lines[$i]->fetch_product(); $object->lines[$i]->label = $object->lines[$i]->product->label; $object->lines[$i]->description = $object->lines[$i]->product->description; @@ -514,8 +480,7 @@ class pdf_eagle extends ModelePdfStockTransfer pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); - if ($pageposafter > $pageposbefore) // There is a pagebreak - { + if ($pageposafter > $pageposbefore) { // There is a pagebreak $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; @@ -525,28 +490,22 @@ class pdf_eagle extends ModelePdfStockTransfer $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text - { - if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text + if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $pdf->setPage($pageposafter + 1); } - } - else - { + } else { // We found a page break // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - } - else // No pagebreak + } else // No pagebreak { $pdf->commitTransaction(); } @@ -572,7 +531,7 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut // Lot / série - if(!empty($conf->productbatch->enabled)) { + if (!empty($conf->productbatch->enabled)) { $pdf->SetXY($this->posxlot, $curY); $pdf->MultiCell(($this->posxweightvol - $this->posxlot), 3, $object->lines[$i]->batch, '', 'C'); } @@ -580,19 +539,16 @@ class pdf_eagle extends ModelePdfStockTransfer // Weight $pdf->SetXY($this->posxweightvol, $curY); $weighttxt = ''; - if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight) - { + if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight) { $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1); } $voltxt = ''; - if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume) - { + if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume) { $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1); } // Weight - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) - { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) { $pdf->writeHTMLCell($this->posxqty - $this->posxweightvol + 2, 3, $this->posxweightvol - 1, $curY, $weighttxt.(($weighttxt && $voltxt) ? '
' : '').$voltxt, 0, 0, false, true, 'C'); //$pdf->MultiCell(($this->posxqtyordered - $this->posxweightvol), 3, $weighttxt.(($weighttxt && $voltxt)?'
':'').$voltxt,'','C'); } @@ -604,7 +560,7 @@ class pdf_eagle extends ModelePdfStockTransfer // Warehouse source $wh_source = new Entrepot($db); - if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_source])) $wh_source = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source]; + if (!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_source])) $wh_source = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source]; else { $wh_source->fetch($object->lines[$i]->fk_warehouse_source); $TCacheEntrepots[$object->lines[$i]->fk_warehouse_source] = $wh_source; @@ -614,7 +570,7 @@ class pdf_eagle extends ModelePdfStockTransfer // Warehouse destination $wh_destination = new Entrepot($db); - if(!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination])) $wh_destination = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination]; + if (!empty($TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination])) $wh_destination = $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination]; else { $wh_destination->fetch($object->lines[$i]->fk_warehouse_destination); $TCacheEntrepots[$object->lines[$i]->fk_warehouse_destination] = $wh_destination; @@ -622,8 +578,7 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetXY($this->posxwarehousedestination, $curY); $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination), 3, $wh_destination->ref.(!empty($wh_destination->lieu) ? ' - '.$wh_destination->lieu : ''), '', 'C'); - if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) - { + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { $pdf->SetXY($this->posxpuht, $curY); $pdf->MultiCell(($this->posxtotalht - $this->posxpuht - 1), 3, price($object->lines[$i]->subprice, 0, $outputlangs), '', 'R'); @@ -635,8 +590,7 @@ class pdf_eagle extends ModelePdfStockTransfer if ($weighttxt && $voltxt) $nexY += 2; // Add line - if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) - { + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); @@ -645,15 +599,11 @@ class pdf_eagle extends ModelePdfStockTransfer } // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) - { + while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); - if ($pagenb == 1) - { + if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -662,14 +612,10 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) - { - if ($pagenb == 1) - { + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { + if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -682,13 +628,10 @@ class pdf_eagle extends ModelePdfStockTransfer } // Show square - if ($pagenb == 1) - { + if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } @@ -709,8 +652,7 @@ class pdf_eagle extends ModelePdfStockTransfer $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) - { + if ($reshook < 0) { $this->error = $hookmanager->error; $this->errors = $hookmanager->errors; } @@ -721,15 +663,11 @@ class pdf_eagle extends ModelePdfStockTransfer $this->result = array('fullpath'=>$file); return 1; // No error - } - else - { + } else { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } - } - else - { + } else { $this->error = $langs->transnoentities("ErrorConstantNotDefined", "EXP_OUTPUTDIR"); return 0; } @@ -780,13 +718,12 @@ class pdf_eagle extends ModelePdfStockTransfer $totalWeight = $tmparray['weight']; $totalVolume = $tmparray['volume']; $totalQty = 0; - if(!empty($object->lines)) - foreach ($object->lines as $line) { - $totalQty+=$line->qty; - } + if (!empty($object->lines)) + foreach ($object->lines as $line) { + $totalQty+=$line->qty; + } // Set trueVolume and volume_units not currently stored into database - if ($object->trueWidth && $object->trueHeight && $object->trueDepth) - { + if ($object->trueWidth && $object->trueHeight && $object->trueDepth) { $object->trueVolume = price(($object->trueWidth * $object->trueHeight * $object->trueDepth), 0, $outputlangs, 0, 0); $object->volume_units = $object->size_units * 3; } @@ -800,14 +737,12 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Total"), 0, 'L', 1); - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) - { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_ORDERED)) { $pdf->SetXY($this->posxqty, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($this->posxwarehousesource - $this->posxqty, $tab2_hl, $totalQty, 0, 'C', 1); } - if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) - { + if (!empty($conf->global->STOCKTRANSFER_PDF_DISPLAY_AMOUNT_HT)) { $pdf->SetXY($this->posxpuht, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($this->posxtotalht - $this->posxpuht, $tab2_hl, '', 0, 'C', 1); @@ -815,18 +750,15 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxtotalht, $tab2_hl, price($object->total_ht, 0, $outputlangs), 0, 'C', 1); } - if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) - { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) { // Total Weight - if ($totalWeighttoshow) - { + if ($totalWeighttoshow) { $pdf->SetXY($this->posxweightvol, $tab2_top + $tab2_hl * $index); $pdf->MultiCell(($this->posxqty - $this->posxweightvol), $tab2_hl, $totalWeighttoshow, 0, 'C', 1); $index++; } - if ($totalVolumetoshow) - { + if ($totalVolumetoshow) { $pdf->SetXY($this->posxweightvol, $tab2_top + $tab2_hl * $index); $pdf->MultiCell(($this->posxqty - $this->posxweightvol), $tab2_hl, $totalVolumetoshow, 0, 'C', 1); @@ -873,15 +805,14 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetDrawColor(128, 128, 128); $pdf->SetFont('', '', $default_font_size - 1); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5); $pdf->SetXY($this->posxdesc - 1, $tab_top + 1); $pdf->MultiCell($this->posxlot - $this->posxdesc, 2, $outputlangs->transnoentities("Description"), '', 'L'); } - if(!empty($conf->productbatch->enabled) && $this->atLeastOneBatch) { + if (!empty($conf->productbatch->enabled) && $this->atLeastOneBatch) { $pdf->line($this->posxlot - 1, $tab_top, $this->posxlot - 1, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxlot, $tab_top + 1); @@ -889,7 +820,7 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if(empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) { + if (empty($conf->global->STOCKTRANSFER_PDF_HIDE_WEIGHT_AND_VOLUME)) { $pdf->line($this->posxweightvol - 1, $tab_top, $this->posxweightvol - 1, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxweightvol - 1, $tab_top + 1); @@ -898,23 +829,20 @@ class pdf_eagle extends ModelePdfStockTransfer } $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->SetXY($this->posxqty - 1, $tab_top + 1); $pdf->MultiCell(($this->posxwarehousesource - $this->posxqty), 2, $outputlangs->transnoentities("Qty"), '', 'C'); } $pdf->line($this->posxwarehousesource - 1, $tab_top, $this->posxwarehousesource - 1, $tab_top + $tab_height); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->SetXY($this->posxwarehousesource - 1, $tab_top + 1); $pdf->MultiCell(($this->posxwarehousedestination - $this->posxwarehousesource), 2, $outputlangs->transnoentities("WarehouseSource"), '', 'C'); } $pdf->line($this->posxwarehousedestination - 1, $tab_top, $this->posxwarehousedestination - 1, $tab_top + $tab_height); - if (empty($hidetop)) - { + if (empty($hidetop)) { $pdf->SetXY($this->posxwarehousedestination-2.5, $tab_top + 1); $pdf->MultiCell(($this->posxpuht - $this->posxwarehousedestination+4), 2, $outputlangs->transnoentities("WarehouseTarget"), '', 'C'); } @@ -936,22 +864,22 @@ class pdf_eagle extends ModelePdfStockTransfer }*/ } - function atLeastOneBatch($object) { + function atLeastOneBatch($object) + { global $conf; $atLeastOneBatch = false; - if(empty($conf->productbatch->enabled)) return false; + if (empty($conf->productbatch->enabled)) return false; foreach ($object->lines as $line) { - if(!empty($line->batch)) { + if (!empty($line->batch)) { return true; } } return false; - } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore @@ -975,8 +903,7 @@ class pdf_eagle extends ModelePdfStockTransfer pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); // Show Draft Watermark - if ($object->statut == 0 && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) - { + if ($object->statut == 0 && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) { pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->SHIPPING_DRAFT_WATERMARK); } @@ -993,47 +920,36 @@ class pdf_eagle extends ModelePdfStockTransfer // Logo $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; - if ($this->emetteur->logo) - { - if (is_readable($logo)) - { + if ($this->emetteur->logo) { + if (is_readable($logo)) { $height = pdf_getHeightForLogo($logo); $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) - } - else - { + } else { $pdf->SetTextColor(200, 0, 0); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } - } - else - { + } else { $text = $this->emetteur->name; $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); } // Show barcode - if (!empty($conf->barcode->enabled)) - { + if (!empty($conf->barcode->enabled)) { $posx = 105; - } - else - { + } else { $posx = $this->marge_gauche + 3; } //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); - if (!empty($conf->barcode->enabled)) - { + if (!empty($conf->barcode->enabled)) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); } $pdf->SetDrawColor(128, 128, 128); - if (!empty($conf->barcode->enabled)) - { + if (!empty($conf->barcode->enabled)) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); @@ -1058,8 +974,7 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->MultiCell($w, 4, $outputlangs->transnoentities("Ref")." : ".$object->ref, '', 'R'); // Date prévue depart - if (!empty($object->date_prevue_depart)) - { + if (!empty($object->date_prevue_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1067,8 +982,7 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date prévue arrivée - if (!empty($object->date_prevue_arrivee)) - { + if (!empty($object->date_prevue_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1076,8 +990,7 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date reelle depart - if (!empty($object->date_reelle_depart)) - { + if (!empty($object->date_reelle_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1085,16 +998,14 @@ class pdf_eagle extends ModelePdfStockTransfer } // Date reelle arrivée - if (!empty($object->date_reelle_arrivee)) - { + if (!empty($object->date_reelle_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); } - if (!empty($object->thirdparty->code_client)) - { + if (!empty($object->thirdparty->code_client)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1110,15 +1021,13 @@ class pdf_eagle extends ModelePdfStockTransfer $origin_id = $object->origin_id; // TODO move to external function - if (!empty($conf->$origin->enabled)) // commonly $origin='commande' - { + if (!empty($conf->$origin->enabled)) { // commonly $origin='commande' $outputlangs->load('orders'); $classname = ucfirst($origin); $linkedobject = new $classname($this->db); $result = $linkedobject->fetch($origin_id); - if ($result >= 0) - { + if ($result >= 0) { //$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects $pdf->SetFont('', '', $default_font_size - 2); @@ -1133,8 +1042,7 @@ class pdf_eagle extends ModelePdfStockTransfer } } - if ($showaddress) - { + if ($showaddress) { // Sender properties $carac_emetteur = ''; // Add internal contact of origin element if defined @@ -1142,8 +1050,7 @@ class pdf_eagle extends ModelePdfStockTransfer $arrayidcontact = $object->getIdContact('external', 'STFROM'); $usecontact = false; - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { /*$object->fetch_user(reset($arrayidcontact)); $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ $usecontact = true; @@ -1153,9 +1060,9 @@ class pdf_eagle extends ModelePdfStockTransfer if ($usecontact) $thirdparty = $object->contact; else $thirdparty = $this->emetteur; - if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + if ($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); // Show sender @@ -1192,8 +1099,7 @@ class pdf_eagle extends ModelePdfStockTransfer // If SHIPPING contact defined, we use it $usecontact = false; $arrayidcontact = $object->getIdContact('external', 'STDEST'); - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { $usecontact = true; $result = $object->fetch_contact($arrayidcontact[0]); } @@ -1206,7 +1112,7 @@ class pdf_eagle extends ModelePdfStockTransfer $thirdparty = $object->thirdparty; } - if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php index 9ba4d869ec0..accbf4e0dbb 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -219,49 +219,35 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); $this->atleastonephoto = false; - if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) - { + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) { $objphoto = new Product($this->db); - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { if (empty($object->lines[$i]->fk_product)) continue; $objphoto->fetch($object->lines[$i]->fk_product); //var_dump($objphoto->ref);exit; - if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) - { + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; - } - else - { + } else { $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative } $arephoto = false; - foreach ($pdir as $midir) - { - if (!$arephoto) - { + foreach ($pdir as $midir) { + if (!$arephoto) { $dir = $conf->product->dir_output.'/'.$midir; - foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) - { - if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo - { - if ($obj['photo_vignette']) - { + foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + if ($obj['photo_vignette']) { $filename = $obj['photo_vignette']; - } - else - { + } else { $filename = $obj['photo']; } - } - else - { + } else { $filename = $obj['photo']; } @@ -278,39 +264,31 @@ class pdf_eagle_proforma extends ModelePDFCommandes - if ($conf->stocktransfer->dir_output) - { + if ($conf->stocktransfer->dir_output) { $object->fetch_thirdparty(); $deja_regle = 0; // Definition of $dir and $file - if ($object->specimen) - { + if ($object->specimen) { $dir = $conf->stocktransfer->multidir_output[$conf->entity]; $file = $dir."/SPECIMEN.pdf"; - } - else - { + } else { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->stocktransfer->multidir_output[$conf->entity]."/".$object->element."/".$objectref; $file = $dir."/".$objectref.".pdf"; } - if (!file_exists($dir)) - { - if (dol_mkdir($dir) < 0) - { + if (!file_exists($dir)) { + if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } - if (file_exists($dir)) - { + if (file_exists($dir)) { // Add pdfgeneration hook - if (!is_object($hookmanager)) - { + if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } @@ -328,15 +306,13 @@ class pdf_eagle_proforma extends ModelePDFCommandes $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin) - if (class_exists('TCPDF')) - { + if (class_exists('TCPDF')) { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File - if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) - { + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } @@ -377,11 +353,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10); // Incoterm - if ($conf->incoterm->enabled) - { + if ($conf->incoterm->enabled) { $desc_incoterms = $object->getIncotermsForPDF(); - if ($desc_incoterms) - { + if ($desc_incoterms) { $tab_top -= 2; $pdf->SetFont('', '', $default_font_size - 1); @@ -399,11 +373,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Displays notes $notetoshow = empty($object->note_public) ? '' : $object->note_public; - if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) - { + if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) { // Get first sale rep - if (is_object($object->thirdparty)) - { + if (is_object($object->thirdparty)) { $salereparray = $object->thirdparty->getSalesRepresentatives($user); $salerepobj = new User($this->db); $salerepobj->fetch($salereparray[0]['id']); @@ -413,14 +385,12 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Extrafields in note $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); - if (!empty($extranote)) - { + if (!empty($extranote)) { $notetoshow = dol_concatdesc($notetoshow, $extranote); } $pagenb = $pdf->getPage(); - if ($notetoshow) - { + if ($notetoshow) { $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite; $pageposbeforenote = $pagenb; @@ -439,8 +409,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pageposafternote = $pdf->getPage(); $posyafter = $pdf->GetY(); - if ($pageposafternote > $pageposbeforenote) - { + if ($pageposafternote > $pageposbeforenote) { $pdf->rollbackTransaction(true); // prepare pages to receive notes @@ -464,8 +433,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $posyafter = $pdf->GetY(); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) // There is no space left for total+free text - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text $pdf->AddPage('', '', true); $pagenb++; $pageposafternote++; @@ -488,8 +456,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes if ($i > $pageposbeforenote) { $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); - } - else { + } else { $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); } @@ -507,8 +474,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $height_note = $posyafter - $tab_top_newpage; $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); - } - else // No pagebreak + } else // No pagebreak { $pdf->commitTransaction(); $posyafter = $pdf->GetY(); @@ -516,8 +482,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // not enough space, need to add page $pdf->AddPage('', '', true); $pagenb++; @@ -532,9 +497,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $tab_height = $tab_height - $height_note; $tab_top = $posyafter + 6; - } - else - { + } else { $height_note = 0; } @@ -552,8 +515,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Loop on each lines $pageposbeforeprintlines = $pdf->getPage(); $pagenb = $pageposbeforeprintlines; - for ($i = 0; $i < $nblines; $i++) - { + for ($i = 0; $i < $nblines; $i++) { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -570,11 +532,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes $showpricebeforepagebreak = 1; $posYAfterImage = 0; - if ($this->getColumnStatus('photo')) - { + if ($this->getColumnStatus('photo')) { // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page - { + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); $pdf->setPage($pageposbefore + 1); @@ -584,23 +544,20 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) - { + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } } - if ($this->getColumnStatus('desc')) - { + if ($this->getColumnStatus('desc')) { $pdf->startTransaction(); - if(method_exists($object->lines[$i], 'fetch_product')) { + if (method_exists($object->lines[$i], 'fetch_product')) { $object->lines[$i]->fetch_product(); $object->lines[$i]->label = $object->lines[$i]->product->label; $object->lines[$i]->description = $object->lines[$i]->product->description; @@ -610,8 +567,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); - if ($pageposafter > $pageposbefore) // There is a pagebreak - { + if ($pageposafter > $pageposbefore) { // There is a pagebreak $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; @@ -620,27 +576,21 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text - { - if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page - { + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text + if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page $pdf->AddPage('', '', true); if (!empty($tplidx)) $pdf->useTemplate($tplidx); //if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); $pdf->setPage($pageposafter + 1); } - } - else - { + } else { // We found a page break // Allows data in the first page if description is long enough to break in multiples pages if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) $showpricebeforepagebreak = 1; - else - $showpricebeforepagebreak = 0; + else $showpricebeforepagebreak = 0; } - } - else // No pagebreak + } else // No pagebreak { $pdf->commitTransaction(); } @@ -665,16 +615,14 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font // VAT Rate - if ($this->getColumnStatus('vat')) - { + if ($this->getColumnStatus('vat')) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); $nexY = max($pdf->GetY(), $nexY); } // Unit price before discount - if ($this->getColumnStatus('subprice')) - { + if ($this->getColumnStatus('subprice')) { $pmp = $object->lines[$i]->pmp; $this->printStdColumnContent($pdf, $curY, 'subprice', price($pmp)); $nexY = max($pdf->GetY(), $nexY); @@ -682,8 +630,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Quantity // Enough for 6 chars - if ($this->getColumnStatus('qty')) - { + if ($this->getColumnStatus('qty')) { $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'qty', $qty); $nexY = max($pdf->GetY(), $nexY); @@ -691,24 +638,21 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Unit - if ($this->getColumnStatus('unit')) - { + if ($this->getColumnStatus('unit')) { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); $this->printStdColumnContent($pdf, $curY, 'unit', $unit); $nexY = max($pdf->GetY(), $nexY); } // Discount on line - if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) - { + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) { $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); $nexY = max($pdf->GetY(), $nexY); } // Total HT line - if ($this->getColumnStatus('totalexcltax')) - { + if ($this->getColumnStatus('totalexcltax')) { $pmp_qty = $pmp * $object->lines[$i]->qty; $this->printStdColumnContent($pdf, $curY, 'totalexcltax', price($pmp_qty)); $nexY = max($pdf->GetY(), $nexY); @@ -717,8 +661,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Extrafields if (!empty($object->lines[$i]->array_options)) { foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) { - if ($this->getColumnStatus($extrafieldColKey)) - { + if ($this->getColumnStatus($extrafieldColKey)) { $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); $nexY = max($pdf->GetY(), $nexY); @@ -757,8 +700,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Retrieve type from database for backward compatibility with old records if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined - && (!empty($localtax1_rate) || !empty($localtax2_rate))) // and there is local tax - { + && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); $localtax1_type = $localtaxtmp_array[0]; $localtax2_type = $localtaxtmp_array[2]; @@ -775,8 +717,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->tva[$vatrate] += $tvaligne; // Add line - if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) - { + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); @@ -786,15 +727,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) - { + while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); - if ($pagenb == $pageposbeforeprintlines) - { + if ($pagenb == $pageposbeforeprintlines) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -803,14 +740,10 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) - { - if ($pagenb == $pageposafter) - { + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { + if ($pagenb == $pageposafter) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); - } - else - { + } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); @@ -825,8 +758,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Show square if ($pagenb == $pageposbeforeprintlines) $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code); - else - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + else $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; // Affiche zone infos @@ -857,8 +789,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) - { + if ($reshook < 0) { $this->error = $hookmanager->error; $this->errors = $hookmanager->errors; } @@ -869,15 +800,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes $this->result = array('fullpath'=>$file); return 1; // No error - } - else - { + } else { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } - } - else - { + } else { $this->error = $langs->transnoentities("ErrorConstantNotDefined", "STOCKTRANSFER_OUTPUTDIR"); return 0; } @@ -913,8 +840,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // If France, show VAT mention if not applicable - if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) - { + if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); @@ -925,8 +851,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $posxval = 52; // Show payments conditions - if ($object->cond_reglement_code || $object->cond_reglement) - { + if ($object->cond_reglement_code || $object->cond_reglement) { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("PaymentConditions").':'; @@ -959,18 +884,17 @@ class pdf_eagle_proforma extends ModelePDFCommandes /* TODO else if (! empty($object->availability_code)) { - $pdf->SetXY($this->marge_gauche, $posy); - $pdf->SetTextColor(200,0,0); - $pdf->SetFont('','B', $default_font_size - 2); - $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); - $pdf->SetTextColor(0,0,0); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); + $pdf->SetTextColor(0,0,0); - $posy=$pdf->GetY()+1; + $posy=$pdf->GetY()+1; }*/ // Show planed date of delivery - if (!empty($object->date_livraison)) - { + if (!empty($object->date_livraison)) { $outputlangs->load("sendings"); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); @@ -982,9 +906,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->MultiCell(80, 4, $dlp, 0, 'L'); $posy = $pdf->GetY() + 1; - } - elseif ($object->availability_code || $object->availability) // Show availability conditions - { + } elseif ($object->availability_code || $object->availability) { // Show availability conditions $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("AvailabilityPeriod").':'; @@ -1017,13 +939,10 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Show payment mode CHQ - if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') - { + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { // Si mode reglement non force ou si force a CHQ - if (!empty($conf->global->FACTURE_CHQ_NUMBER)) - { - if ($conf->global->FACTURE_CHQ_NUMBER > 0) - { + if (!empty($conf->global->FACTURE_CHQ_NUMBER)) { + if ($conf->global->FACTURE_CHQ_NUMBER > 0) { $account = new Account($this->db); $account->fetch($conf->global->FACTURE_CHQ_NUMBER); @@ -1032,23 +951,20 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); $posy = $pdf->GetY() + 1; - if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) - { + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); $posy = $pdf->GetY() + 2; } } - if ($conf->global->FACTURE_CHQ_NUMBER == -1) - { + if ($conf->global->FACTURE_CHQ_NUMBER == -1) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); $posy = $pdf->GetY() + 1; - if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) - { + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - 3); $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); @@ -1059,10 +975,8 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // If payment mode not forced or forced to VIR, show payment with BAN - if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') - { - if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) - { + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') { + if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) { $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank $account = new Account($this->db); @@ -1103,8 +1017,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Tableau total $col1x = 120; $col2x = 170; - if ($this->page_largeur < 210) // To work with US executive format - { + if ($this->page_largeur < 210) { // To work with US executive format $col2x -= 20; } $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); @@ -1153,8 +1066,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'); if (!empty($object->paye)) $resteapayer = 0; - if ($deja_regle > 0) - { + if ($deja_regle > 0) { // Already paid + Deposits $index++; @@ -1209,8 +1121,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetTextColor(0, 0, 0); $pdf->SetFont('', '', $default_font_size - 2); - if (empty($hidetop)) - { + if (empty($hidetop)) { $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); @@ -1260,8 +1171,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); // Show Draft Watermark - if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) - { + if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) { pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->COMMANDE_DRAFT_WATERMARK); } @@ -1274,34 +1184,25 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetXY($this->marge_gauche, $posy); // Logo - if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) - { - if ($this->emetteur->logo) - { + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) { + if ($this->emetteur->logo) { $logodir = $conf->mycompany->dir_output; if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity]; - if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) - { + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; - } - else { + } else { $logo = $logodir.'/logos/'.$this->emetteur->logo; } - if (is_readable($logo)) - { + if (is_readable($logo)) { $height = pdf_getHeightForLogo($logo); $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) - } - else - { + } else { $pdf->SetTextColor(200, 0, 0); $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } - } - else - { + } else { $text = $this->emetteur->name; $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); } @@ -1324,8 +1225,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetFont('', '', $default_font_size - 1); // Date prévue depart - if (!empty($object->date_prevue_depart)) - { + if (!empty($object->date_prevue_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1333,8 +1233,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date prévue arrivée - if (!empty($object->date_prevue_arrivee)) - { + if (!empty($object->date_prevue_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1342,8 +1241,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date reelle depart - if (!empty($object->date_reelle_depart)) - { + if (!empty($object->date_reelle_depart)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1351,27 +1249,23 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Date reelle arrivée - if (!empty($object->date_reelle_arrivee)) - { + if (!empty($object->date_reelle_arrivee)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R'); } - if ($object->ref_client) - { + if ($object->ref_client) { $posy += 5; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); } - if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) - { + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) { $object->fetch_projet(); - if (!empty($object->project->ref)) - { + if (!empty($object->project->ref)) { $posy += 3; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1379,11 +1273,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes } } - if (!empty($conf->global->PDF_SHOW_PROJECT)) - { + if (!empty($conf->global->PDF_SHOW_PROJECT)) { $object->fetch_projet(); - if (!empty($object->project->ref)) - { + if (!empty($object->project->ref)) { $posy += 3; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1391,8 +1283,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes } } - if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) - { + if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) { $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1400,11 +1291,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes } // Get contact - if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) - { + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) { $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL'); - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { $usertmp = new User($this->db); $usertmp->fetch($arrayidcontact[0]); $posy += 4; @@ -1420,13 +1309,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Show list of linked objects $current_y = $pdf->getY(); $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); - if ($current_y < $pdf->getY()) - { + if ($current_y < $pdf->getY()) { $top_shift = $pdf->getY() - $current_y; } - if ($showaddress) - { + if ($showaddress) { // Sender properties $carac_emetteur = ''; // Add internal contact of origin element if defined @@ -1434,8 +1321,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $arrayidcontact = $object->getIdContact('external', 'STFROM'); $usecontact = false; - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { /*$object->fetch_user(reset($arrayidcontact)); $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/ $usecontact = true; @@ -1445,9 +1331,9 @@ class pdf_eagle_proforma extends ModelePDFCommandes if ($usecontact) $thirdparty = $object->contact; else $thirdparty = $this->emetteur; - if(!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - if($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); + if ($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object); else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); // Show sender @@ -1484,8 +1370,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // If SHIPPING contact defined, we use it $usecontact = false; $arrayidcontact = $object->getIdContact('external', 'STDEST'); - if (count($arrayidcontact) > 0) - { + if (count($arrayidcontact) > 0) { $usecontact = true; $result = $object->fetch_contact($arrayidcontact[0]); } @@ -1498,7 +1383,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $thirdparty = $object->thirdparty; } - if(!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + if (!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object); @@ -1631,8 +1516,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes 'border-left' => false, // remove left line separator ); - if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) - { + if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) { $this->cols['photo']['status'] = true; } @@ -1740,16 +1624,11 @@ class pdf_eagle_proforma extends ModelePDFCommandes ); $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook - if ($reshook < 0) - { + if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - } - elseif (empty($reshook)) - { + } elseif (empty($reshook)) { $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys - } - else - { + } else { $this->cols = $hookmanager->resArray; } } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index ae80b55b51d..9de775f29d6 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -102,8 +102,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Initialize array of search criterias $search_all = trim(GETPOST("search_all", 'alpha')); $search = array(); -foreach ($object->fields as $key => $val) -{ +foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha')) $search[$key] = GETPOST('search_'.$key, 'alpha'); } @@ -141,8 +140,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if (empty($reshook)) -{ +if (empty($reshook)) { $error = 0; $backurlforlist = dol_buildpath('/product/stock/stocktransfer/stocktransfer_list.php', 1); @@ -170,30 +168,27 @@ if (empty($reshook)) // Action to build doc include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - if ($action == 'set_thirdparty' && $permissiontoadd) - { + if ($action == 'set_thirdparty' && $permissiontoadd) { $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'STOCKTRANSFER_MODIFY'); } - if ($action == 'classin' && $permissiontoadd) - { + if ($action == 'classin' && $permissiontoadd) { $object->setProject(GETPOST('projectid', 'int')); } - if($action == 'addline' && $permissiontoadd) { - - if($qty <= 0) { + if ($action == 'addline' && $permissiontoadd) { + if ($qty <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); $action = 'view'; } - if($fk_warehouse_source <= 0) { + if ($fk_warehouse_source <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); $action = 'view'; } - if($fk_warehouse_destination <= 0) { + if ($fk_warehouse_destination <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); $action = 'view'; @@ -201,25 +196,23 @@ if (empty($reshook)) $prod = new Product($db); $prod->fetch($fk_product); - if ($prod->hasbatch()) - { - if (empty($batch)) - { + if ($prod->hasbatch()) { + if (empty($batch)) { $error++; $langs->load("errors"); setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); } } else { - if(!empty($batch)) { + if (!empty($batch)) { $error++; setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); } } - if(empty($error)) { + if (empty($error)) { $line = new StockTransferLine($db); $records = $line->fetchAll('', '', 0, 0, array('customsql'=>' fk_stocktransfer = '.$id.' AND fk_product = '.$fk_product.' AND fk_warehouse_source = '.$fk_warehouse_source.' AND fk_warehouse_destination = '.$fk_warehouse_destination.' AND ('.(empty($batch) ? 'batch = "" or batch IS NULL' : 'batch = "'.$batch.'"' ).')')); - if(!empty($records[key($records)])) $line = $records[key($records)]; + if (!empty($records[key($records)])) $line = $records[key($records)]; $line->fk_stocktransfer = $id; $line->qty += $qty; $line->fk_warehouse_source = $fk_warehouse_source; @@ -228,28 +221,27 @@ if (empty($reshook)) $line->batch = $batch; $line->pmp = $prod->pmp; - if($line->id > 0) $line->update($user); + if ($line->id > 0) $line->update($user); else { $line->rang = count($object->lines) + 1; $line->create($user); } $object->fetchLines(); } - } elseif($action === 'updateline' && $permissiontoadd) { - - if($qty <= 0) { + } elseif ($action === 'updateline' && $permissiontoadd) { + if ($qty <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); $action = 'editline'; } - if($fk_warehouse_source <= 0) { + if ($fk_warehouse_source <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors'); $action = 'editline'; } - if($fk_warehouse_destination <= 0) { + if ($fk_warehouse_destination <= 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors'); $action = 'editline'; @@ -257,24 +249,22 @@ if (empty($reshook)) $prod = new Product($db); $prod->fetch($fk_product); - if ($prod->hasbatch()) - { - if (empty($batch)) - { + if ($prod->hasbatch()) { + if (empty($batch)) { $error++; $langs->load("errors"); setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); $action = 'editline'; } } else { - if(!empty($batch)) { + if (!empty($batch)) { $error++; setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); $action = 'editline'; } } - if(empty($error)) { + if (empty($error)) { $line = new StockTransferLine($db); $line->fetch($lineid); $line->qty = $qty; @@ -288,18 +278,18 @@ if (empty($reshook)) } // Décrémentation - if($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { + if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_source); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_TRANSFERED, $id); $object->status = $object::STATUS_TRANSFERED; $object->date_reelle_depart = date('Y-m-d'); @@ -309,18 +299,18 @@ if (empty($reshook)) } // Annulation décrémentation - if($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_source, 0); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_VALIDATED, $id); $object->status = $object::STATUS_VALIDATED; $object->date_reelle_depart = null; @@ -330,18 +320,18 @@ if (empty($reshook)) } // Incrémentation - if($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_destination, 0); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_CLOSED, $id); $object->status = $object::STATUS_CLOSED; $object->date_reelle_arrivee = date('Y-m-d'); @@ -351,18 +341,18 @@ if (empty($reshook)) } // Annulation incrémentation - if($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { + if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { $lines = $object->getLinesArray(); - if(!empty($lines)) { + if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { $res = $line->doStockMovement($label, $line->fk_warehouse_destination); - if($res <= 0) $error++; + if ($res <= 0) $error++; } - if(empty($error)) $db->commit(); + if (empty($error)) $db->commit(); else $db->rollback(); } - if(empty($error)) { + if (empty($error)) { $object->setStatut($object::STATUS_TRANSFERED, $id); $object->status = $object::STATUS_TRANSFERED; $object->date_reelle_arrivee = null; @@ -400,8 +390,8 @@ jQuery(document).ready(function() {'; // Affichage alerte date prévue de départ si transfert concerné $date_prevue_depart = $object->date_prevue_depart; $date_prevue_depart_plus_delai = $date_prevue_depart; -if($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); -if(!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) { +if ($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day'); +if (!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) { print "$('.valuefield.fieldname_date_prevue_depart').append('"; print img_warning($langs->trans('Alert').' - '.$langs->trans('Late')); print "');"; @@ -412,8 +402,7 @@ print '}); // Part to create -if ($action == 'create') -{ +if ($action == 'create') { print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("StockTransfer")), '', 'object_'.$object->picto); print '
'; @@ -461,8 +450,7 @@ if ($action == 'create') } // Part to edit record -if (($id || $ref) && $action == 'edit') -{ +if (($id || $ref) && $action == 'edit') { //if($object->status < 3) { print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto); @@ -496,8 +484,7 @@ if (($id || $ref) && $action == 'edit') } // Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) -{ +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { $res = $object->fetch_optionals(); $head = stocktransferPrepareHead($object); @@ -506,13 +493,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formconfirm = ''; // Confirmation to delete - if ($action == 'delete') - { + if ($action == 'delete') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Delete'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); } // Confirmation to delete line - if ($action == 'deleteline') - { + if ($action == 'deleteline') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); } // Clone confirmation @@ -551,8 +536,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Confirmation of action xxxx - if ($action == 'xxx') - { + if ($action == 'xxx') { $formquestion = array(); /* $forcecombo=0; @@ -590,15 +574,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtmlref = '
'; // Thirdparty - if($conf->societe->enabled) { + if ($conf->societe->enabled) { $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 ($permissiontoadd) { //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; $morehtmlref.=' : '; if ($action == 'classify') { @@ -662,8 +645,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea * Lines */ - if (!empty($object->table_element_line)) - { + if (!empty($object->table_element_line)) { // Show object lines /*$result = $object->getLinesArray(); @@ -720,9 +702,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea '; - if($lineid > 0) print ''; + if ($lineid > 0) print ''; print ''; -//print '
'; + //print '
'; $param = ''; @@ -741,7 +723,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); - if(empty($object->status)) { + if (empty($object->status)) { print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); @@ -754,8 +736,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $warehousestatics = new Entrepot($db); $warehousestatict = new Entrepot($db); - foreach ($listofdata as $key => $line) - { + foreach ($listofdata as $key => $line) { $productstatic->fetch($line->fk_product); $warehousestatics->fetch($line->fk_warehouse_source); $warehousestatict->fetch($line->fk_warehouse_destination); @@ -768,36 +749,34 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; - if ($conf->productbatch->enabled) - { + if ($conf->productbatch->enabled) { print ''; } print ''; print ''; - if($action === 'editline' && $line->id == $lineid) print ''; + if ($action === 'editline' && $line->id == $lineid) print ''; else print ''; - if ($conf->global->PRODUCT_USE_UNITS) - { + if ($conf->global->PRODUCT_USE_UNITS) { print ''; - if(empty($object->status)) { - - if($action === 'editline' && $line->id == $lineid) { + if (empty($object->status)) { + if ($action === 'editline' && $line->id == $lineid) { //print ''; print ''; @@ -853,9 +831,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; } - if(empty($object->status) && $action !== 'editline') { + if (empty($object->status) && $action !== 'editline') { print ''; -// Product + // Product print ''; // PMP print ''; - if($conf->global->PRODUCT_USE_UNITS) { + if ($conf->global->PRODUCT_USE_UNITS) { // Unité print ''; } @@ -925,7 +903,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Grad and drop lines print ''; print ''; - } print '
'; - if($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); + if ($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1); else print $productstatic->getNomUrl(1).' - '.$productstatic->label; print ''; - if($action === 'editline' && $line->id == $lineid) print ''; + if ($action === 'editline' && $line->id == $lineid) print ''; else { $productlot = new Productlot($db); - if($productlot->fetch(0, $line->fk_product, $line->batch) > 0) { + if ($productlot->fetch(0, $line->fk_product, $line->batch) > 0) { print $productlot->getNomUrl(1); - } elseif(!empty($line->batch)) print $line->batch.' '.img_warning($langs->trans('BatchNotFound'));; + } elseif (!empty($line->batch)) print $line->batch.' '.img_warning($langs->trans('BatchNotFound'));; } print ''; - if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); + if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource); else print $warehousestatics->getNomUrl(1); print ''; - if($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination,'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); + if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination); else print $warehousestatict->getNomUrl(1); print ''.$line->qty.''; $label = $productstatic->getLabelOfUnit('short'); if ($label !== '') { @@ -812,9 +791,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency); print '
'; print '
'; $filtertype = 0; if (!empty($conf->global->STOCK_SUPPORTS_SERVICES)) $filtertype = ''; @@ -878,21 +856,21 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // On stock ceux qui ne doivent pas être proposés dans la liste $TExcludedWarehouseSource=array(); - if(!empty($object->fk_warehouse_source)) { + if (!empty($object->fk_warehouse_source)) { $source_ent = new Entrepot($db); $source_ent->fetch($object->fk_warehouse_source); foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { - if(strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id']; + if (strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id']; } } // On stock ceux qui ne doivent pas être proposés dans la liste $TExcludedWarehouseDestination=array(); - if(!empty($object->fk_warehouse_destination)) { + if (!empty($object->fk_warehouse_destination)) { $dest_ent = new Entrepot($db); $dest_ent->fetch($object->fk_warehouse_destination); foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) { - if(strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id']; + if (strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id']; } } @@ -914,7 +892,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; @@ -940,25 +917,21 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $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)) - { + if (empty($reshook)) { // Send if (empty($user->socid)) { print ''.$langs->trans('SendMail').''."\n"; } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_VALIDATED) { + if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; } } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } /*else @@ -967,38 +940,26 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea }*/ // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { - if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { + if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; - } - else - { + } else { $langs->load("errors"); print ''.$langs->trans("Validate").''; } } - } - - elseif($object->status == $object::STATUS_VALIDATED) { + } elseif ($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("StockTransferDecrementation").''; - } - - elseif($object->status == $object::STATUS_TRANSFERED) { + } elseif ($object->status == $object::STATUS_TRANSFERED) { print ''.$langs->trans("StockTransferDecrementationCancel").''; print ''.$langs->trans("StockTransferIncrementation").''; - } - - elseif($object->status == $object::STATUS_CLOSED) { + } elseif ($object->status == $object::STATUS_CLOSED) { print ''.$langs->trans("StockTransferIncrementationCancel").''; } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } @@ -1028,8 +989,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea */ // Delete (need delete permission, or if draft, just need create/modify permission) - if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) - { + if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) { print ''.$langs->trans('Delete').''."\n"; } /*else @@ -1046,8 +1006,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $action = 'presend'; } - if ($action != 'presend') - { + if ($action != 'presend') { print '
'; print ''; // ancre From 6e7fa5ffeb0378e19a298663f0ddb23c03e9231d Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Tue, 3 Aug 2021 16:53:44 +0200 Subject: [PATCH 016/128] FIX : stickler feddbacks --- .../stocktransfer/doc/pdf_eagle.modules.php | 8 +++++++- .../stock/stocktransfer/stocktransfer_card.php | 16 ++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index ccdfee026d0..9edf386833c 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -864,7 +864,13 @@ class pdf_eagle extends ModelePdfStockTransfer }*/ } - function atLeastOneBatch($object) + /** + * Used to know if at least one line of Stock Transfer object has a batch set + * + * @param $object Stock Transfer object + * @return bool true if at least one line has batch set, false if not + */ + public function atLeastOneBatch($object) { global $conf; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 9de775f29d6..c21c9ef220a 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -505,30 +505,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // 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); - } - // Destock confirmation - elseif ($action == 'destock') { + } elseif ($action == 'destock') { // Destock confirmation // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1); - } - // Destock confirmation cancel - elseif ($action == 'destockcancel') { + } elseif ($action == 'destockcancel') { // Destock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1); - } - // Addstock confirmation - elseif ($action == 'addstock') { + } elseif ($action == 'addstock') { // Addstock confirmation // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40)); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1); - } - // Addstock confirmation cancel - elseif ($action == 'addstockcancel') { + } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40)); From f77b6d87c972e52a5a72ed95b90481ccf9e33dfc Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 4 Aug 2021 09:18:32 +0200 Subject: [PATCH 017/128] FIX : langs --- htdocs/langs/en_US/stocks.lang | 1 + htdocs/langs/fr_FR/stocks.lang | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index f396c31d0ed..61dd157c607 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -303,3 +303,4 @@ StockTransferSetupPage = Configuration page for stocks transfer module StockTransferRightRead=Read stocks transfers StockTransferRightCreateUpdate=Create/Update stocks transfers StockTransferRightDelete=Delete stocks transfers +BatchNotFound=Lot / serial not found for this product diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index 84686cd675a..9f41a907578 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -298,3 +298,4 @@ StockTransferSetupPage = Page de configuration du module transferts de stocks StockTransferRightRead=Lire les transferts de stocks StockTransferRightCreateUpdate=Créer/Mettre à jour les transferts de stocks StockTransferRightDelete=Supprimer les transferts de stocks +BatchNotFound=Lot / série non trouvé(e) pour ce produit From 5364a5dddf5a9824f85ba5d97448378cef1bbc57 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 4 Aug 2021 09:36:06 +0200 Subject: [PATCH 018/128] FIX : transnoentities --- htdocs/product/stock/stocktransfer/stocktransfer_card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index c21c9ef220a..bab18384c47 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -253,13 +253,13 @@ if (empty($reshook)) { if (empty($batch)) { $error++; $langs->load("errors"); - setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors'); + setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->getNomUrl()), null, 'errors'); $action = 'editline'; } } else { if (!empty($batch)) { $error++; - setEventMessages($langs->trans('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); + setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors'); $action = 'editline'; } } From a80c30bc453197eb7a6b0679e8e650c4fb9cb732 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 18 Aug 2021 19:15:47 +0200 Subject: [PATCH 019/128] NEW : inventory code filled when movements are done --- .../class/stocktransferline.class.php | 25 ++++++++++++++++--- .../stocktransfer/stocktransfer_card.php | 25 +++++++++++++------ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index ea869635e56..8370d05e2ed 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -439,11 +439,12 @@ class StockTransferLine extends CommonObjectLine * Makes all stock movements (add quantity, remove quantity or cancel all actions) * * @param string $label label of stock movement + * @param string $code_inv label of stock movement * @param int $fk_entrepot Warehouse concerned by stock movement * @param int $direction add or remove qty * @return int 1 if ok, <= 0 if ko */ - public function doStockMovement($label, $fk_entrepot, $direction = 1) + public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1) { global $db, $conf, $user, $langs; @@ -473,7 +474,14 @@ class StockTransferLine extends CommonObjectLine $this->fk_stocktransfer );*/ - $result = $movementstock->_create($user, $p->id, $fk_entrepot, $op[$direction], $direction, empty($direction) ? $this->pmp : 0, $label); + $result = $movementstock->_create($user + , $p->id + , $fk_entrepot + , $op[$direction] + , $direction + , empty($direction) ? $this->pmp : 0 + , $label + , $code_inv); if ($result < 0) { setEventMessages($p->errors, $p->errorss, 'errors'); @@ -505,7 +513,18 @@ class StockTransferLine extends CommonObjectLine GETPOST("codemove") );*/ - $result = $movementstock->_create($user, $p->id, $fk_entrepot, $op[$direction], $direction, empty($direction) ? $this->pmp : 0, $label, '', '', $dlc, $dluo, $this->batch); + $result = $movementstock->_create($user + , $p->id + , $fk_entrepot + , $op[$direction] + , $direction + , empty($direction) ? $this->pmp : 0 + , $label + , $code_inv + , '' + , $dlc + , $dluo + , $this->batch); if ($result < 0) { setEventMessages($p->errors, $p->errorss, 'errors'); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index bab18384c47..aaf7f92701a 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -87,6 +87,7 @@ $fk_warehouse_destination = GETPOST('fk_warehouse_destination', 'int'); $lineid = GETPOST('lineid', 'int'); $label = GETPOST('label', 'alpha'); $batch = GETPOST('batch', 'alpha'); +$code_inv = GETPOST('inventorycode', 'alphanohtml'); // Initialize technical objects $object = new StockTransfer($db); @@ -283,7 +284,7 @@ if (empty($reshook)) { if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { - $res = $line->doStockMovement($label, $line->fk_warehouse_source); + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source); if ($res <= 0) $error++; } if (empty($error)) $db->commit(); @@ -304,7 +305,7 @@ if (empty($reshook)) { if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { - $res = $line->doStockMovement($label, $line->fk_warehouse_source, 0); + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source, 0); if ($res <= 0) $error++; } if (empty($error)) $db->commit(); @@ -325,7 +326,7 @@ if (empty($reshook)) { if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { - $res = $line->doStockMovement($label, $line->fk_warehouse_destination, 0); + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination, 0); if ($res <= 0) $error++; } if (empty($error)) $db->commit(); @@ -346,7 +347,7 @@ if (empty($reshook)) { if (!empty($lines)) { $db->begin(); foreach ($lines as $line) { - $res = $line->doStockMovement($label, $line->fk_warehouse_destination); + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination); if ($res <= 0) $error++; } if (empty($error)) $db->commit(); @@ -508,22 +509,30 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } elseif ($action == 'destock') { // Destock confirmation // Create an array for form $formquestion = array( 'text' => '', - array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40)); + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40), + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1); } elseif ($action == 'destockcancel') { // Destock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', - array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40)); + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40), + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1); } elseif ($action == 'addstock') { // Addstock confirmation // Create an array for form $formquestion = array( 'text' => '', - array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40)); + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40), + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1); } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', - array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40)); + array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40), + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProductCancel'), '', 'confirm_addstockcancel', $formquestion, 'yes', 1); } From d29aa636a5107e4cd3c243cad20a5e050d7e764b Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 18 Aug 2021 17:19:19 +0000 Subject: [PATCH 020/128] Fixing style errors. --- .../class/stocktransferline.class.php | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 8370d05e2ed..2db20cca0d1 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -474,14 +474,14 @@ class StockTransferLine extends CommonObjectLine $this->fk_stocktransfer );*/ - $result = $movementstock->_create($user - , $p->id - , $fk_entrepot - , $op[$direction] - , $direction - , empty($direction) ? $this->pmp : 0 - , $label - , $code_inv); + $result = $movementstock->_create($user, + $p->id, + $fk_entrepot, + $op[$direction], + $direction, + empty($direction) ? $this->pmp : 0, + $label, + $code_inv); if ($result < 0) { setEventMessages($p->errors, $p->errorss, 'errors'); @@ -513,18 +513,18 @@ class StockTransferLine extends CommonObjectLine GETPOST("codemove") );*/ - $result = $movementstock->_create($user - , $p->id - , $fk_entrepot - , $op[$direction] - , $direction - , empty($direction) ? $this->pmp : 0 - , $label - , $code_inv - , '' - , $dlc - , $dluo - , $this->batch); + $result = $movementstock->_create($user, + $p->id, + $fk_entrepot, + $op[$direction], + $direction, + empty($direction) ? $this->pmp : 0, + $label, + $code_inv, + '', + $dlc, + $dluo, + $this->batch); if ($result < 0) { setEventMessages($p->errors, $p->errorss, 'errors'); From c8ccc456b0dc72eea04b43dc3fa6f6f4f11d0c99 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 18 Aug 2021 19:35:06 +0200 Subject: [PATCH 021/128] FIX : no need to have stock transfer ref in inventory code + need to change size of origintype field to be able to save StockTransfer@product/stock/stocktransfer --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 2 ++ .../stock/stocktransfer/class/stocktransfer.class.php | 2 +- htdocs/product/stock/stocktransfer/stocktransfer_card.php | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 43482d94fdd..697cb00e541 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -144,3 +144,5 @@ create table llx_stocktransfer_stocktransferline_extrafields ) ENGINE=innodb; ALTER TABLE llx_stocktransfer_stocktransferline_extrafields ADD INDEX idx_fk_object(fk_object); + +ALTER TABLE `llx_stock_mouvement` CHANGE `origintype` `origintype` VARCHAR(64) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index d34666b7cb2..dd55392b70d 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -184,7 +184,7 @@ class StockTransfer extends CommonObject global $conf, $langs; $this->db = $db; - $this->origin_type = 'StockTransfer@stocktransfer'; + $this->origin_type = 'StockTransfer@product/stock/stocktransfer'; 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; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index aaf7f92701a..f57ffb8078f 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -510,28 +510,28 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40), - array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1); } elseif ($action == 'destockcancel') { // Destock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40), - array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1); } elseif ($action == 'addstock') { // Addstock confirmation // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40), - array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1); } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel // Create an array for form $formquestion = array( 'text' => '', array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").' :', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40), - array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => $object->ref.'_'.dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) + array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25) ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProductCancel'), '', 'confirm_addstockcancel', $formquestion, 'yes', 1); } From 9098356b1f607540ff73acca155fc8be1936eefb Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 18 Aug 2021 19:44:40 +0200 Subject: [PATCH 022/128] FIX : travis feedbacks --- htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 9edf386833c..c0754f61a8d 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -867,8 +867,8 @@ class pdf_eagle extends ModelePdfStockTransfer /**  * Used to know if at least one line of Stock Transfer object has a batch set  * - * @param $object Stock Transfer object - * @return bool true if at least one line has batch set, false if not + * @param Object $object Stock Transfer object + * @return boolean true if at least one line has batch set, false if not  */ public function atLeastOneBatch($object) { From 5cde5e26b9f63a17b22d70be0b5fdd295f6ddf00 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 18 Aug 2021 19:48:17 +0200 Subject: [PATCH 023/128] FIX : ne back quote in migration script --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 697cb00e541..215427fec8a 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -145,4 +145,4 @@ create table llx_stocktransfer_stocktransferline_extrafields ALTER TABLE llx_stocktransfer_stocktransferline_extrafields ADD INDEX idx_fk_object(fk_object); -ALTER TABLE `llx_stock_mouvement` CHANGE `origintype` `origintype` VARCHAR(64) +ALTER TABLE llx_stock_mouvement CHANGE origintype origintype VARCHAR(64) From 9d5f288ca30ffde734e47c00399631b0b3945c1d Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Thu, 23 Sep 2021 14:30:00 +0200 Subject: [PATCH 024/128] FIX Totalttc into total --- .../modules/stocktransfer/doc/pdf_eagle_proforma.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php index accbf4e0dbb..aabaaa9edc7 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -1051,7 +1051,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); $pdf->SetTextColor(0, 0, 60); $pdf->SetFillColor(224, 224, 224); - $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalTTC", $mysoc->country_code) : ''), $useborder, 'L', 1); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Total").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("Total", $mysoc->country_code) : ''), $useborder, 'L', 1); $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1); From 72bb1062cc95894ef39d10448c8bdf030261328b Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Thu, 23 Sep 2021 15:15:35 +0200 Subject: [PATCH 025/128] FIX proforma pdf name --- .../modules/stocktransfer/doc/pdf_eagle_proforma.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php index aabaaa9edc7..bd9e4d3f11a 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -276,7 +276,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes } else { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->stocktransfer->multidir_output[$conf->entity]."/".$object->element."/".$objectref; - $file = $dir."/".$objectref.".pdf"; + $file = $dir."/".$objectref."-proforma.pdf"; } if (!file_exists($dir)) { From 8de4d3d1a4b83661bebfb87438ad24f2348a589c Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Wed, 29 Sep 2021 16:56:57 +0200 Subject: [PATCH 026/128] NEW incoterms --- .../llx_stocktransfer_stocktransfer.sql | 4 +- .../class/stocktransfer.class.php | 5 +++ .../stocktransfer/stocktransfer_card.php | 38 ++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql index a891fdc2f5d..e04a6dcb1ec 100644 --- a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql @@ -39,6 +39,8 @@ CREATE TABLE llx_stocktransfer_stocktransfer( import_key varchar(14), model_pdf varchar(255), last_main_doc varchar(255), - status smallint NOT NULL + status smallint NOT NULL, + fk_incoterms integer, -- for incoterms + location_incoterms varchar(255) -- END MODULEBUILDER FIELDS ) ENGINE=innodb; diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index dd55392b70d..38d3484ec9f 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -25,6 +25,8 @@ // Put here all includes required by your class file require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php'; + //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; @@ -33,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; */ class StockTransfer extends CommonObject { + use CommonIncoterm; /** * @var string ID to identify managed object. */ @@ -118,6 +121,8 @@ class StockTransfer extends CommonObject 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ChangedBy', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>220), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>225), 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>5, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '2'=>'StockStransferDecremented', '3'=>'StockStransferIncremented'),), ); public $rowid; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index f57ffb8078f..1c8eccb2c4f 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -70,6 +70,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/stocktransfer/modules_stocktransfe // Load translation files required by the page $langs->loadLangs(array("stocks", "other", "productbatch", "companies")); + if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); // Get parameters $id = GETPOST('id', 'int'); @@ -361,7 +362,11 @@ if (empty($reshook)) { setEventMessage('StockStransferIncrementedShortCancel', 'warnings'); } } - + // Set incoterm + if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $permissiontoadd) + { + $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + } // Actions to send emails $triggersendname = 'STOCKTRANSFER_SENTBYMAIL'; $autocopy = 'MAIN_MAIL_AUTOCOPY_STOCKTRANSFER_TO'; @@ -422,6 +427,14 @@ if ($action == 'create') { // Common attributes include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + print ''; + print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : ''),'','fk_incoterms'); + print ''; + } // Template to use by default print ''.$langs->trans('DefaultModel').''; print ''; @@ -626,6 +639,29 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $object->fields['fk_project']['visible']=0; // Already available in banner include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print '
'; + print $langs->trans('IncotermLabel'); + print ''; + if ($permissiontoadd && $action != 'editincoterm') print ''.img_edit().''; + else print ' '; + print '
'; + print ''; + print ''; + if ($action != 'editincoterm') + { + print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1); + } + else + { + print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id); + } + print ''; + } + echo ''; echo ''.$langs->trans('EnhancedValue').' '.strtolower($langs->trans('TotalWoman')); echo ''.price($object->getValorisationTotale(), 0, '', 1, -1, -1, $conf->currency).''; From 05cd74a64ea5ddba017d03a34cdd797185a389f9 Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Mon, 4 Oct 2021 08:46:24 +0200 Subject: [PATCH 027/128] missing migration file incoterm stocktransfer --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index a003247219e..1ad93a55508 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -116,14 +116,14 @@ CREATE TABLE llx_stocktransfer_stocktransfer( -- BEGIN MODULEBUILDER FIELDS rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, entity integer DEFAULT 1 NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, - label varchar(255), - fk_soc integer, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + fk_soc integer, fk_project integer, fk_warehouse_source integer, fk_warehouse_destination integer, description text, - note_public text, + note_public text, note_private text, tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, date_creation datetime NOT NULL, @@ -137,7 +137,9 @@ CREATE TABLE llx_stocktransfer_stocktransfer( import_key varchar(14), model_pdf varchar(255), last_main_doc varchar(255), - status smallint NOT NULL + status smallint NOT NULL, + fk_incoterms integer, -- for incoterms + location_incoterms varchar(255) -- END MODULEBUILDER FIELDS ) ENGINE=innodb; From 4b359af0d0e7a9a2e096ead25ab91008e3b0aa74 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 4 Oct 2021 09:13:05 +0000 Subject: [PATCH 028/128] Fixing style errors. --- .../class/stocktransfer.class.php | 4 ++-- .../stocktransfer/stocktransfer_card.php | 22 +++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 38d3484ec9f..76300c1596e 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php'; */ class StockTransfer extends CommonObject { - use CommonIncoterm; + use CommonIncoterm; /** * @var string ID to identify managed object. */ @@ -121,7 +121,7 @@ class StockTransfer extends CommonObject 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ChangedBy', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), - 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>220), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>220), 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>225), 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>5, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '2'=>'StockStransferDecremented', '3'=>'StockStransferIncremented'),), ); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 1c8eccb2c4f..dd56c5ce6df 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -362,9 +362,8 @@ if (empty($reshook)) { setEventMessage('StockStransferIncrementedShortCancel', 'warnings'); } } - // Set incoterm - if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $permissiontoadd) - { + // Set incoterm + if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $permissiontoadd) { $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); } // Actions to send emails @@ -427,12 +426,11 @@ if ($action == 'create') { // Common attributes include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; - if (!empty($conf->incoterm->enabled)) - { + if (!empty($conf->incoterm->enabled)) { print ''; print ''; print ''; - print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : ''),'','fk_incoterms'); + print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : ''), '', 'fk_incoterms'); print ''; } // Template to use by default @@ -639,9 +637,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $object->fields['fk_project']['visible']=0; // Already available in banner include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; - // Incoterms - if (!empty($conf->incoterm->enabled)) - { + // Incoterms + if (!empty($conf->incoterm->enabled)) { print ''; print '
'; print $langs->trans('IncotermLabel'); @@ -651,12 +648,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; print ''; - if ($action != 'editincoterm') - { + if ($action != 'editincoterm') { print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1); - } - else - { + } else { print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id); } print ''; From 59f5f9b0c6a05c34902ee8187bcc56e812d18824 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 7 Oct 2021 10:37:47 +0200 Subject: [PATCH 029/128] FIX : travis feedback --- .../core/modules/modStockTransfer.class.php | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index 86dc451cfac..597171709be 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -433,7 +433,7 @@ class modStockTransfer extends DolibarrModules */ public function init($options = '') { - global $db, $conf, $langs; + global $conf, $langs; $result = $this->_load_tables('/stocktransfer/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') @@ -485,17 +485,17 @@ class modStockTransfer extends DolibarrModules } // Rôles - $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "internal"'); - $res = $db->fetch_object($resql); - if (empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "internal", "STRESP", "Responsable du transfert de stocks", 1, NULL, 0)'); + $resql = $this->db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "internal"'); + $res = $this->db->fetch_object($resql); + if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "internal", "STRESP", "Responsable du transfert de stocks", 1, NULL, 0)'); - $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STFROM" AND element = "StockTransfer" AND source = "external"'); - $res = $db->fetch_object($resql); - if (empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STFROM", "Contact expéditeur transfert de stocks", 1, NULL, 0)'); + $resql = $this->db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STFROM" AND element = "StockTransfer" AND source = "external"'); + $res = $this->db->fetch_object($resql); + if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STFROM", "Contact expéditeur transfert de stocks", 1, NULL, 0)'); - $resql = $db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "external"'); - $res = $db->fetch_object($resql); - if (empty($res)) $db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STDEST", "Contact destinataire transfert de stocks", 1, NULL, 0)'); + $resql = $this->db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "external"'); + $res = $this->db->fetch_object($resql); + if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STDEST", "Contact destinataire transfert de stocks", 1, NULL, 0)'); return $this->_init($sql, $options); } @@ -506,17 +506,15 @@ class modStockTransfer extends DolibarrModules */ public function getNextId() { - global $db; - // Get free id for insert $newid = 0; $sql = "SELECT max(rowid) newid from ".MAIN_DB_PREFIX."c_type_contact"; - $result = $db->query($sql); + $result = $this->db->query($sql); if ($result) { - $obj = $db->fetch_object($result); + $obj = $this->db->fetch_object($result); $newid = ($obj->newid + 1); } else { - dol_print_error($db); + dol_print_error($this->db); return -1; } return $newid; From 409c19a582bb0a24685606c967be0025e233af34 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 7 Oct 2021 11:19:04 +0200 Subject: [PATCH 030/128] FIX : useless code --- .../core/modules/modStockTransfer.class.php | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index 597171709be..1d3ecda6fb4 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -452,38 +452,6 @@ class modStockTransfer extends DolibarrModules $sql = array(); - // Document templates - $moduledir = 'stocktransfer'; - $myTmpObjects = array(); - $myTmpObjects['StockTransfer']=array('includerefgeneration'=>0, 'includedocgeneration'=>0); - - foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { - if ($myTmpObjectKey == 'StockTransfer') continue; - if ($myTmpObjectArray['includerefgeneration']) { - $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/stocktransfer/template_stocktransfers.odt'; - $dirodt=DOL_DATA_ROOT.'/doctemplates/stocktransfer'; - $dest=$dirodt.'/template_stocktransfers.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.")" - )); - } - } - // Rôles $resql = $this->db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "internal"'); $res = $this->db->fetch_object($resql); From ca3899dbf1e61b6682dd5d46bf9c7eee1cb91d17 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 7 Oct 2021 14:00:31 +0200 Subject: [PATCH 031/128] FIX : travis + several fixes --- htdocs/core/modules/modStockTransfer.class.php | 9 ++++++--- .../stock/stocktransfer/stocktransfer_agenda.php | 2 +- .../stock/stocktransfer/stocktransfer_card.php | 14 ++++++++------ .../stock/stocktransfer/stocktransfer_list.php | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index 1d3ecda6fb4..24bdd4b42d0 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -455,15 +455,18 @@ class modStockTransfer extends DolibarrModules // Rôles $resql = $this->db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "internal"'); $res = $this->db->fetch_object($resql); - if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "internal", "STRESP", "Responsable du transfert de stocks", 1, NULL, 0)'); + $nextid=$this->getNextId(); + if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.((int) $nextid).', "StockTransfer", "internal", "STRESP", "Responsable du transfert de stocks", 1, NULL, 0)'); $resql = $this->db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STFROM" AND element = "StockTransfer" AND source = "external"'); $res = $this->db->fetch_object($resql); - if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STFROM", "Contact expéditeur transfert de stocks", 1, NULL, 0)'); + $nextid=$this->getNextId(); + if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.((int) $nextid).', "StockTransfer", "external", "STFROM", "Contact expéditeur transfert de stocks", 1, NULL, 0)'); $resql = $this->db->query('SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE code = "STDEST" AND element = "StockTransfer" AND source = "external"'); $res = $this->db->fetch_object($resql); - if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.$this->getNextId().', "StockTransfer", "external", "STDEST", "Contact destinataire transfert de stocks", 1, NULL, 0)'); + $nextid=$this->getNextId(); + if (empty($res)) $this->db->query('INSERT INTO '.MAIN_DB_PREFIX.'c_type_contact(rowid, element, source, code, libelle, active, module, position) VALUES('.((int) $nextid).', "StockTransfer", "external", "STDEST", "Contact destinataire transfert de stocks", 1, NULL, 0)'); return $this->_init($sql, $options); } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php index b260dfc8d76..ccbdf12e712 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php @@ -89,7 +89,7 @@ if ($id > 0 || !empty($ref)) $upload_dir = $conf->stocktransfer->multidir_output // Security check - Protection if external user //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; -//$result = restrictedArea($user, 'stocktransfer', $object->id); +$result = restrictedArea($user, 'stocktransfer', $object->id, '', 'stocktransfer'); $permissiontoadd = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_addupdatedelete.inc.php diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index dd56c5ce6df..b001904b6de 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -116,7 +116,6 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ $permissiontoread = $user->rights->stocktransfer->stocktransfer->read; $permissiontoadd = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php -$permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); $permissionnote = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_setnotes.inc.php $permissiondellink = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_dellink.inc.php $upload_dir = $conf->stocktransfer->multidir_output[isset($object->entity) ? $object->entity : 1]; @@ -127,7 +126,7 @@ $upload_dir = $conf->stocktransfer->multidir_output[isset($object->entity) ? $ob //$isdraft = (($object->statut == $object::STATUS_DRAFT) ? 1 : 0); //$result = restrictedArea($user, 'stocktransfer', $object->id, '', '', 'fk_soc', 'rowid', $isdraft); -//if (!$permissiontoread) accessforbidden(); +if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) accessforbidden(); /* @@ -158,6 +157,9 @@ if (empty($reshook)) { // 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'; + // On met cette permission ici car nécessaire d'avoir le dernier statut de l'objet après toute action exécutée dessus + $permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); + // Actions when linking object each other include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; @@ -754,7 +756,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone '); - if (empty($object->status)) { + if (empty($object->status) && $permissiontoadd) { print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); print getTitleFieldOfList('', 0); @@ -822,7 +824,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency); print ''; - if (empty($object->status)) { + if (empty($object->status) && $permissiontoadd) { if ($action === 'editline' && $line->id == $lineid) { //print ''; print '
'; @@ -862,7 +864,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; } - if (empty($object->status) && $action !== 'editline') { + if (empty($object->status) && $action !== 'editline' && $permissiontoadd) { print ''; // Product print ''; @@ -1020,7 +1022,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea */ // Delete (need delete permission, or if draft, just need create/modify permission) - if ($object->status < $object::STATUS_TRANSFERED && $permissiontoadd) { + if ($object->status < $object::STATUS_TRANSFERED && $permissiontodelete) { print ''.$langs->trans('Delete').''."\n"; } /*else diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_list.php b/htdocs/product/stock/stocktransfer/stocktransfer_list.php index e196e9b1068..0424251d54d 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_list.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_list.php @@ -158,7 +158,7 @@ if ($user->socid > 0) { // Protection if external user accessforbidden(); } //$result = restrictedArea($user, 'stocktransfer', $id, ''); -//if (!$permissiontoread) accessforbidden(); +if (!$permissiontoread) accessforbidden(); From ef6f7a619a802f2637e1980c4b03b71dd107ba4b Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 8 Oct 2021 13:33:19 +0200 Subject: [PATCH 032/128] FIX : object linked to stock movement + travis --- .../class/stocktransfer.class.php | 7 +++---- .../class/stocktransferline.class.php | 18 ++++++++++-------- .../stock/stocktransfer/stocktransfer_card.php | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 76300c1596e..3cff895c215 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -505,7 +505,6 @@ class StockTransfer extends CommonObject */ public function deleteLine(User $user, $idline, $notrigger = false) { - global $db; if ($this->status < 0) { $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; return -2; @@ -564,8 +563,8 @@ class StockTransfer extends CommonObject $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; + if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id); + $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::validate()", LOG_DEBUG); $resql = $this->db->query($sql); @@ -590,7 +589,7 @@ class StockTransfer extends CommonObject 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 = 'stocktransfer/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->error = $this->db->lasterror(); } diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 2db20cca0d1..f2378469e29 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -447,19 +447,21 @@ class StockTransferLine extends CommonObjectLine public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1) { - global $db, $conf, $user, $langs; + global $conf, $user, $langs; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php'; + include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php'; - $p = new Product($db); + $p = new Product($this->db); $p->fetch($this->fk_product); $op[0] = "+".trim($this->qty); $op[1] = "-".trim($this->qty); - $movementstock = new MouvementStock($db); - $movementstock->origin = new StockTransfer($db); - $movementstock->origin->id = $this->fk_stocktransfer; + $movementstock = new MouvementStock($this->db); + $st = new StockTransfer($this->db); + $movementstock->origin_type = $st->origin_type; + $movementstock->origin_id = $this->fk_stocktransfer; if (empty($this->batch)) { // no batch for line /*$result = $p->correct_stock( @@ -586,8 +588,8 @@ class StockTransferLine extends CommonObjectLine $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; + if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id); + $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::validate()", LOG_DEBUG); $resql = $this->db->query($sql); @@ -612,7 +614,7 @@ class StockTransferLine extends CommonObjectLine 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 = 'stocktransferline/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->error = $this->db->lasterror(); } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index b001904b6de..0c1d46bcd3e 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -215,7 +215,7 @@ if (empty($reshook)) { if (empty($error)) { $line = new StockTransferLine($db); - $records = $line->fetchAll('', '', 0, 0, array('customsql'=>' fk_stocktransfer = '.$id.' AND fk_product = '.$fk_product.' AND fk_warehouse_source = '.$fk_warehouse_source.' AND fk_warehouse_destination = '.$fk_warehouse_destination.' AND ('.(empty($batch) ? 'batch = "" or batch IS NULL' : 'batch = "'.$batch.'"' ).')')); + $records = $line->fetchAll('', '', 0, 0, array('customsql'=>' fk_stocktransfer = '.((int) $id).' AND fk_product = '.((int) $fk_product).' AND fk_warehouse_source = '.((int) $fk_warehouse_source).' AND fk_warehouse_destination = '.((int) $fk_warehouse_destination).' AND ('.(empty($batch) ? 'batch = "" or batch IS NULL' : "batch = '".$db->escape($batch)."'" ).')')); if (!empty($records[key($records)])) $line = $records[key($records)]; $line->fk_stocktransfer = $id; $line->qty += $qty; From 3d5e4fb87cfa32849d5e88d73c15ccae3305ec98 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 8 Oct 2021 13:42:03 +0200 Subject: [PATCH 033/128] FIX : travis --- .../product/stock/stocktransfer/class/stocktransfer.class.php | 2 +- .../stock/stocktransfer/class/stocktransferline.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 3cff895c215..acd60346fe1 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -427,7 +427,7 @@ class StockTransfer extends CommonObject } } if (count($sqlwhere) > 0) { - $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; } if (!empty($sortfield)) { diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index f2378469e29..3a362395dd8 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -357,7 +357,7 @@ class StockTransferLine extends CommonObjectLine } } if (count($sqlwhere) > 0) { - $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; } if (!empty($sortfield)) { From 361ca6afff1aefe73fa40e5438a61c51f52e2583 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 8 Oct 2021 13:49:11 +0200 Subject: [PATCH 034/128] FIX : travis --- htdocs/product/stock/stocktransfer/stocktransfer_list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_list.php b/htdocs/product/stock/stocktransfer/stocktransfer_list.php index 0424251d54d..a371b252732 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_list.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_list.php @@ -216,7 +216,7 @@ $title = $langs->trans('StockTransferList'); // -------------------------------------------------------------------- $sql = 'SELECT '; foreach ($object->fields as $key => $val) { - $sql .= 't.'.$key.', '; + $sql .= "t.".$key.", "; } // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { @@ -253,7 +253,7 @@ $sql .= $hookmanager->resPrint; $sql.= " GROUP BY "; foreach($object->fields as $key => $val) { - $sql.='t.'.$key.', '; + $sql.="t.".$key.", "; } // Add fields from extrafields if (! empty($extrafields->attributes[$object->table_element]['label'])) { From 1a11135aa4fbf8754f65a10a0320fa65b3dd2591 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 8 Oct 2021 14:00:47 +0200 Subject: [PATCH 035/128] FIX : travis and stickler --- htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 6 +++--- htdocs/product/stock/stocktransfer/stocktransfer_list.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index c0754f61a8d..34f6a94fc35 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -865,10 +865,10 @@ class pdf_eagle extends ModelePdfStockTransfer } /** - * Used to know if at least one line of Stock Transfer object has a batch set + * Used to know if at least one line of Stock Transfer object has a batch set  * - * @param Object $object Stock Transfer object - * @return boolean true if at least one line has batch set, false if not + * @param Object $object Stock Transfer object + * @return boolean true if at least one line has batch set, false if not  */ public function atLeastOneBatch($object) { diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_list.php b/htdocs/product/stock/stocktransfer/stocktransfer_list.php index a371b252732..3ef27f37557 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_list.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_list.php @@ -220,7 +220,7 @@ foreach ($object->fields as $key => $val) { } // 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.', ' : ''); + 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(); From 61a34829c133effe7a44e87e22af96659df9f154 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 20 Oct 2021 09:11:08 +0200 Subject: [PATCH 036/128] FIX : this is a development version --- htdocs/core/modules/modStockTransfer.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index 24bdd4b42d0..5d11464d644 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -66,7 +66,7 @@ class modStockTransfer 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 = 'dolibarr'; + $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 210926d23a7cf2f3cfdd28bb7216b832a863f4b3 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 20 Oct 2021 09:32:03 +0200 Subject: [PATCH 037/128] FIX : action buttons only if $permissiontoadd --- .../stocktransfer/stocktransfer_card.php | 165 +++++++++--------- 1 file changed, 84 insertions(+), 81 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 0c1d46bcd3e..7a2c3547bd8 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -281,89 +281,92 @@ if (empty($reshook)) { } } - // Décrémentation - if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { - $lines = $object->getLinesArray(); - if (!empty($lines)) { - $db->begin(); - foreach ($lines as $line) { - $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source); - if ($res <= 0) $error++; + if($permissiontoadd) { + // Décrémentation + if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { + $lines = $object->getLinesArray(); + if (!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source); + if ($res <= 0) $error++; + } + if (empty($error)) $db->commit(); + else $db->rollback(); + } + if (empty($error)) { + $object->setStatut($object::STATUS_TRANSFERED, $id); + $object->status = $object::STATUS_TRANSFERED; + $object->date_reelle_depart = date('Y-m-d'); + $object->update($user); + setEventMessage('StockStransferDecremented'); } - if (empty($error)) $db->commit(); - else $db->rollback(); } - if (empty($error)) { - $object->setStatut($object::STATUS_TRANSFERED, $id); - $object->status = $object::STATUS_TRANSFERED; - $object->date_reelle_depart = date('Y-m-d'); - $object->update($user); - setEventMessage('StockStransferDecremented'); + + // Annulation décrémentation + if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + $lines = $object->getLinesArray(); + if (!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source, 0); + if ($res <= 0) $error++; + } + if (empty($error)) $db->commit(); + else $db->rollback(); + } + if (empty($error)) { + $object->setStatut($object::STATUS_VALIDATED, $id); + $object->status = $object::STATUS_VALIDATED; + $object->date_reelle_depart = null; + $object->update($user); + setEventMessage('StockStransferDecrementedCancel', 'warnings'); + } + } + + // Incrémentation + if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { + $lines = $object->getLinesArray(); + if (!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination, 0); + if ($res <= 0) $error++; + } + if (empty($error)) $db->commit(); + else $db->rollback(); + } + if (empty($error)) { + $object->setStatut($object::STATUS_CLOSED, $id); + $object->status = $object::STATUS_CLOSED; + $object->date_reelle_arrivee = date('Y-m-d'); + $object->update($user); + setEventMessage('StockStransferIncrementedShort'); + } + } + + // Annulation incrémentation + if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { + $lines = $object->getLinesArray(); + if (!empty($lines)) { + $db->begin(); + foreach ($lines as $line) { + $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination); + if ($res <= 0) $error++; + } + if (empty($error)) $db->commit(); + else $db->rollback(); + } + if (empty($error)) { + $object->setStatut($object::STATUS_TRANSFERED, $id); + $object->status = $object::STATUS_TRANSFERED; + $object->date_reelle_arrivee = null; + $object->update($user); + setEventMessage('StockStransferIncrementedShortCancel', 'warnings'); + } } } - // Annulation décrémentation - if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { - $lines = $object->getLinesArray(); - if (!empty($lines)) { - $db->begin(); - foreach ($lines as $line) { - $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source, 0); - if ($res <= 0) $error++; - } - if (empty($error)) $db->commit(); - else $db->rollback(); - } - if (empty($error)) { - $object->setStatut($object::STATUS_VALIDATED, $id); - $object->status = $object::STATUS_VALIDATED; - $object->date_reelle_depart = null; - $object->update($user); - setEventMessage('StockStransferDecrementedCancel', 'warnings'); - } - } - - // Incrémentation - if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) { - $lines = $object->getLinesArray(); - if (!empty($lines)) { - $db->begin(); - foreach ($lines as $line) { - $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination, 0); - if ($res <= 0) $error++; - } - if (empty($error)) $db->commit(); - else $db->rollback(); - } - if (empty($error)) { - $object->setStatut($object::STATUS_CLOSED, $id); - $object->status = $object::STATUS_CLOSED; - $object->date_reelle_arrivee = date('Y-m-d'); - $object->update($user); - setEventMessage('StockStransferIncrementedShort'); - } - } - - // Annulation incrémentation - if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) { - $lines = $object->getLinesArray(); - if (!empty($lines)) { - $db->begin(); - foreach ($lines as $line) { - $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination); - if ($res <= 0) $error++; - } - if (empty($error)) $db->commit(); - else $db->rollback(); - } - if (empty($error)) { - $object->setStatut($object::STATUS_TRANSFERED, $id); - $object->status = $object::STATUS_TRANSFERED; - $object->date_reelle_arrivee = null; - $object->update($user); - setEventMessage('StockStransferIncrementedShortCancel', 'warnings'); - } - } // Set incoterm if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $permissiontoadd) { $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); @@ -982,12 +985,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''.$langs->trans("Validate").''; } } - } elseif ($object->status == $object::STATUS_VALIDATED) { + } elseif ($object->status == $object::STATUS_VALIDATED && $permissiontoadd) { print ''.$langs->trans("StockTransferDecrementation").''; - } elseif ($object->status == $object::STATUS_TRANSFERED) { + } elseif ($object->status == $object::STATUS_TRANSFERED && $permissiontoadd) { print ''.$langs->trans("StockTransferDecrementationCancel").''; print ''.$langs->trans("StockTransferIncrementation").''; - } elseif ($object->status == $object::STATUS_CLOSED) { + } elseif ($object->status == $object::STATUS_CLOSED && $permissiontoadd) { print ''.$langs->trans("StockTransferIncrementationCancel").''; } From a8f69a2fb65fb5a3286b2698ecbb00d9e42d4b6f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 20 Oct 2021 07:34:52 +0000 Subject: [PATCH 038/128] Fixing style errors. --- htdocs/product/stock/stocktransfer/stocktransfer_card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 7a2c3547bd8..50e4e4f81f9 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -281,7 +281,7 @@ if (empty($reshook)) { } } - if($permissiontoadd) { + if ($permissiontoadd) { // Décrémentation if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) { $lines = $object->getLinesArray(); From 738f6a90b201599472a4868f98f5ae4e2c7a71a5 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 20 Oct 2021 09:48:26 +0200 Subject: [PATCH 039/128] FIX : $childtablesoncascade use + fix $permissiontodelete --- .../stock/stocktransfer/class/stocktransfer.class.php | 11 +++++------ .../stock/stocktransfer/stocktransfer_card.php | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index acd60346fe1..d6183242453 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -170,7 +170,7 @@ class StockTransfer extends CommonObject * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object */ - //protected $childtablesoncascade = array('stocktransfer_stocktransferdet'); + protected $childtablesoncascade = array('stocktransfer_stocktransferline'); /** * @var StockTransferLine[] Array of subtable lines @@ -487,12 +487,11 @@ class StockTransfer extends CommonObject */ public function delete(User $user, $notrigger = false) { - if (empty($this->lines)) $this->fetchLines(); - if (!empty($this->lines)) { - foreach ($this->lines as $l) $res = $this->deleteLine($user, $l->id); + if($this->status > self::STATUS_VALIDATED) { + return 0; + } else { + return $this->deleteCommon($user, $notrigger); } - return $this->deleteCommon($user, $notrigger); - //return $this->deleteCommon($user, $notrigger, 1); } /** diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 7a2c3547bd8..07613883497 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -117,6 +117,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ $permissiontoread = $user->rights->stocktransfer->stocktransfer->read; $permissiontoadd = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php $permissionnote = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_setnotes.inc.php +$permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); $permissiondellink = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_dellink.inc.php $upload_dir = $conf->stocktransfer->multidir_output[isset($object->entity) ? $object->entity : 1]; @@ -157,7 +158,7 @@ if (empty($reshook)) { // 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'; - // On met cette permission ici car nécessaire d'avoir le dernier statut de l'objet après toute action exécutée dessus + // On remet cette lecture de permission ici car nécessaire d'avoir le nouveau statut de l'objet après toute action exécutée dessus (après incrémentation par exemple, le bouton supprimer doit disparaître) $permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); // Actions when linking object each other From daa7e56d3551011331a55b3a6902c9c1717570b8 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 20 Oct 2021 07:52:24 +0000 Subject: [PATCH 040/128] Fixing style errors. --- .../product/stock/stocktransfer/class/stocktransfer.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index d6183242453..d8f987a5b53 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -487,7 +487,7 @@ class StockTransfer extends CommonObject */ public function delete(User $user, $notrigger = false) { - if($this->status > self::STATUS_VALIDATED) { + if ($this->status > self::STATUS_VALIDATED) { return 0; } else { return $this->deleteCommon($user, $notrigger); From 96f78adb9280d466ed2a1a2f5058153c3fedb3c2 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 10 Mar 2022 11:07:00 +0100 Subject: [PATCH 041/128] FIX : travis feedback, tms without "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" --- .../tables/llx_stocktransfer_stocktransfer_extrafields.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql index 33a91fc1070..e03a0bf5343 100644 --- a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql @@ -16,7 +16,7 @@ create table llx_stocktransfer_stocktransfer_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_object integer NOT NULL, import_key varchar(14) -- import key ) ENGINE=innodb; From 9e2c8ffe37a30ee135ace4a09395629ca4c7d8dd Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 10 Mar 2022 11:10:38 +0100 Subject: [PATCH 042/128] FIX : test for stickler feedback --- htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 34f6a94fc35..259dcdbdcfa 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -865,10 +865,10 @@ class pdf_eagle extends ModelePdfStockTransfer } /** - * Used to know if at least one line of Stock Transfer object has a batch set + * Used to know if at least one line of Stock Transfer object has a batch set  * - * @param Object $object Stock Transfer object - * @return boolean true if at least one line has batch set, false if not + * @param Object $object Stock Transfer object + * @return boolean true if at least one line has batch set, false if not  */ public function atLeastOneBatch($object) { From db7bd84ec3c31ac3ab68e4636396c43a08dcbe33 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 10 Mar 2022 11:29:53 +0100 Subject: [PATCH 043/128] FIX : tms without DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP --- .../tables/llx_stocktransfer_stocktransferline_extrafields.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql index 5b5080441bd..ecb256699b5 100644 --- a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql @@ -16,7 +16,7 @@ create table llx_stocktransfer_stocktransferline_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_object integer NOT NULL, import_key varchar(14) -- import key ) ENGINE=innodb; From 732724ea51b1d55e790eb79d41249887dbc75611 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 10 Mar 2022 11:37:52 +0100 Subject: [PATCH 044/128] FIX : move all sql stock transfer queries into 15 => 16 migration file --- .../install/mysql/migration/14.0.0-15.0.0.sql | 83 ------------------- .../install/mysql/migration/15.0.0-16.0.0.sql | 82 ++++++++++++++++++ 2 files changed, 82 insertions(+), 83 deletions(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 4f6c6df88fe..3e0fa10ccd0 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -392,89 +392,6 @@ ALTER TABLE llx_societe_perentity ADD COLUMN accountancy_code_supplier varchar(2 ALTER TABLE llx_projet_task ADD COLUMN budget_amount double(24,8) AFTER priority; - --- Stock transfers module - -CREATE TABLE llx_stocktransfer_stocktransfer( - -- BEGIN MODULEBUILDER FIELDS - rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - entity integer DEFAULT 1 NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, - label varchar(255), - fk_soc integer, - fk_project integer, - fk_warehouse_source integer, - fk_warehouse_destination integer, - description text, - note_public text, - note_private text, - tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - date_creation datetime NOT NULL, - date_prevue_depart date DEFAULT NULL, - date_reelle_depart date DEFAULT NULL, - date_prevue_arrivee date DEFAULT NULL, - date_reelle_arrivee date DEFAULT NULL, - lead_time_for_warning integer DEFAULT NULL, - fk_user_creat integer NOT NULL, - fk_user_modif integer, - import_key varchar(14), - model_pdf varchar(255), - last_main_doc varchar(255), - status smallint NOT NULL, - fk_incoterms integer, -- for incoterms - location_incoterms varchar(255) - -- END MODULEBUILDER FIELDS -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_rowid (rowid); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_ref (ref); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_soc (fk_soc); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_project (fk_project); -ALTER TABLE llx_stocktransfer_stocktransfer ADD CONSTRAINT llx_stocktransfer_stocktransfer_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_status (status); - -CREATE TABLE llx_stocktransfer_stocktransferline( - -- BEGIN MODULEBUILDER FIELDS - rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - amount double DEFAULT NULL, - qty real, - fk_warehouse_source integer NOT NULL, - fk_warehouse_destination integer NOT NULL, - fk_stocktransfer integer NOT NULL, - fk_product integer NOT NULL, - batch varchar(128) DEFAULT NULL, -- Lot or serial number - pmp double, - rang integer DEFAULT 0, - fk_parent_line integer NULL - -- END MODULEBUILDER FIELDS -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransferline ADD INDEX idx_stocktransfer_stocktransferline_rowid (rowid); - -create table llx_stocktransfer_stocktransfer_extrafields -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, - fk_object integer NOT NULL, - import_key varchar(14) -- import key -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransfer_extrafields ADD INDEX idx_fk_object(fk_object); - -create table llx_stocktransfer_stocktransferline_extrafields -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, - fk_object integer NOT NULL, - import_key varchar(14) -- import key -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransferline_extrafields ADD INDEX idx_fk_object(fk_object); - -ALTER TABLE llx_stock_mouvement CHANGE origintype origintype VARCHAR(64) - --- End Stock transfers module - -- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_graph_ticket_by_severity.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_graph_ticket_by_severity.php' AND entity = 1); -- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_graph_nb_ticket_last_x_days.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_graph_nb_ticket_last_x_days.php' AND entity = 1); -- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_graph_nb_tickets_type.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_graph_nb_tickets_type.php' AND entity = 1); diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 3f313c180eb..44eded1a679 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -280,3 +280,85 @@ ALTER TABLE llx_propal ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; UPDATE llx_c_country SET eec=0 WHERE eec IS NULL; ALTER TABLE llx_c_country MODIFY COLUMN eec tinyint DEFAULT 0 NOT NULL; + +-- Stock transfers module + +CREATE TABLE llx_stocktransfer_stocktransfer( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + entity integer DEFAULT 1 NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + fk_soc integer, + fk_project integer, + fk_warehouse_source integer, + fk_warehouse_destination integer, + description text, + note_public text, + note_private text, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + date_creation datetime NOT NULL, + date_prevue_depart date DEFAULT NULL, + date_reelle_depart date DEFAULT NULL, + date_prevue_arrivee date DEFAULT NULL, + date_reelle_arrivee date DEFAULT NULL, + lead_time_for_warning integer DEFAULT NULL, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + last_main_doc varchar(255), + status smallint NOT NULL, + fk_incoterms integer, -- for incoterms + location_incoterms varchar(255) + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_rowid (rowid); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_ref (ref); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_soc (fk_soc); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_project (fk_project); +ALTER TABLE llx_stocktransfer_stocktransfer ADD CONSTRAINT llx_stocktransfer_stocktransfer_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_status (status); + +CREATE TABLE llx_stocktransfer_stocktransferline( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + amount double DEFAULT NULL, + qty real, + fk_warehouse_source integer NOT NULL, + fk_warehouse_destination integer NOT NULL, + fk_stocktransfer integer NOT NULL, + fk_product integer NOT NULL, + batch varchar(128) DEFAULT NULL, -- Lot or serial number + pmp double, + rang integer DEFAULT 0, + fk_parent_line integer NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransferline ADD INDEX idx_stocktransfer_stocktransferline_rowid (rowid); + +create table llx_stocktransfer_stocktransfer_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransfer_extrafields ADD INDEX idx_fk_object(fk_object); + +create table llx_stocktransfer_stocktransferline_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_stocktransfer_stocktransferline_extrafields ADD INDEX idx_fk_object(fk_object); + +ALTER TABLE llx_stock_mouvement CHANGE origintype origintype VARCHAR(64) + +-- End Stock transfers module From b73e1019edbbc8764d5b621f1e36f8578291aa4a Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 10 Mar 2022 12:02:25 +0100 Subject: [PATCH 045/128] FIX : cast int sql --- .../product/stock/stocktransfer/class/stocktransfer.class.php | 2 +- .../stock/stocktransfer/class/stocktransferline.class.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index d8f987a5b53..a144895e836 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -849,7 +849,7 @@ class StockTransfer extends CommonObject $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; + $sql .= ' WHERE t.rowid = '.((int) $id); $result = $this->db->query($sql); if ($result) { if ($this->db->num_rows($result)) { diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 3a362395dd8..31549e04832 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -873,7 +873,7 @@ class StockTransferLine extends CommonObjectLine $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; + $sql .= ' WHERE t.rowid = '.((int) $id); $result = $this->db->query($sql); if ($result) { if ($this->db->num_rows($result)) { @@ -929,7 +929,7 @@ class StockTransferLine extends CommonObjectLine $this->lines = array(); $objectline = new StockTransferLineLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.$this->id)); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.((int) $this->id))); if (is_numeric($result)) { $this->error = $this->error; From 5daca35e791e74f25514f208549670ebb5b55966 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 9 May 2022 12:33:39 +0200 Subject: [PATCH 046/128] FIX : new tables loading system --- .../core/modules/modStockTransfer.class.php | 2 +- .../install/mysql/migration/15.0.0-16.0.0.sql | 84 ------------------- ...nsfer_stocktransfer-stocktransfer.key.sql} | 0 ...ktransfer_stocktransfer-stocktransfer.sql} | 0 ...ransfer_extrafields-stocktransfer.key.sql} | 0 ...ocktransfer_extrafields-stocktransfer.sql} | 0 ...r_stocktransferline-stocktransfer.key.sql} | 0 ...nsfer_stocktransferline-stocktransfer.sql} | 0 ...ferline_extrafields-stocktransfer.key.sql} | 0 ...ransferline_extrafields-stocktransfer.sql} | 0 10 files changed, 1 insertion(+), 85 deletions(-) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransfer.key.sql => llx_stocktransfer_stocktransfer-stocktransfer.key.sql} (100%) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransfer.sql => llx_stocktransfer_stocktransfer-stocktransfer.sql} (100%) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransfer_extrafields.key.sql => llx_stocktransfer_stocktransfer_extrafields-stocktransfer.key.sql} (100%) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransfer_extrafields.sql => llx_stocktransfer_stocktransfer_extrafields-stocktransfer.sql} (100%) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransferline.key.sql => llx_stocktransfer_stocktransferline-stocktransfer.key.sql} (100%) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransferline.sql => llx_stocktransfer_stocktransferline-stocktransfer.sql} (100%) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransferline_extrafields.key.sql => llx_stocktransfer_stocktransferline_extrafields-stocktransfer.key.sql} (100%) rename htdocs/install/mysql/tables/{llx_stocktransfer_stocktransferline_extrafields.sql => llx_stocktransfer_stocktransferline_extrafields-stocktransfer.sql} (100%) diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index 5d11464d644..376cf9409f2 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -435,7 +435,7 @@ class modStockTransfer extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/stocktransfer/sql/'); + $result = $this->_load_tables('/install/mysql/tables/', 'stocktransfer'); 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 diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 89b6ff838c4..e1a29588054 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -342,87 +342,3 @@ ALTER TABLE llx_c_partnership_type ADD COLUMN keyword varchar(128); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN firstname varchar(100); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN lastname varchar(100); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN email_company varchar(128) after email; - --- Stock transfers module - -CREATE TABLE llx_stocktransfer_stocktransfer( - -- BEGIN MODULEBUILDER FIELDS - rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - entity integer DEFAULT 1 NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, - label varchar(255), - fk_soc integer, - fk_project integer, - fk_warehouse_source integer, - fk_warehouse_destination integer, - description text, - note_public text, - note_private text, - tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - date_creation datetime NOT NULL, - date_prevue_depart date DEFAULT NULL, - date_reelle_depart date DEFAULT NULL, - date_prevue_arrivee date DEFAULT NULL, - date_reelle_arrivee date DEFAULT NULL, - lead_time_for_warning integer DEFAULT NULL, - fk_user_creat integer NOT NULL, - fk_user_modif integer, - import_key varchar(14), - model_pdf varchar(255), - last_main_doc varchar(255), - status smallint NOT NULL, - fk_incoterms integer, -- for incoterms - location_incoterms varchar(255) - -- END MODULEBUILDER FIELDS -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_rowid (rowid); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_ref (ref); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_soc (fk_soc); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_fk_project (fk_project); -ALTER TABLE llx_stocktransfer_stocktransfer ADD CONSTRAINT llx_stocktransfer_stocktransfer_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); -ALTER TABLE llx_stocktransfer_stocktransfer ADD INDEX idx_stocktransfer_stocktransfer_status (status); - -CREATE TABLE llx_stocktransfer_stocktransferline( - -- BEGIN MODULEBUILDER FIELDS - rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - amount double DEFAULT NULL, - qty real, - fk_warehouse_source integer NOT NULL, - fk_warehouse_destination integer NOT NULL, - fk_stocktransfer integer NOT NULL, - fk_product integer NOT NULL, - batch varchar(128) DEFAULT NULL, -- Lot or serial number - pmp double, - rang integer DEFAULT 0, - fk_parent_line integer NULL - -- END MODULEBUILDER FIELDS -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransferline ADD INDEX idx_stocktransfer_stocktransferline_rowid (rowid); - -create table llx_stocktransfer_stocktransfer_extrafields -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - fk_object integer NOT NULL, - import_key varchar(14) -- import key -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransfer_extrafields ADD INDEX idx_fk_object(fk_object); - -create table llx_stocktransfer_stocktransferline_extrafields -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - fk_object integer NOT NULL, - import_key varchar(14) -- import key -) ENGINE=innodb; - -ALTER TABLE llx_stocktransfer_stocktransferline_extrafields ADD INDEX idx_fk_object(fk_object); - -ALTER TABLE llx_stock_mouvement CHANGE origintype origintype VARCHAR(64) - --- End Stock transfers module - - diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer-stocktransfer.key.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.key.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer-stocktransfer.key.sql diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer-stocktransfer.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer-stocktransfer.sql diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields-stocktransfer.key.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.key.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields-stocktransfer.key.sql diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields-stocktransfer.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransfer_extrafields-stocktransfer.sql diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline-stocktransfer.key.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.key.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline-stocktransfer.key.sql diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline-stocktransfer.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline-stocktransfer.sql diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.key.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields-stocktransfer.key.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.key.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields-stocktransfer.key.sql diff --git a/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql b/htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields-stocktransfer.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields.sql rename to htdocs/install/mysql/tables/llx_stocktransfer_stocktransferline_extrafields-stocktransfer.sql From 08a3ef5bbf5e1aa7b38a9340d183880f1e14ffa1 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Tue, 10 May 2022 12:25:38 +0200 Subject: [PATCH 047/128] NEW : method avoid being blocked when entry already exists for import in llx_categorie_product (use update keys) --- htdocs/core/modules/import/import_csv.modules.php | 14 +++++++++++++- .../core/modules/import/import_xlsx.modules.php | 15 ++++++++++++++- htdocs/core/modules/modCategorie.class.php | 1 + 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 78c8f5e104f..8a99dfe90d2 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -776,11 +776,18 @@ class ImportCsv extends ModeleImports $updatedone = false; $insertdone = false; + $is_table_category_link = false; + $fname = 'rowid'; + if(strpos($tablename, '_categorie_') !== false) { + $is_table_category_link = true; + $fname='*'; + } + if (!empty($updatekeys)) { // We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields) if (empty($lastinsertid)) { // No insert done yet for a parent table - $sqlSelect = 'SELECT rowid FROM '.$tablename; + $sqlSelect = 'SELECT '.$fname.' FROM '.$tablename; $data = array_combine($listfields, $listvalues); $where = array(); @@ -798,6 +805,7 @@ class ImportCsv extends ModeleImports $res = $this->db->fetch_object($resql); if ($resql->num_rows == 1) { $lastinsertid = $res->rowid; + if($is_table_category_link) $lastinsertid = 'linktable'; // used to apply update on tables like llx_categorie_product and avoid being blocked for all file content if at least one entry already exists $last_insert_id_array[$tablename] = $lastinsertid; } elseif ($resql->num_rows > 1) { $this->errors[$error]['lib'] = $langs->trans('MultipleRecordFoundWithTheseFilters', implode(', ', $filters)); @@ -859,6 +867,10 @@ class ImportCsv extends ModeleImports } $sqlend = ' WHERE '.$keyfield.' = '.((int) $lastinsertid); + if($is_table_category_link) { + $sqlend = ' WHERE ' . implode(' AND ', $where); + } + $sql = $sqlstart.$sqlend; // Run update request diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 38c9cd8c56a..c972dcbcb28 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -816,11 +816,19 @@ class ImportXlsx extends ModeleImports if (!empty($listfields)) { $updatedone = false; $insertdone = false; + + $is_table_category_link = false; + $fname = 'rowid'; + if(strpos($tablename, '_categorie_') !== false) { + $is_table_category_link = true; + $fname='*'; + } + if (!empty($updatekeys)) { // We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields) if (empty($lastinsertid)) { // No insert done yet for a parent table - $sqlSelect = 'SELECT rowid FROM ' . $tablename; + $sqlSelect = 'SELECT '.$fname.' FROM ' . $tablename; $data = array_combine($listfields, $listvalues); $where = array(); @@ -838,6 +846,7 @@ class ImportXlsx extends ModeleImports $res = $this->db->fetch_object($resql); if ($resql->num_rows == 1) { $lastinsertid = $res->rowid; + if($is_table_category_link) $lastinsertid = 'linktable'; // used to apply update on tables like llx_categorie_product and avoid being blocked for all file content if at least one entry already exists $last_insert_id_array[$tablename] = $lastinsertid; } elseif ($resql->num_rows > 1) { $this->errors[$error]['lib'] = $langs->trans('MultipleRecordFoundWithTheseFilters', implode(', ', $filters)); @@ -899,6 +908,10 @@ class ImportXlsx extends ModeleImports } $sqlend = ' WHERE ' . $keyfield . ' = '.((int) $lastinsertid); + if($is_table_category_link) { + $sqlend = ' WHERE ' . implode(' AND ', $where); + } + $sql = $sqlstart . $sqlend; // Run update request diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index 776c5c76681..ab48a702250 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -481,6 +481,7 @@ class modCategorie extends DolibarrModules 'cp.fk_product'=>array('rule'=>'fetchidfromref', 'classfile'=>'/product/class/product.class.php', 'class'=>'Product', 'method'=>'fetch', 'element'=>'Product') ); $this->import_examplevalues_array[$r] = array('cp.fk_categorie'=>"rowid or label", 'cp.fk_product'=>"rowid or ref"); + $this->import_updatekeys_array[$r] = array('cp.fk_categorie' => 'Category', 'cp.fk_product' => 'ProductRef'); } // 1 Suppliers From 98f5edbfba15678d1b59d41a7c8f798f358ca400 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 10 May 2022 10:47:18 +0000 Subject: [PATCH 048/128] Fixing style errors. --- htdocs/core/modules/import/import_csv.modules.php | 6 +++--- htdocs/core/modules/import/import_xlsx.modules.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 58ff558b54b..2032730112e 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -787,7 +787,7 @@ class ImportCsv extends ModeleImports $is_table_category_link = false; $fname = 'rowid'; - if(strpos($tablename, '_categorie_') !== false) { + if (strpos($tablename, '_categorie_') !== false) { $is_table_category_link = true; $fname='*'; } @@ -814,7 +814,7 @@ class ImportCsv extends ModeleImports $res = $this->db->fetch_object($resql); if ($resql->num_rows == 1) { $lastinsertid = $res->rowid; - if($is_table_category_link) $lastinsertid = 'linktable'; // used to apply update on tables like llx_categorie_product and avoid being blocked for all file content if at least one entry already exists + if ($is_table_category_link) $lastinsertid = 'linktable'; // used to apply update on tables like llx_categorie_product and avoid being blocked for all file content if at least one entry already exists $last_insert_id_array[$tablename] = $lastinsertid; } elseif ($resql->num_rows > 1) { $this->errors[$error]['lib'] = $langs->trans('MultipleRecordFoundWithTheseFilters', implode(', ', $filters)); @@ -876,7 +876,7 @@ class ImportCsv extends ModeleImports } $sqlend = " WHERE ".$keyfield." = ".((int) $lastinsertid); - if($is_table_category_link) { + if ($is_table_category_link) { $sqlend = " WHERE " . implode(' AND ', $where); } diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 564156e8cc1..9433d864d50 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -828,7 +828,7 @@ class ImportXlsx extends ModeleImports $is_table_category_link = false; $fname = 'rowid'; - if(strpos($tablename, '_categorie_') !== false) { + if (strpos($tablename, '_categorie_') !== false) { $is_table_category_link = true; $fname='*'; } @@ -855,7 +855,7 @@ class ImportXlsx extends ModeleImports $res = $this->db->fetch_object($resql); if ($resql->num_rows == 1) { $lastinsertid = $res->rowid; - if($is_table_category_link) $lastinsertid = 'linktable'; // used to apply update on tables like llx_categorie_product and avoid being blocked for all file content if at least one entry already exists + if ($is_table_category_link) $lastinsertid = 'linktable'; // used to apply update on tables like llx_categorie_product and avoid being blocked for all file content if at least one entry already exists $last_insert_id_array[$tablename] = $lastinsertid; } elseif ($resql->num_rows > 1) { $this->errors[$error]['lib'] = $langs->trans('MultipleRecordFoundWithTheseFilters', implode(', ', $filters)); @@ -917,7 +917,7 @@ class ImportXlsx extends ModeleImports } $sqlend = " WHERE " . $keyfield . " = ".((int) $lastinsertid); - if($is_table_category_link) { + if ($is_table_category_link) { $sqlend = " WHERE " . implode(' AND ', $where); } From e437a53657d378ac765d117359f190442cc959a7 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 23 May 2022 21:40:47 +0200 Subject: [PATCH 049/128] Typo --- htdocs/accountancy/class/accountingaccount.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index a4dcac8c1ad..b50139a2d76 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -732,11 +732,11 @@ class AccountingAccount extends CommonObject global $hookmanager; // Instantiate hooks for external modules - $hookmanager->initHooks(array('accoutancyBindingCalculation')); + $hookmanager->initHooks(array('accountancyBindingCalculation')); - // Execute hook accoutancyBindingCalculation + // Execute hook accountancyBindingCalculation $parameters = array('buyer' => $buyer, 'seller' => $seller, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount, $type); - $reshook = $hookmanager->executeHooks('accoutancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks + $reshook = $hookmanager->executeHooks('accountancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { if ($type == 'customer') { From c5bbbd88afb528e3279e9ec214b553840f6ffe7f Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 24 May 2022 07:14:22 +0200 Subject: [PATCH 050/128] Merge problem --- htdocs/langs/en_US/errors.lang | 8 -------- 1 file changed, 8 deletions(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 61f0c4d71bd..1a4250834b2 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -313,8 +313,6 @@ WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connec WarningModuleXDisabledSoYouMayMissEventHere=Module %s has not been enabled. So you may miss a lot of event here. WarningPaypalPaymentNotCompatibleWithStrict=The value 'Strict' makes the online payment features not working correctly. Use 'Lax' instead. -<<<<<<< HEAD -<<<<<<< HEAD # Validate RequireValidValue = Value not valid RequireAtLeastXString = Requires at least %s character(s) @@ -335,9 +333,3 @@ BadSetupOfField = Error bad setup of field BadSetupOfFieldClassNotFoundForValidation = Error bad setup of field : Class not found for validation BadSetupOfFieldFileNotFound = Error bad setup of field : File not found for inclusion BadSetupOfFieldFetchNotCallable = Error bad setup of field : Fetch not callable on class -======= -======= ->>>>>>> branch '13.0' of git@github.com:Dolibarr/dolibarr.git ->>>>>>> branch '14.0' of git@github.com:Dolibarr/dolibarr.git -======= ->>>>>>> branch '14.0' of git@github.com:Dolibarr/dolibarr.git From 192f273e27dca33865cad196c6b041556bca1e56 Mon Sep 17 00:00:00 2001 From: kamel Date: Tue, 24 May 2022 15:02:35 +0200 Subject: [PATCH 051/128] FIX: Fix show errors in card --- htdocs/contrat/card.php | 7 +++---- htdocs/fichinter/card.php | 10 ++++++++-- htdocs/projet/tasks/task.php | 3 +++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 1466f595b3d..624d59b0d94 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -236,10 +236,6 @@ if (empty($reshook)) { } $id = $object->create($user); - if ($id < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } - if ($id > 0) { dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); @@ -351,6 +347,9 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); $error++; } + if ($error) { + $action = 'create'; + } } else { $result = $object->create($user); if ($result > 0) { diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 225f9ebacb8..8fb73d1b780 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -375,11 +375,15 @@ if (empty($reshook)) { } } } else { - $mesg = $srcobject->error; + $langs->load("errors"); + setEventMessages($srcobject->error, $srcobject->errors, 'errors'); + $action = 'create'; $error++; } } else { - $mesg = $object->error; + $langs->load("errors"); + setEventMessages($object->error, $object->errors, 'errors'); + $action = 'create'; $error++; } } else { @@ -403,12 +407,14 @@ if (empty($reshook)) { $langs->load("errors"); setEventMessages($object->error, $object->errors, 'errors'); $action = 'create'; + $error++; } } } } else { $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ThirdParty")); $action = 'create'; + $error++; } } elseif ($action == 'update' && $user->rights->ficheinter->creer) { $object->socid = $socid; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index bec61ec0f48..86ac5b3caab 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -116,7 +116,10 @@ if ($action == 'update' && !GETPOST("cancel") && $user->rights->projet->creer) { $result = $object->update($user); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); + $action='edit'; } + } else { + $action = 'edit'; } } else { $action = 'edit'; From 79462c43fa57d754ddb02746a376275f14ebe2b8 Mon Sep 17 00:00:00 2001 From: kamel Date: Tue, 24 May 2022 15:13:19 +0200 Subject: [PATCH 052/128] FIX: Fix get origin from other than supplier proposal when add a new supplier proposal --- htdocs/supplier_proposal/card.php | 32 +++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 1500f00ba91..4ad5fa9ff56 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -303,8 +303,20 @@ if (empty($reshook)) { if (!$error) { if ($origin && $originid) { - $element = 'supplier_proposal'; - $subelement = 'supplier_proposal'; + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { + $element = $regs[1]; + $subelement = $regs[2]; + } + + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; + $subelement = 'propal'; + } $object->origin = $origin; $object->origin_id = $originid; @@ -1063,8 +1075,20 @@ if ($action == 'create') { // Load objectsrc if (!empty($origin) && !empty($originid)) { - $element = 'supplier_proposal'; - $subelement = 'supplier_proposal'; + $element = $subelement = GETPOST('origin'); + if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'), $regs)) { + $element = $regs[1]; + $subelement = $regs[2]; + } + + // For compatibility + if ($element == 'order' || $element == 'commande') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; + $subelement = 'propal'; + } dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); From 9d31d6448c3c19acaea2e8a109ff52f6a1c78775 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Wed, 25 May 2022 09:59:45 +0200 Subject: [PATCH 053/128] Fix btn confirm url --- htdocs/core/lib/functions.lib.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 43a549655b9..93fbf98e81b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10043,9 +10043,11 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = // Js Confirm button if ($userRight && !empty($params['confirm'])) { if (!is_array($params['confirm'])) { - $params['confirm'] = array( - 'url' => $url . (strpos($url, '?') > 0 ? '&' : '?') . 'confirm=yes' - ); + $params['confirm'] = array(); + } + + if (empty($params['confirm'])) { + $params['confirm']['url'] = $url . (strpos($url, '?') > 0 ? '&' : '?') . 'confirm=yes'; } // for js desabled compatibility set $url as call to confirm action and $params['confirm']['url'] to confirmed action From e07827a0befca2d2a0c28a1edf7262a57889cf8a Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Wed, 25 May 2022 10:03:08 +0200 Subject: [PATCH 054/128] Fix btn confirm url --- 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 93fbf98e81b..99320a47072 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10046,7 +10046,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = $params['confirm'] = array(); } - if (empty($params['confirm'])) { + if (empty($params['confirm']['url'])) { $params['confirm']['url'] = $url . (strpos($url, '?') > 0 ? '&' : '?') . 'confirm=yes'; } From 4e289741f9bc0c0e6cc057bfa8c01847107d5a4b Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 25 May 2022 16:59:23 +0200 Subject: [PATCH 055/128] fix: extrafields chkbxlst or checkbox or badly displayed in line object --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/theme/eldy/global.inc.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 8df70054d11..9dad6b49279 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7571,7 +7571,7 @@ abstract class CommonObject if ($display_type == 'card') { $out .= ''; } elseif ($display_type == 'line') { - $out .= '
'; + $out .= '
'; } switch ($mode) { diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 9eb479d93ad..61b60a00644 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -7104,6 +7104,11 @@ if (!empty($conf->global->THEME_CUSTOM_CSS)) { ?> + div.extra_inline_chkbxlst, + div.extra_inline_checkbox { + min-width:150px; + } + /* Must be at end */ div.flot-text .flot-tick-label .tickLabel { color: unset; From f1914ff66f248ac20bee36eb96bd891a15427f14 Mon Sep 17 00:00:00 2001 From: kamel Date: Wed, 25 May 2022 18:02:18 +0200 Subject: [PATCH 056/128] FIX: Show sellist type of extrafield when none category selected --- htdocs/core/class/extrafields.class.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 7a449f3e7ea..6e4f6892e05 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1766,15 +1766,18 @@ class ExtraFields } } } else { - require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - $toprint = array(); $obj = $this->db->fetch_object($resql); - $c = new Categorie($this->db); - $c->fetch($obj->rowid); - $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text - foreach ($ways as $way) { - $toprint[] = '
  • color ? ' style="background: #'.$c->color.';"' : ' style="background: #bbb"').'>'.img_object('', 'category').' '.$way.'
  • '; + if ($obj->rowid) { + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $result = $c->fetch($obj->rowid); + if ($result > 0) { + $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text + foreach ($ways as $way) { + $toprint[] = '
  • color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . img_object('', 'category') . ' ' . $way . '
  • '; + } + } } $value = '
      '.implode(' ', $toprint).'
    '; } From 9c5ee2d0b92bc09bc082638047562675b65ce9f8 Mon Sep 17 00:00:00 2001 From: Neal Joos Date: Wed, 25 May 2022 22:50:16 +0200 Subject: [PATCH 057/128] fix broken links fixed DoliWamp and DoliDeb links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5559613eaa2..9250259aa20 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ Other licenses apply for some included dependencies. See [COPYRIGHT](https://git If you have low technical skills and you're looking to install Dolibarr ERP/CRM in just a few clicks, you can use one of the packaged versions: -- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_DoliWamp) -- [DoliDeb for Debian](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian) +- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php?title=Dolibarr_for_Windows_(DoliWamp)) +- [DoliDeb for Debian](https://wiki.dolibarr.org/index.php?title=Dolibarr_for_Ubuntu_or_Debian) - DoliRpm for Redhat, Fedora, OpenSuse, Mandriva or Mageia Releases can be downloaded from [official website](https://www.dolibarr.org/). From 8f736b3ecb1aaa30d8ca90a981b323d9b343c68b Mon Sep 17 00:00:00 2001 From: DATUC Date: Thu, 26 May 2022 12:57:27 +0100 Subject: [PATCH 058/128] Local CM adjust Local ref update --- htdocs/langs/en_US/companies.lang | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 8f44b999a3a..c4a964b6b62 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -163,14 +163,14 @@ ProfId5CL=- ProfId6CL=- ProfId1CM=Id. prof. 1 (Trade Register) ProfId2CM=Id. prof. 2 (Taxpayer No.) -ProfId3CM=Id. prof. 3 (Decree of creation) -ProfId4CM=Id. prof. 4 (Certificate of deposits) +ProfId3CM=Id. prof. 3 (No. of creation decree) +ProfId4CM=Id. prof. 4 (Deposit certificate No.) ProfId5CM=Id. prof. 5 (Others) ProfId6CM=- ProfId1ShortCM=Trade Register ProfId2ShortCM=Taxpayer No. -ProfId3ShortCM=Decree of creation -ProfId4ShortCM=Certificate of deposits +ProfId3ShortCM=No. of creation decree +ProfId4ShortCM=Deposit certificate No. ProfId5ShortCM=Others ProfId6ShortCM=- ProfId1CO=Prof Id 1 (R.U.T.) From d14faf86a028b4a93aabd6d81a640d9cb6252534 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Fri, 27 May 2022 16:14:36 +0200 Subject: [PATCH 059/128] php V8 warning fix --- htdocs/accountancy/admin/defaultaccounts.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 6d7d92ce22b..583b12368dc 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -81,22 +81,22 @@ $list_account[] = '---Others---'; $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT'; -if ($conf->banque->enabled) { +if (!empty($conf->banque->enabled)) { $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH'; } -if ($conf->don->enabled) { +if (!empty($conf->don->enabled)) { $list_account[] = 'DONATION_ACCOUNTINGACCOUNT'; } -if ($conf->adherent->enabled) { +if (!empty($conf->adherent->enabled)) { $list_account[] = 'ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT'; } -if ($conf->loan->enabled) { +if (!empty($conf->loan->enabled)) { $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL'; $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INTEREST'; $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE'; } $list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE'; -if ($conf->societe->enabled) { +if (!empty($conf->societe->enabled)) { $list_account[] = '---Deposits---'; $list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT'; } @@ -246,7 +246,7 @@ foreach ($list_account as $key) { } } -if ($conf->societe->enabled) { +if (!empty($conf->societe->enabled)) { print ''; print '' . img_picto('', 'bill', 'class="pictofixedwidth"') . $langs->trans("UseAuxiliaryAccountOnCustomerDeposit") . ''; if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT)) { From ebfc5666988b76da0087fbc7d8d795cf37c2f490 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Fri, 27 May 2022 16:16:41 +0200 Subject: [PATCH 060/128] php V8 warning --- htdocs/admin/supplier_proposal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 9bd684afb22..80f2c6a62f4 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -498,7 +498,7 @@ print '\n"; print ''; -if ($conf->banque->enabled) { +if (!empty($conf->banque->enabled)) { print ''; print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_PROPOSAL").' '; if (!empty($conf->use_javascript_ajax)) { From 0bf09e0fb263715f48c4650800d197196efd53c1 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Fri, 27 May 2022 16:22:01 +0200 Subject: [PATCH 061/128] php V8 fix warning --- htdocs/blockedlog/class/blockedlog.class.php | 66 +++++++------------- 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index 578e1afa497..a313d28d938 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -1,6 +1,7 @@ - * Copyright (C) 2017-2020 Laurent Destailleur +/* Copyright (C) 2017 ATM Consulting + * Copyright (C) 2017-2020 Laurent Destailleur + * Copyright (C) 2022 charlene benke * * 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 @@ -139,76 +140,53 @@ class BlockedLog $this->trackedevents = array(); - if ($conf->facture->enabled) { + if (!empty($conf->facture->enabled)) { $this->trackedevents['BILL_VALIDATE'] = 'logBILL_VALIDATE'; - } - if ($conf->facture->enabled) { $this->trackedevents['BILL_DELETE'] = 'logBILL_DELETE'; - } - if ($conf->facture->enabled) { $this->trackedevents['BILL_SENTBYMAIL'] = 'logBILL_SENTBYMAIL'; - } - if ($conf->facture->enabled) { $this->trackedevents['DOC_DOWNLOAD'] = 'BlockedLogBillDownload'; - } - if ($conf->facture->enabled) { $this->trackedevents['DOC_PREVIEW'] = 'BlockedLogBillPreview'; - } - if ($conf->facture->enabled) { $this->trackedevents['PAYMENT_CUSTOMER_CREATE'] = 'logPAYMENT_CUSTOMER_CREATE'; - } - if ($conf->facture->enabled) { $this->trackedevents['PAYMENT_CUSTOMER_DELETE'] = 'logPAYMENT_CUSTOMER_DELETE'; } /* Supplier - if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_VALIDATE']='BlockedLogSupplierBillValidate'; - if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_DELETE']='BlockedLogSupplierBillDelete'; - if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_SENTBYMAIL']='BlockedLogSupplierBillSentByEmail'; // Trigger key does not exists, we want just into array to list it as done - if ($conf->fournisseur->enabled) $this->trackedevents['SUPPLIER_DOC_DOWNLOAD']='BlockedLogSupplierBillDownload'; // Trigger key does not exists, we want just into array to list it as done - if ($conf->fournisseur->enabled) $this->trackedevents['SUPPLIER_DOC_PREVIEW']='BlockedLogSupplierBillPreview'; // Trigger key does not exists, we want just into array to list it as done + if (!empty($conf->fournisseur->enabled)) { + $this->trackedevents['BILL_SUPPLIER_VALIDATE']='BlockedLogSupplierBillValidate'; + $this->trackedevents['BILL_SUPPLIER_DELETE']='BlockedLogSupplierBillDelete'; + $this->trackedevents['BILL_SUPPLIER_SENTBYMAIL']='BlockedLogSupplierBillSentByEmail'; // Trigger key does not exists, we want just into array to list it as done + $this->trackedevents['SUPPLIER_DOC_DOWNLOAD']='BlockedLogSupplierBillDownload'; // Trigger key does not exists, we want just into array to list it as done + $this->trackedevents['SUPPLIER_DOC_PREVIEW']='BlockedLogSupplierBillPreview'; // Trigger key does not exists, we want just into array to list it as done - if ($conf->fournisseur->enabled) $this->trackedevents['PAYMENT_SUPPLIER_CREATE']='BlockedLogSupplierBillPaymentCreate'; - if ($conf->fournisseur->enabled) $this->trackedevents['PAYMENT_SUPPLIER_DELETE']='BlockedLogsupplierBillPaymentCreate'; + $this->trackedevents['PAYMENT_SUPPLIER_CREATE']='BlockedLogSupplierBillPaymentCreate'; + $this->trackedevents['PAYMENT_SUPPLIER_DELETE']='BlockedLogsupplierBillPaymentCreate'; + } */ - if ($conf->don->enabled) { + if (!empty($conf->don->enabled)) { $this->trackedevents['DON_VALIDATE'] = 'logDON_VALIDATE'; - } - if ($conf->don->enabled) { $this->trackedevents['DON_DELETE'] = 'logDON_DELETE'; - } - //if ($conf->don->enabled) $this->trackedevents['DON_SENTBYMAIL']='logDON_SENTBYMAIL'; - - if ($conf->don->enabled) { + //$this->trackedevents['DON_SENTBYMAIL']='logDON_SENTBYMAIL'; $this->trackedevents['DONATION_PAYMENT_CREATE'] = 'logDONATION_PAYMENT_CREATE'; - } - if ($conf->don->enabled) { $this->trackedevents['DONATION_PAYMENT_DELETE'] = 'logDONATION_PAYMENT_DELETE'; } /* - if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_CREATE']='BlockedLogSalaryPaymentCreate'; - if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_MODIFY']='BlockedLogSalaryPaymentCreate'; - if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_DELETE']='BlockedLogSalaryPaymentCreate'; + if (!empty($conf->salary->enabled)) { + $this->trackedevents['PAYMENT_SALARY_CREATE']='BlockedLogSalaryPaymentCreate'; + $this->trackedevents['PAYMENT_SALARY_MODIFY']='BlockedLogSalaryPaymentCreate'; + $this->trackedevents['PAYMENT_SALARY_DELETE']='BlockedLogSalaryPaymentCreate'; + } */ - if ($conf->adherent->enabled) { + if (!empty($conf->adherent->enabled)) { $this->trackedevents['MEMBER_SUBSCRIPTION_CREATE'] = 'logMEMBER_SUBSCRIPTION_CREATE'; - } - if ($conf->adherent->enabled) { $this->trackedevents['MEMBER_SUBSCRIPTION_MODIFY'] = 'logMEMBER_SUBSCRIPTION_MODIFY'; - } - if ($conf->adherent->enabled) { $this->trackedevents['MEMBER_SUBSCRIPTION_DELETE'] = 'logMEMBER_SUBSCRIPTION_DELETE'; } - if ($conf->banque->enabled) { + if (!empty($conf->banque->enabled)) { $this->trackedevents['PAYMENT_VARIOUS_CREATE'] = 'logPAYMENT_VARIOUS_CREATE'; - } - if ($conf->banque->enabled) { $this->trackedevents['PAYMENT_VARIOUS_MODIFY'] = 'logPAYMENT_VARIOUS_MODIFY'; - } - if ($conf->banque->enabled) { $this->trackedevents['PAYMENT_VARIOUS_DELETE'] = 'logPAYMENT_VARIOUS_DELETE'; } // $conf->global->BANK_ENABLE_POS_CASHCONTROL must be set to 1 by all external POS modules From d36175c523d62102999c750032629b7b05c7325b Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Fri, 27 May 2022 16:23:57 +0200 Subject: [PATCH 062/128] php V8 warning --- htdocs/core/menus/standard/auguria.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 556ee3e609a..ea6d21fe457 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -339,7 +339,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t $newmenu = $menuArbo->menuLeftCharger($newmenu, $mainmenu, $leftmenu, ($user->socid ? 1 : 0), 'auguria', $tabMenu); // We update newmenu for special dynamic menus - if ($conf->banque->enabled && $user->rights->banque->lire && $mainmenu == 'bank') { // Entry for each bank account + if (!empty($conf->banque->enabled) && $user->rights->banque->lire && $mainmenu == 'bank') { // Entry for each bank account include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Required for to get Account::TYPE_CASH for example $sql = "SELECT rowid, label, courant, rappro, courant"; From c257d77dc30e4652c819d4486dfadfd93ce89b28 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 28 May 2022 09:47:21 +0200 Subject: [PATCH 063/128] php V8 warning --- htdocs/adherents/admin/member.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/admin/member.php b/htdocs/adherents/admin/member.php index ed2453ef793..bae229bc77b 100644 --- a/htdocs/adherents/admin/member.php +++ b/htdocs/adherents/admin/member.php @@ -108,7 +108,7 @@ if ($action == 'set_default') { $res3 = dolibarr_set_const($db, 'ADHERENT_CREATE_EXTERNAL_USER_LOGIN', GETPOST('ADHERENT_CREATE_EXTERNAL_USER_LOGIN', 'alpha'), 'chaine', 0, '', $conf->entity); $res4 = dolibarr_set_const($db, 'ADHERENT_BANK_USE', GETPOST('ADHERENT_BANK_USE', 'alpha'), 'chaine', 0, '', $conf->entity); // Use vat for invoice creation - if ($conf->facture->enabled) { + if (!empty($conf->facture->enabled)) { $res4 = dolibarr_set_const($db, 'ADHERENT_VAT_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_VAT_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity); $res5 = dolibarr_set_const($db, 'ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity); if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { @@ -256,7 +256,7 @@ print ''; print "\n"; // Use vat for invoice creation -if ($conf->facture->enabled) { +if (!empty($conf->facture->enabled)) { print ''.$langs->trans("VATToUseForSubscriptions").''; if (!empty($conf->banque->enabled)) { print ''; From 0b3e32a2236f05f34c8dfa7fd6fe4a825a126f9b Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 28 May 2022 09:52:03 +0200 Subject: [PATCH 064/128] fix php v8 warning --- htdocs/contact/consumption.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/contact/consumption.php b/htdocs/contact/consumption.php index dc4b56b2763..b7fc682d2c6 100644 --- a/htdocs/contact/consumption.php +++ b/htdocs/contact/consumption.php @@ -153,16 +153,16 @@ print ''; if ($object->thirdparty->client) { $thirdTypeArray['customer'] = $langs->trans("customer"); - if ($conf->propal->enabled && $user->rights->propal->lire) { + if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { $elementTypeArray['propal'] = $langs->transnoentitiesnoconv('Proposals'); } - if ($conf->commande->enabled && $user->rights->commande->lire) { + if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { $elementTypeArray['order'] = $langs->transnoentitiesnoconv('Orders'); } - if ($conf->facture->enabled && $user->rights->facture->lire) { + if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { $elementTypeArray['invoice'] = $langs->transnoentitiesnoconv('Invoices'); } - if ($conf->contrat->enabled && $user->rights->contrat->lire) { + if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire) { $elementTypeArray['contract'] = $langs->transnoentitiesnoconv('Contracts'); } } From 4c96921a5f38c8f31756cdf7e224ccd9fb07fe68 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 28 May 2022 09:54:59 +0200 Subject: [PATCH 065/128] php 8 fix warning --- htdocs/core/class/html.formticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 5600f51f5e2..31a48f38cf4 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -346,7 +346,7 @@ class FormTicket } } - if ($conf->knowledgemanagement->enabled) { + if (!empty($conf->knowledgemanagement->enabled)) { // KM Articles print ''; print ' From b1c4aa07f09fb5cbb2de8c47c1542aada89ef77a Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 28 May 2022 09:58:54 +0200 Subject: [PATCH 066/128] fix php 8 warning --- htdocs/admin/stock.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index e8f59727c07..a5e83155f03 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -394,7 +394,7 @@ print "\n"; print "\n"; // Option to force stock to be enough before adding a line into document -if ($conf->invoice->enabled) { +if (!empty($conf->invoice->enabled)) { print ''; print ''.$langs->trans("StockMustBeEnoughForInvoice").''; print ''; @@ -408,7 +408,7 @@ if ($conf->invoice->enabled) { print "\n"; } -if ($conf->order->enabled) { +if (!empty($conf->order->enabled)) { print ''; print ''.$langs->trans("StockMustBeEnoughForOrder").''; print ''; @@ -422,7 +422,7 @@ if ($conf->order->enabled) { print "\n"; } -if ($conf->expedition->enabled) { +if (!empty($conf->expedition->enabled)) { print ''; print ''.$langs->trans("StockMustBeEnoughForShipment").''; print ''; From eba9f695c20538aa179fb3d376a99c00c92f7cb6 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 28 May 2022 10:02:02 +0200 Subject: [PATCH 067/128] fix php 8 warning --- htdocs/admin/emailcollector_card.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index d01b160ca31..50e3faa7d51 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -1,5 +1,6 @@ + * Copyright (C) 2022 Charlene Benke * * 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 @@ -592,15 +593,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea 'recordjoinpiece'=>'AttachJoinedDocumentsToObject', 'recordevent'=>'RecordEvent'); $arrayoftypesnocondition = $arrayoftypes; - if ($conf->projet->enabled) { + if (!empty($conf->projet->enabled)) { $arrayoftypes['project'] = 'CreateLeadAndThirdParty'; } $arrayoftypesnocondition['project'] = 'CreateLeadAndThirdParty'; - if ($conf->ticket->enabled) { + if (!empty($conf->ticket->enabled)) { $arrayoftypes['ticket'] = 'CreateTicketAndThirdParty'; } $arrayoftypesnocondition['ticket'] = 'CreateTicketAndThirdParty'; - if ($conf->recruitment->enabled) { + if (!empty($conf->recruitment->enabled)) { $arrayoftypes['candidature'] = 'CreateCandidature'; } $arrayoftypesnocondition['candidature'] = 'CreateCandidature'; From a961bb550778467d19bf9edc58f1eee88fa2cec7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 May 2022 11:31:41 +0200 Subject: [PATCH 068/128] Debug v16 --- htdocs/core/tpl/login.tpl.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index ccec4352e89..175fb080818 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2011-2021 Laurent Destailleur + * Copyright (C) 2011-2022 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,7 @@ // Need global variable $urllogo, $title and $titletruedolibarrversion to be defined by caller (like dol_loginfunction in security2.lib.php) // Caller can also set $morelogincontent = array(['options']=>array('js'=>..., 'table'=>...); - +// $titletruedolibarrversion must be defined if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', 1); @@ -71,6 +71,9 @@ $php_self .= dol_escape_htmltag($_SERVER["QUERY_STRING"]) ? '?'.dol_escape_htmlt if (!preg_match('/mainmenu=/', $php_self)) { $php_self .= (preg_match('/\?/', $php_self) ? '&' : '?').'mainmenu=home'; } +if (preg_match('/'.preg_quote('core/modules/oauth', '/').'/', $php_self)) { + $php_self = DOL_URL_ROOT.'/index.php?mainmenu=home'; +} // Javascript code on logon page only to detect user tz, dst_observed, dst_first, dst_second $arrayofjs = array( From dcfb0679c87698f0ed4911e84f31ff5b6970646d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 May 2022 12:24:11 +0200 Subject: [PATCH 069/128] FIX Look and field v16 for list of lot --- .../modulebuilder/template/myobject_list.php | 2 +- htdocs/product/stock/productlot_list.php | 236 ++++++++++++------ 2 files changed, 164 insertions(+), 74 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index c03302551e3..92f7f22f328 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -477,7 +477,7 @@ $arrayofmassactions = array( //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); -if ($permissiontodelete) { +if (!empty($permissiontodelete)) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 565b309b113..13695752ad0 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -76,7 +76,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // 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. + $sortfield = "t.fk_product,t.batch"; // Set here default search field. By default 1st field in definition. } if (!$sortorder) { $sortorder = "ASC"; @@ -89,6 +89,10 @@ foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } } // List of fields to search into when doing a "search in all" @@ -104,12 +108,13 @@ $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, 1, '1'); + $visible = (int) 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, 1, '1')), - 'position'=>$val['position'] + 'enabled'=>(abs($visible) != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' ); } } @@ -147,7 +152,8 @@ if (!$permissiontoread) accessforbidden(); */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -167,6 +173,10 @@ if (empty($reshook)) { 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] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } } $toselect = array(); $search_array_options = array(); @@ -185,7 +195,7 @@ if (empty($reshook)) { /* - * VIEW + * View */ @@ -194,20 +204,19 @@ $form = new Form($db); $now = dol_now(); $help_url = 'EN:Module_Lot_/_Serial|FR:Module_Lot_/_Série'; - $title = $langs->trans('LotSerialList'); +$morejs = array(); +$morecss = array(); // Build and execute select // -------------------------------------------------------------------- $sql = 'SELECT '; -foreach ($object->fields as $key => $val) { - $sql .= "t.".$key.", "; -} +$sql .= $object->getFieldList('t'); // 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.', ' : ''); + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : ''); } } // Add fields from hooks @@ -216,9 +225,13 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $obje $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; -if ( !empty($extrafields->attributes[$object->table_element]['label']) && ($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (isset($extrafields->attributes[$object->table_element]['label']) && 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 { @@ -237,17 +250,17 @@ foreach ($search as $key => $val) { $mode_search = 2; } if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search)); } } else { if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { if (preg_match('/_dtstart$/', $key)) { - $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'"; + $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'"; } if (preg_match('/_dtend$/', $key)) { - $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'"; } } } @@ -265,21 +278,22 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $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); // Note that $action and $object may have been modified by hook - $sql.=$hookmanager->resPrint; - $sql=preg_replace('/,\s*$/','', $sql); - */ +$sql.= " GROUP BY "; +foreach($object->fields as $key => $val) { + $sql .= "t.".$db->escape($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); +*/ // Count total nb of records $nbtotalofrecords = ''; @@ -290,14 +304,23 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { */ /* The slow method does not consume memory on mysql (not tested on pgsql) */ /*$resql = $db->query($sql, 0, 'auto', 1); - while ($db->fetch_object($resql)) { - $nbtotalofrecords++; - }*/ + while ($db->fetch_object($resql)) { + if (empty($nbtotalofrecords)) { + $nbtotalofrecords = 1; // We can't make +1 because init value is '' + } else { + $nbtotalofrecords++; + } + }*/ /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); $resql = $db->query($sqlforcount); - $objforcount = $db->fetch_object($resql); - $nbtotalofrecords = $objforcount->nbtotalofrecords; + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; @@ -332,11 +355,14 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url); +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist'); $arrayofselected = is_array($toselect) ? $toselect : array(); $param = ''; +if (!empty($mode)) { + $param .= '&mode='.urlencode($mode); +} if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } @@ -346,9 +372,11 @@ if ($limit > 0 && $limit != $conf->liste_limit) { foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { foreach ($search[$key] as $skey) { - $param .= '&search_'.$key.'[]='.urlencode($skey); + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } } - } else { + } elseif ($search[$key] != '') { $param .= '&search_'.$key.'='.urlencode($search[$key]); } } @@ -357,6 +385,10 @@ if ($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( @@ -382,8 +414,9 @@ print ''; print ''; print ''; -//print ''; +print ''; print ''; +print ''; $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/product/stock/productlot_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); @@ -397,10 +430,13 @@ $trackid = 'lot'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; if ($search_all) { + $setupstring = ''; foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); + $setupstring .= $key."=".$val.";"; } - print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '; + print ''."\n"; + print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '."\n"; } $moreforfilter = ''; @@ -423,7 +459,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // 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 @@ -433,7 +469,15 @@ print ''; +// Action column +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} foreach ($object->fields as $key => $val) { + $searchkey = empty($search[$key]) ? '' : $search[$key]; $cssforfield = (empty($val['css']) ? '' : $val['css']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; @@ -441,17 +485,28 @@ foreach ($object->fields as $key => $val) { $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') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; } @@ -463,46 +518,61 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; $parameters = array('arrayfields'=>$arrayfields); $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; +/*if (!empty($arrayfields['anotherfield']['checked'])) { + print ''; + }*/ // Action column -print ''; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} print ''."\n"; +$totalarray = array(); +$totalarray['nbfield'] = 0; // Fields title label // -------------------------------------------------------------------- print ''; +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $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') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } + $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label 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"; + $totalarray['nbfield']++; } } // 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); +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray); $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"; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} +$totalarray['nbfield']++; print ''."\n"; // Detect if we need a fetch on each output line $needToFetchEachLine = 0; -if (!empty($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { +if (isset($extrafields->attributes[$object->table_element]['computed']) && 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 @@ -514,9 +584,10 @@ if (!empty($extrafields->attributes[$object->table_element]['computed']) && is_a // Loop on record // -------------------------------------------------------------------- $i = 0; -$totalarray = array(); +$savnbfield = $totalarray['nbfield']; $totalarray['nbfield'] = 0; -while ($i < ($limit ? min($num, $limit) : $num)) { +$imaxinloop = ($limit ? min($num, $limit) : $num); +while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); if (empty($obj)) { break; // Should not happen @@ -526,9 +597,22 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $object->setVarsFromFetchObj($obj); // Show here line of result - print ''; + $j = 0; + print ''; + // Action column + if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + } foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif ($key == 'status') { @@ -541,17 +625,21 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; } - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status'))) { + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; if (!empty($arrayfields['t.'.$key]['checked'])) { - print ''; + print ''; if ($key == 'status') { print $object->getLibStatut(5); } elseif ($key == 'rowid') { - print $object->id; + print $object->showOutputField($val, $key, $object->id, ''); } else { if ($key == 'batch') { print $object->getNomUrl(1); @@ -584,15 +672,17 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column - print ''; } - print ''; if (!$i) { $totalarray['nbfield']++; } @@ -613,14 +703,14 @@ if ($num == 0) { $colspan++; } } - print ''; + 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 +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print '
    '; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + 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, !empty($search[$key])?$search[$key]:0, '', '', 'search_', 'maxwidth150', 1); - } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { - print ''; + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1); + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; } print '
    '; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -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 ''; - 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; + if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + 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 ''; + print '
    '.$langs->trans("NoRecordFound").'
    '.$langs->trans("NoRecordFound").'
    '."\n"; From 59fcd9de13a304e8c56f2ac0f402d9cb3afcf291 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 May 2022 12:36:03 +0200 Subject: [PATCH 070/128] Fix trans --- htdocs/product/popuprop.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index b8118ba4884..cfa2f8fc2f6 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -181,7 +181,7 @@ $arrayofmode = array( 'commande' => 'Orders', 'facture' => 'Facture' ); -$title .= ' '.$form->selectarray('mode', $arrayofmode, $mode, 1); +$title .= ' '.$form->selectarray('mode', $arrayofmode, $mode, 1, 0, 0, '', 1); $title .= ' '; From 7ddf4ef315dafb578aa0763e9915889f99f1b1e1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 May 2022 12:50:25 +0200 Subject: [PATCH 071/128] Fix look and feel v16 --- htdocs/product/class/product.class.php | 4 +-- htdocs/product/popuprop.php | 40 +++++++++++++++----------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 7df8e437272..9358eb9c60d 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4896,14 +4896,14 @@ class Product extends CommonObject } if (!empty($conf->accounting->enabled)) { - if ($this->status) { + if ($this->status && isset($this->accountancy_code_sell)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; $label .= '
    '; $label .= '
    '.$langs->trans('ProductAccountancySellCode').': '.length_accountg($this->accountancy_code_sell); $label .= '
    '.$langs->trans('ProductAccountancySellIntraCode').': '.length_accountg($this->accountancy_code_sell_intra); $label .= '
    '.$langs->trans('ProductAccountancySellExportCode').': '.length_accountg($this->accountancy_code_sell_export); } - if ($this->status_buy) { + if ($this->status_buy && isset($this->accountancy_code_buy)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; if (empty($this->status)) { $label .= '
    '; diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index cfa2f8fc2f6..b921f16d02e 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -68,6 +68,7 @@ restrictedArea($user, 'produit|service', 0, 'product&product', '', ''); */ $form = new Form($db); +$tmpproduct = new Product($db); $helpurl = ''; if ($type == '0') { @@ -124,7 +125,7 @@ $infoprod = array(); // Add lines for object -$sql = "SELECT p.rowid, p.label, p.ref, p.fk_product_type as type, SUM(pd.qty) as c"; +$sql = "SELECT p.rowid, p.label, p.ref, p.fk_product_type as type, p.tobuy, p.tosell, p.tobatch, p.barcode, SUM(pd.qty) as c"; $textforqty = 'Qty'; if ($mode == 'facture') { $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as pd"; @@ -141,7 +142,7 @@ $sql .= " AND p.rowid = pd.fk_product"; if ($type !== '') { $sql .= " AND fk_product_type = ".((int) $type); } -$sql .= " GROUP BY p.rowid, p.label, p.ref, p.fk_product_type"; +$sql .= " GROUP BY p.rowid, p.label, p.ref, p.fk_product_type, p.tobuy, p.tosell, p.tobatch, p.barcode"; $num = 0; $totalnboflines = 0; @@ -163,7 +164,7 @@ if (!empty($mode) && $mode != '-1') { while ($i < $num) { $objp = $db->fetch_object($resql); - $infoprod[$objp->rowid] = array('type'=>$objp->type, 'ref'=>$objp->ref, 'label'=>$objp->label); + $infoprod[$objp->rowid] = array('type'=>$objp->type, 'ref'=>$objp->ref, 'label'=>$objp->label, 'tobuy'=>$objp->tobuy, 'tosell'=>$objp->tobuy, 'tobatch'=>$objp->tobatch, 'barcode'=>$objp->barcode); $infoprod[$objp->rowid]['nbline'] = $objp->c; $i++; @@ -228,23 +229,28 @@ if ($mode && $mode != '-1') { } } + $tmpproduct->ref = $vals['ref']; + $tmpproduct->label = $vals['label']; + $tmpproduct->type = $vals['type']; + $tmpproduct->status = $vals['tosell']; + $tmpproduct->status_buy = $vals['tobuy']; + $tmpproduct->status_batch = $vals['tobatch']; + $tmpproduct->barcode = $vals['barcode']; + print ""; - print ''; - if ($vals['type'] == 1) { - print img_object($langs->trans("ShowService"), "service"); - } else { - print img_object($langs->trans("ShowProduct"), "product"); - } - print " "; - print $vals['ref'].''; print ''; - if ($vals['type'] == 1) { - print $langs->trans("Service"); - } else { - print $langs->trans("Product"); - } + print $tmpproduct->getNomUrl(1); print ''; - print ''.$vals['label'].''; + print ''; + $s = ''; + if ($vals['type'] == 1) { + $s .= img_picto($langs->trans("Service"), 'service', 'class="paddingleftonly paddingrightonly colorgrey"'); + } else { + $s .= img_picto($langs->trans("Product"), 'product', 'class="paddingleftonly paddingrightonly colorgrey"'); + } + print $s; + print ''; + print ''.dol_escape_htmltag($vals['label']).''; print ''.$vals['nbline'].''; print "\n"; $i++; From 2c9c55bc7526466d266549ae9e44f0fe93ff5685 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 May 2022 16:52:39 +0200 Subject: [PATCH 072/128] Fix filter on dates --- htdocs/product/reassortlot.php | 739 ++++++++++++++++++--------------- 1 file changed, 415 insertions(+), 324 deletions(-) diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index c5463e3e4e2..031ef60ff6e 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -33,11 +33,18 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; // Load translation files required by the page $langs->loadLangs(array('products', 'stocks', 'productbatch')); -$action = GETPOST('action', 'aZ09'); +$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) +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'myobjectlist'; // 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') +$mode = GETPOST('mode', 'aZ'); + $sref = GETPOST("sref", 'alpha'); $snom = GETPOST("snom", 'alpha'); $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); @@ -52,25 +59,21 @@ $fourn_id = GETPOST("fourn_id", 'int'); $sbarcode = GETPOST("sbarcode", 'int'); $search_stock_physique = GETPOST('search_stock_physique', 'alpha'); +// 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) { +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { + // If $page is not defined, or '' or -1 or if we click on clear filters $page = 0; } -if (!$sortfield) { - $sortfield = "p.ref"; -} -if (!$sortorder) { - $sortorder = "ASC"; -} -$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; -if (empty($page) || $page == -1) { - $page = 0; -} // If $page is not defined, or '' or -1 $offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; -// Load sale and categ filters +// Initialize array of search criterias +$object = new Product($db); $search_sale = GETPOST("search_sale"); if (GETPOSTISSET('catid')) { $search_categ = GETPOST('catid', 'int'); @@ -78,6 +81,33 @@ if (GETPOSTISSET('catid')) { $search_categ = GETPOST('search_categ', 'int'); } +// 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) { + reset($object->fields); // Reset is required to avoid key() to return null. + $sortfield = "p.".key($object->fields); // Set here default search field. By default 1st field in definition. +} +if (!$sortorder) { + $sortorder = "ASC"; +} + +// Initialize array of search criterias +$search = array(); +foreach ($object->fields as $key => $val) { + if (GETPOST('search_'.$key, 'alpha') !== '') { + $search[$key] = GETPOST('search_'.$key, 'alpha'); + } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } +} + // Get object canvas (By default, this is not defined, so standard usage of dolibarr) $canvas = GETPOST("canvas"); $objcanvas = null; @@ -98,21 +128,62 @@ $result = restrictedArea($user, 'produit|service', 0, 'product&product'); * Actions */ -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 - $sref = ""; - $snom = ""; - $sall = ""; - $tosell = ""; - $tobuy = ""; - $search_sale = ""; - $search_categ = ""; - $toolowstock = ''; - $search_batch = ''; - $search_warehouse = ''; - $fourn_id = ''; - $sbarcode = ''; - $search_stock_physique = ''; +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] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } + } + $sref = ""; + $snom = ""; + $sall = ""; + $tosell = ""; + $tobuy = ""; + $search_sale = ""; + $search_categ = ""; + $toolowstock = ''; + $search_batch = ''; + $search_warehouse = ''; + $fourn_id = ''; + $sbarcode = ''; + $search_stock_physique = ''; + $toselect = array(); + $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 = 'MyObject'; + $objectlabel = 'MyObject'; + $uploaddir = $conf->mymodule->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + */ +} + /* @@ -122,8 +193,12 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $form = new Form($db); $htmlother = new FormOther($db); +$now = dol_now(); + $helpurl = 'EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; $title = $langs->trans("ProductsAndServices"); +$morejs = array(); +$morecss = array(); $sql = 'SELECT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,'; $sql .= ' p.fk_product_type, p.tms as datem,'; @@ -217,318 +292,334 @@ if ($search_stock_physique != '') { if (!empty($sql_having)) { $sql .= $sql_having; } -$sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } -$sql .= $db->plimit($limit + 1, $offset); +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} $resql = $db->query($sql); -if ($resql) { - $num = $db->num_rows($resql); - - $i = 0; - - if ($num == 1 && GETPOST('autojumpifoneonly') && ($sall or $snom or $sref)) { - $objp = $db->fetch_object($resql); - header("Location: card.php?id=$objp->rowid"); - exit; - } - - if (isset($type)) { - if ($type == 1) { - $texte = $langs->trans("Services"); - } else { - $texte = $langs->trans("Products"); - } - } else { - $texte = $langs->trans("ProductsAndServices"); - } - $texte .= ' ('.$langs->trans("StocksByLotSerial").')'; - - $param = ''; - if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); - } - if ($sall) { - $param .= "&sall=".urlencode($sall); - } - if ($tosell) { - $param .= "&tosell=".urlencode($tosell); - } - if ($tobuy) { - $param .= "&tobuy=".urlencode($tobuy); - } - if ($type != '') { - $param .= "&type=".urlencode($type); - } - if ($fourn_id) { - $param .= "&fourn_id=".urlencode($fourn_id); - } - if ($snom) { - $param .= "&snom=".urlencode($snom); - } - if ($sref) { - $param .= "&sref=".urlencode($sref); - } - if ($search_batch) { - $param .= "&search_batch=".urlencode($search_batch); - } - if ($sbarcode) { - $param .= "&sbarcode=".urlencode($sbarcode); - } - if ($search_warehouse) { - $param .= "&search_warehouse=".urlencode($search_warehouse); - } - if ($toolowstock) { - $param .= "&toolowstock=".urlencode($toolowstock); - } - if ($search_sale) { - $param .= "&search_sale=".urlencode($search_sale); - } - if (!empty($search_categ) && $search_categ != '-1') { - $param .= "&search_categ=".urlencode($search_categ); - } - if ($search_stock_physique) { - $param .= '&search_stock_physique=' . urlencode($search_stock_physique); - } - /*if ($eatby) $param.="&eatby=".$eatby; - if ($sellby) $param.="&sellby=".$sellby;*/ - - llxHeader("", $title, $helpurl, $texte); - - print '
    '; - print ''; - print ''; - print ''; - print ''; - - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'product', 0, '', '', $limit, 0, 0, 1); - - - if ($search_categ > 0) { - print "
    "; - $c = new Categorie($db); - $c->fetch($search_categ); - $ways = $c->print_all_ways(' > ', 'product/reassortlot.php'); - print " > ".$ways[0]."
    \n"; - print "

    "; - } - - // Filter on categories - $moreforfilter = ''; - if (!empty($conf->categorie->enabled)) { - $moreforfilter .= '
    '; - $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"'); - $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1); - $moreforfilter .= '
    '; - } - //$moreforfilter.=$langs->trans("StockTooLow").' '; - - if (!empty($moreforfilter)) { - print '
    '; - print $moreforfilter; - $parameters = array(); - $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - print '
    '; - } - - - print '
    '; - print ''; - - // Fields title search - print ''; - print ''; - print ''; - if (!empty($conf->service->enabled) && $type == 1) { - print ''; - } - print ''; - print ''; - if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { - print ''; - } - if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { - print ''; - } - // Physical stock - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - //Line for column titles - print ""; - print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.ref", '', $param, "", $sortfield, $sortorder); - print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "p.label", '', $param, "", $sortfield, $sortorder); - if (!empty($conf->service->enabled) && $type == 1) { - print_liste_field_titre("Duration", $_SERVER["PHP_SELF"], "p.duration", '', $param, "", $sortfield, $sortorder, 'center '); - } - print_liste_field_titre("Warehouse", $_SERVER["PHP_SELF"], "e.ref", '', $param, "", $sortfield, $sortorder); - //print_liste_field_titre("DesiredStock", $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'',$sortfield,$sortorder, 'right ); - print_liste_field_titre("Batch", $_SERVER["PHP_SELF"], "pb.batch", '', $param, "", $sortfield, $sortorder, 'center '); - if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { - print_liste_field_titre("SellByDate", $_SERVER["PHP_SELF"], "pb.sellby", '', $param, "", $sortfield, $sortorder, 'center '); - } - if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { - print_liste_field_titre("EatByDate", $_SERVER["PHP_SELF"], "pb.eatby", '', $param, "", $sortfield, $sortorder, 'center '); - } - print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stock_physique", '', $param, "", $sortfield, $sortorder, 'right '); - // TODO Add info of running suppliers/customers orders - //print_liste_field_titre("TheoreticalStock",$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'',$sortfield,$sortorder, 'right '); - print_liste_field_titre(''); - print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'right '); - print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'right '); - print_liste_field_titre(''); - print "\n"; - - $product_static = new Product($db); - $product_lot_static = new Productlot($db); - $warehousetmp = new Entrepot($db); - - while ($i < min($num, $limit)) { - $objp = $db->fetch_object($resql); - - // Multilangs - if (!empty($conf->global->MAIN_MULTILANGS)) { // si l'option est active - $sql = "SELECT label"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_lang"; - $sql .= " WHERE fk_product = ".((int) $objp->rowid); - $sql .= " AND lang = '".$db->escape($langs->getDefaultLang())."'"; - $sql .= " LIMIT 1"; - - $result = $db->query($sql); - if ($result) { - $objtp = $db->fetch_object($result); - if (!empty($objtp->label)) { - $objp->label = $objtp->label; - } - } - } - - $product_static->ref = $objp->ref; - $product_static->id = $objp->rowid; - $product_static->label = $objp->label; - $product_static->type = $objp->fk_product_type; - $product_static->entity = $objp->entity; - $product_static->status = $objp->tosell; - $product_static->status_buy = $objp->tobuy; - $product_static->status_batch = $objp->tobatch; - - $product_lot_static->batch = $objp->batch; - $product_lot_static->product_id = $objp->rowid; - $product_lot_static->id = $objp->lotid; - $product_lot_static->eatby = $objp->eatby; - $product_lot_static->sellby = $objp->sellby; - - - $warehousetmp->id = $objp->fk_entrepot; - $warehousetmp->ref = $objp->warehouse_ref; - $warehousetmp->label = $objp->warehouse_ref; - $warehousetmp->fk_parent = $objp->warehouse_parent; - - print ''; - - // Ref - print ''; - - // Label - print ''; - - if (!empty($conf->service->enabled) && $type == 1) { - print ''; - } - //print ''; - //print ''; - //print ''; - - // Warehouse - print ''; - - // Lot - print ''; - - if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { - print ''; - } - - if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { - print ''; - } - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print "\n"; - $i++; - } - - print "
    '; - print ''; - print ''; - print ''; - print ''; - print ' '; - print '  '; - print ''; - print '   '; - $searchpicto = $form->showFilterAndCheckAddButtons(0); - print $searchpicto; - print '
    '; - print $product_static->getNomUrl(1, '', 16); - //if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow")); - print ''.$objp->label.''; - if (preg_match('/([0-9]+)y/i', $objp->duration, $regs)) { - print $regs[1].' '.$langs->trans("DurationYear"); - } elseif (preg_match('/([0-9]+)m/i', $objp->duration, $regs)) { - print $regs[1].' '.$langs->trans("DurationMonth"); - } elseif (preg_match('/([0-9]+)d/i', $objp->duration, $regs)) { - print $regs[1].' '.$langs->trans("DurationDay"); - } else { - print $objp->duration; - } - print ''.$objp->stock_theorique.''.$objp->seuil_stock_alerte.''.$objp->desiredstock.''; - if ($objp->fk_entrepot > 0) { - print $warehousetmp->getNomUrl(1); - } - print ''; - if ($product_lot_static->batch) { - print $product_lot_static->getNomUrl(1); - } - print ''.dol_print_date($db->jdate($objp->sellby), 'day').''.dol_print_date($db->jdate($objp->eatby), 'day').''; - //if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' '; - print $objp->stock_physique; - print ''; - print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"'); - print ''.$langs->trans("Movements").''; - print ''.$product_static->LibStatut($objp->statut, 5, 0).''.$product_static->LibStatut($objp->tobuy, 5, 1).'
    "; - print '
    '; - print '
    '; - - $db->free($resql); -} else { +if (!$resql) { dol_print_error($db); + exit; } +$num = $db->num_rows($resql); + +$i = 0; + +if ($num == 1 && GETPOST('autojumpifoneonly') && ($sall or $snom or $sref)) { + $objp = $db->fetch_object($resql); + header("Location: card.php?id=$objp->rowid"); + exit; +} + +if (isset($type)) { + if ($type == 1) { + $texte = $langs->trans("Services"); + } else { + $texte = $langs->trans("Products"); + } +} else { + $texte = $langs->trans("ProductsAndServices"); +} +$texte .= ' ('.$langs->trans("StocksByLotSerial").')'; + +$param = ''; +if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); +} +if ($sall) { + $param .= "&sall=".urlencode($sall); +} +if ($tosell) { + $param .= "&tosell=".urlencode($tosell); +} +if ($tobuy) { + $param .= "&tobuy=".urlencode($tobuy); +} +if ($type != '') { + $param .= "&type=".urlencode($type); +} +if ($fourn_id) { + $param .= "&fourn_id=".urlencode($fourn_id); +} +if ($snom) { + $param .= "&snom=".urlencode($snom); +} +if ($sref) { + $param .= "&sref=".urlencode($sref); +} +if ($search_batch) { + $param .= "&search_batch=".urlencode($search_batch); +} +if ($sbarcode) { + $param .= "&sbarcode=".urlencode($sbarcode); +} +if ($search_warehouse) { + $param .= "&search_warehouse=".urlencode($search_warehouse); +} +if ($toolowstock) { + $param .= "&toolowstock=".urlencode($toolowstock); +} +if ($search_sale) { + $param .= "&search_sale=".urlencode($search_sale); +} +if (!empty($search_categ) && $search_categ != '-1') { + $param .= "&search_categ=".urlencode($search_categ); +} +if ($search_stock_physique) { + $param .= '&search_stock_physique=' . urlencode($search_stock_physique); +} +/*if ($eatby) $param.="&eatby=".$eatby; +if ($sellby) $param.="&sellby=".$sellby;*/ + +llxHeader("", $title, $helpurl, $texte); + +print '
    '; +print ''; +print ''; +print ''; +print ''; + +print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'product', 0, '', '', $limit, 0, 0, 1); + + +if ($search_categ > 0) { + print "
    "; + $c = new Categorie($db); + $c->fetch($search_categ); + $ways = $c->print_all_ways(' > ', 'product/reassortlot.php'); + print " > ".$ways[0]."
    \n"; + print "

    "; +} + +// Filter on categories +$moreforfilter = ''; +if (!empty($conf->categorie->enabled)) { + $moreforfilter .= '
    '; + $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"'); + $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1); + $moreforfilter .= '
    '; +} +//$moreforfilter.=$langs->trans("StockTooLow").' '; + +if (!empty($moreforfilter)) { + print '
    '; + print $moreforfilter; + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
    '; +} + + +print '
    '; +print ''; + +// Fields title search +// -------------------------------------------------------------------- +print ''; +print ''; +print ''; +if (!empty($conf->service->enabled) && $type == 1) { + print ''; +} +print ''; +print ''; +if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; +} +if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; +} +// Physical stock +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +//Line for column titles +print ""; +print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.ref", '', $param, "", $sortfield, $sortorder); +print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "p.label", '', $param, "", $sortfield, $sortorder); +if (!empty($conf->service->enabled) && $type == 1) { + print_liste_field_titre("Duration", $_SERVER["PHP_SELF"], "p.duration", '', $param, "", $sortfield, $sortorder, 'center '); +} +print_liste_field_titre("Warehouse", $_SERVER["PHP_SELF"], "e.ref", '', $param, "", $sortfield, $sortorder); +//print_liste_field_titre("DesiredStock", $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'',$sortfield,$sortorder, 'right ); +print_liste_field_titre("Batch", $_SERVER["PHP_SELF"], "pb.batch", '', $param, "", $sortfield, $sortorder, 'center '); +if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print_liste_field_titre("SellByDate", $_SERVER["PHP_SELF"], "pl.sellby", '', $param, "", $sortfield, $sortorder, 'center '); +} +if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print_liste_field_titre("EatByDate", $_SERVER["PHP_SELF"], "pl.eatby", '', $param, "", $sortfield, $sortorder, 'center '); +} +print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stock_physique", '', $param, "", $sortfield, $sortorder, 'right '); +// TODO Add info of running suppliers/customers orders +//print_liste_field_titre("TheoreticalStock",$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'',$sortfield,$sortorder, 'right '); +print_liste_field_titre(''); +print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'right '); +print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'right '); +print_liste_field_titre(''); +print "\n"; + +$product_static = new Product($db); +$product_lot_static = new Productlot($db); +$warehousetmp = new Entrepot($db); + +// Loop on record +// -------------------------------------------------------------------- +$i = 0; +$savnbfield = $totalarray['nbfield']; +$totalarray['nbfield'] = 0; +$imaxinloop = ($limit ? min($num, $limit) : $num); +while ($i < $imaxinloop) { + $objp = $db->fetch_object($resql); + + // Multilangs + if (!empty($conf->global->MAIN_MULTILANGS)) { // si l'option est active + // TODO Use a cache + $sql = "SELECT label"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_lang"; + $sql .= " WHERE fk_product = ".((int) $objp->rowid); + $sql .= " AND lang = '".$db->escape($langs->getDefaultLang())."'"; + $sql .= " LIMIT 1"; + + $result = $db->query($sql); + if ($result) { + $objtp = $db->fetch_object($result); + if (!empty($objtp->label)) { + $objp->label = $objtp->label; + } + } + } + + $product_static->ref = $objp->ref; + $product_static->id = $objp->rowid; + $product_static->label = $objp->label; + $product_static->type = $objp->fk_product_type; + $product_static->entity = $objp->entity; + $product_static->status = $objp->tosell; + $product_static->status_buy = $objp->tobuy; + $product_static->status_batch = $objp->tobatch; + + $product_lot_static->batch = $objp->batch; + $product_lot_static->product_id = $objp->rowid; + $product_lot_static->id = $objp->lotid; + $product_lot_static->eatby = $objp->eatby; + $product_lot_static->sellby = $objp->sellby; + + + $warehousetmp->id = $objp->fk_entrepot; + $warehousetmp->ref = $objp->warehouse_ref; + $warehousetmp->label = $objp->warehouse_ref; + $warehousetmp->fk_parent = $objp->warehouse_parent; + + print ''; + + // Ref + print ''; + + // Label + print ''; + + if (!empty($conf->service->enabled) && $type == 1) { + print ''; + } + //print ''; + //print ''; + //print ''; + + // Warehouse + print ''; + + // Lot + print ''; + + if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; + } + + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; + } + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print "\n"; + $i++; +} + +$db->free($resql); + +print '
    '; +print ''; +print ''; +print ''; +print ''; + print ' '; + print '  '; +print ''; +print '   '; +$searchpicto = $form->showFilterAndCheckAddButtons(0); +print $searchpicto; +print '
    '; + print $product_static->getNomUrl(1, '', 16); + //if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow")); + print ''.$objp->label.''; + if (preg_match('/([0-9]+)y/i', $objp->duration, $regs)) { + print $regs[1].' '.$langs->trans("DurationYear"); + } elseif (preg_match('/([0-9]+)m/i', $objp->duration, $regs)) { + print $regs[1].' '.$langs->trans("DurationMonth"); + } elseif (preg_match('/([0-9]+)d/i', $objp->duration, $regs)) { + print $regs[1].' '.$langs->trans("DurationDay"); + } else { + print $objp->duration; + } + print ''.$objp->stock_theorique.''.$objp->seuil_stock_alerte.''.$objp->desiredstock.''; + if ($objp->fk_entrepot > 0) { + print $warehousetmp->getNomUrl(1); + } + print ''; + if ($product_lot_static->batch) { + print $product_lot_static->getNomUrl(1); + } + print ''.dol_print_date($db->jdate($objp->sellby), 'day').''.dol_print_date($db->jdate($objp->eatby), 'day').''; + //if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' '; + print $objp->stock_physique; + print ''; + print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"'); + print ''.$langs->trans("Movements").''; + print ''.$product_static->LibStatut($objp->statut, 5, 0).''.$product_static->LibStatut($objp->tobuy, 5, 1).'
    '."\n"; +print '
    '."\n"; + +print '
    '."\n"; + + // End of page llxFooter(); $db->close(); From f6ad688dddbcb9336ec7366d89584f6f3f7d3554 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 May 2022 20:42:29 +0200 Subject: [PATCH 073/128] FIX module for emailing target selection must use a condition on module --- htdocs/comm/mailing/cibles.php | 10 ++++++---- .../core/modules/mailings/advthirdparties.modules.php | 2 ++ htdocs/core/modules/mailings/contacts1.modules.php | 2 ++ htdocs/core/modules/mailings/fraise.modules.php | 2 ++ htdocs/core/modules/mailings/modules_mailings.php | 5 +++++ htdocs/core/modules/mailings/partnership.modules.php | 2 ++ htdocs/core/modules/mailings/thirdparties.modules.php | 2 ++ .../mailings/thirdparties_services_expired.modules.php | 2 ++ .../mailings/mailinglist_mymodule_myobject.modules.php | 3 ++- 9 files changed, 25 insertions(+), 5 deletions(-) diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 9069b63179f..dd8ba5902ce 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -135,7 +135,7 @@ if (GETPOST('exportcsv', 'int')) { $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.statut as status, mc.date_envoi, mc.tms,"; $sql .= " mc.source_id, mc.source_type, mc.error_text"; $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; - $sql .= " WHERE mc.fk_mailing=".((int) $object->id); + $sql .= " WHERE mc.fk_mailing = ".((int) $object->id); $sql .= $db->order($sortfield, $sortorder); $resql = $db->query($sql); @@ -365,17 +365,19 @@ if ($object->fetch($id) >= 0) { $obj = new $classname($db); + // Check if qualified + $qualified = (is_null($obj->enabled) ? 1 : dol_eval($obj->enabled, 1)); + // Check dependencies - $qualified = (isset($obj->enabled) ? $obj->enabled : 1); foreach ($obj->require_module as $key) { - if (!$conf->$key->enabled || (!$user->admin && $obj->require_admin)) { + if (empty($conf->$key->enabled) || (empty($user->admin) && $obj->require_admin)) { $qualified = 0; //print "Les prerequis d'activation du module mailing ne sont pas respectes. Il ne sera pas actif"; break; } } - // Si le module mailing est qualifie + // If module is qualified if ($qualified) { $var = !$var; diff --git a/htdocs/core/modules/mailings/advthirdparties.modules.php b/htdocs/core/modules/mailings/advthirdparties.modules.php index 538e5389727..8c5491918dd 100644 --- a/htdocs/core/modules/mailings/advthirdparties.modules.php +++ b/htdocs/core/modules/mailings/advthirdparties.modules.php @@ -42,6 +42,8 @@ class mailing_advthirdparties extends MailingTargets */ public $db; + public $enabled = '$conf->societe->enabled'; + /** * Constructor diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 69b48fd6e32..04bc4131f69 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -38,6 +38,8 @@ class mailing_contacts1 extends MailingTargets public $require_module = array("societe"); // Module mailing actif si modules require_module actifs public $require_admin = 0; // Module mailing actif pour user admin ou non + public $enabled = '$conf->societe->enabled'; + /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png */ diff --git a/htdocs/core/modules/mailings/fraise.modules.php b/htdocs/core/modules/mailings/fraise.modules.php index aa7c218417b..b5b4f249107 100644 --- a/htdocs/core/modules/mailings/fraise.modules.php +++ b/htdocs/core/modules/mailings/fraise.modules.php @@ -41,6 +41,8 @@ class mailing_fraise extends MailingTargets public $require_module = array('adherent'); + public $enabled = '$conf->adherent->enabled'; + /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png */ diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php index 9df8d44daf1..dae8d1a12bf 100644 --- a/htdocs/core/modules/mailings/modules_mailings.php +++ b/htdocs/core/modules/mailings/modules_mailings.php @@ -36,6 +36,11 @@ class MailingTargets // This can't be abstract as it is used for some method */ public $db; + /** + * @var string Condition to be enabled + */ + public $enabled; + /** * @var string Error code (or message) */ diff --git a/htdocs/core/modules/mailings/partnership.modules.php b/htdocs/core/modules/mailings/partnership.modules.php index b41a5e04c85..bb8e00a179f 100644 --- a/htdocs/core/modules/mailings/partnership.modules.php +++ b/htdocs/core/modules/mailings/partnership.modules.php @@ -41,6 +41,8 @@ class mailing_partnership extends MailingTargets */ public $db; + public $enabled = '$conf->partnership->enabled'; + /** * Constructor diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php index a18103b40f9..afd8a05db02 100644 --- a/htdocs/core/modules/mailings/thirdparties.modules.php +++ b/htdocs/core/modules/mailings/thirdparties.modules.php @@ -31,6 +31,8 @@ class mailing_thirdparties extends MailingTargets public $require_module = array("societe"); // This module allows to select by categories must be also enabled if category module is not activated + public $enabled = '$conf->societe->enabled'; + /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png */ diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php index 09f4cf76ae6..9b417ecd95f 100644 --- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php +++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php @@ -29,6 +29,8 @@ class mailing_thirdparties_services_expired extends MailingTargets public $require_module = array('contrat'); + public $enabled = '$conf->societe->enabled'; + /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png */ diff --git a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php index b50f4acf741..290048785fd 100644 --- a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php @@ -24,7 +24,8 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets // CHANGE THIS: Set to 1 if selector is available for admin users only public $require_admin = 0; - public $enabled = 0; + public $enabled = '$conf->mymodule->enabled'; + public $require_module = array(); /** From 23eb0b3264981b3a7cb581afb7ffea37bce53354 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 May 2022 21:07:52 +0200 Subject: [PATCH 074/128] Clean code --- htdocs/core/class/html.form.class.php | 28 +++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 95ebe740f24..143d11c41f1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -867,17 +867,17 @@ class Form /** * Return combo list of activated countries, into language of user * - * @param string $selected Id or Code or Label of preselected country - * @param string $htmlname Name of html select object - * @param string $htmloption More html options on select object - * @param integer $maxlength Max length for labels (0=no limit) - * @param string $morecss More css class - * @param string $usecodeaskey ''=Use id as key (default), 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key - * @param int $showempty Show empty choice - * @param int $disablefavorites 1=Disable favorites, - * @param int $addspecialentries 1=Add dedicated entries for group of countries (like 'European Economic Community', ...) - * @param array $exclude_country_code Array of country code (iso2) to exclude - * @param int $hideflags Hide flags + * @param string $selected Id or Code or Label of preselected country + * @param string $htmlname Name of html select object + * @param string $htmloption More html options on select object + * @param integer $maxlength Max length for labels (0=no limit) + * @param string $morecss More css class + * @param string $usecodeaskey ''=Use id as key (default), 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key + * @param int|string $showempty Show empty choice + * @param int $disablefavorites 1=Disable favorites, + * @param int $addspecialentries 1=Add dedicated entries for group of countries (like 'European Economic Community', ...) + * @param array $exclude_country_code Array of country code (iso2) to exclude + * @param int $hideflags Hide flags * @return string HTML string with select */ public function select_country($selected = '', $htmlname = 'country_id', $htmloption = '', $maxlength = 0, $morecss = 'minwidth300', $usecodeaskey = '', $showempty = 1, $disablefavorites = 0, $addspecialentries = 0, $exclude_country_code = array(), $hideflags = 0) @@ -926,7 +926,11 @@ class Form } if ($showempty) { - $out .= ''."\n"; + if (is_numeric($showempty)) { + $out .= ''."\n"; + } else { + $out .= ''."\n"; + } } if ($addspecialentries) { // Add dedicated entries for groups of countries From 61b69ca8350223aab3585d7087b7d6ae3bb016e9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 29 May 2022 09:37:03 +0200 Subject: [PATCH 075/128] FIX repeating error "token expired" --- htdocs/core/tpl/login.tpl.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 175fb080818..5965132d68c 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -74,6 +74,9 @@ if (!preg_match('/mainmenu=/', $php_self)) { if (preg_match('/'.preg_quote('core/modules/oauth', '/').'/', $php_self)) { $php_self = DOL_URL_ROOT.'/index.php?mainmenu=home'; } +$php_self = preg_replace('/(\?|&|&)action=[^&]+/', '\1', $php_self); +$php_self = preg_replace('/(\?|&|&)massaction=[^&]+/', '\1', $php_self); +$php_self = preg_replace('/(\?|&|&)token=[^&]+/', '\1', $php_self); // Javascript code on logon page only to detect user tz, dst_observed, dst_first, dst_second $arrayofjs = array( From 480452e2915c58ac76bba83bad36d76b201ef749 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 29 May 2022 09:58:36 +0200 Subject: [PATCH 076/128] FIX missing filters --- htdocs/comm/mailing/cibles.php | 2 +- .../mailings/advthirdparties.modules.php | 7 +- .../modules/mailings/contacts1.modules.php | 4 +- .../core/modules/mailings/example.modules.php | 4 +- .../core/modules/mailings/fraise.modules.php | 7 +- .../modules/mailings/modules_mailings.php | 4 +- .../modules/mailings/partnership.modules.php | 7 +- .../core/modules/mailings/pomme.modules.php | 7 +- .../modules/mailings/thirdparties.modules.php | 7 +- .../thirdparties_services_expired.modules.php | 4 +- .../modules/mailings/xinputfile.modules.php | 4 +- .../modules/mailings/xinputuser.modules.php | 4 +- htdocs/product/reassortlot.php | 121 ++++++++++++++++-- htdocs/product/stock/productlot_list.php | 14 +- 14 files changed, 146 insertions(+), 50 deletions(-) diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index dd8ba5902ce..95639a25997 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -404,7 +404,7 @@ if ($object->fetch($id) >= 0) { } print '
    '; - if ($nbofrecipient >= 0) { + if ($nbofrecipient === '' || $nbofrecipient >= 0) { print $nbofrecipient; } else { print $langs->trans("Error").' '.img_error($obj->error); diff --git a/htdocs/core/modules/mailings/advthirdparties.modules.php b/htdocs/core/modules/mailings/advthirdparties.modules.php index 8c5491918dd..688db8b8e7f 100644 --- a/htdocs/core/modules/mailings/advthirdparties.modules.php +++ b/htdocs/core/modules/mailings/advthirdparties.modules.php @@ -200,8 +200,8 @@ class mailing_advthirdparties extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Not use here - * @return int Nb of recipients + * @param string $sql Not use here + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { @@ -212,8 +212,7 @@ class mailing_advthirdparties extends MailingTargets $sql .= " WHERE s.email != ''"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients + // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients return parent::getNbOfRecipients($sql); } diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 04bc4131f69..e3e349d2a17 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -94,8 +94,8 @@ class mailing_contacts1 extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Requete sql de comptage - * @return int + * @param string $sql Requete sql de comptage + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { diff --git a/htdocs/core/modules/mailings/example.modules.php b/htdocs/core/modules/mailings/example.modules.php index bd553e1fd5d..739ab773196 100644 --- a/htdocs/core/modules/mailings/example.modules.php +++ b/htdocs/core/modules/mailings/example.modules.php @@ -111,8 +111,8 @@ class mailing_example extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Requete sql de comptage - * @return int|string Number of recipient or '?' + * @param string $sql Requete sql de comptage + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { diff --git a/htdocs/core/modules/mailings/fraise.modules.php b/htdocs/core/modules/mailings/fraise.modules.php index b5b4f249107..992539cc303 100644 --- a/htdocs/core/modules/mailings/fraise.modules.php +++ b/htdocs/core/modules/mailings/fraise.modules.php @@ -93,8 +93,8 @@ class mailing_fraise extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Requete sql de comptage - * @return int Nb of recipients + * @param string $sql Requete sql de comptage + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { @@ -102,8 +102,7 @@ class mailing_fraise extends MailingTargets $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a"; $sql .= " WHERE (a.email IS NOT NULL AND a.email != '') AND a.entity IN (".getEntity('member').")"; - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients + // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients return parent::getNbOfRecipients($sql); } diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php index dae8d1a12bf..2064613d1e9 100644 --- a/htdocs/core/modules/mailings/modules_mailings.php +++ b/htdocs/core/modules/mailings/modules_mailings.php @@ -99,8 +99,8 @@ class MailingTargets // This can't be abstract as it is used for some method /** * Retourne nombre de destinataires * - * @param string $sql Sql request to count - * @return int Nb of recipient, or <0 if error + * @param string $sql Sql request to count + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql) { diff --git a/htdocs/core/modules/mailings/partnership.modules.php b/htdocs/core/modules/mailings/partnership.modules.php index bb8e00a179f..7813d93f54d 100644 --- a/htdocs/core/modules/mailings/partnership.modules.php +++ b/htdocs/core/modules/mailings/partnership.modules.php @@ -166,8 +166,8 @@ class mailing_partnership extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Requete sql de comptage - * @return int Nb of recipients + * @param string $sql Requete sql de comptage + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { @@ -187,8 +187,7 @@ class mailing_partnership extends MailingTargets //print $sql; - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients + // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients return parent::getNbOfRecipients($sql); } diff --git a/htdocs/core/modules/mailings/pomme.modules.php b/htdocs/core/modules/mailings/pomme.modules.php index 56d62449bcf..7fdcdeb0c60 100644 --- a/htdocs/core/modules/mailings/pomme.modules.php +++ b/htdocs/core/modules/mailings/pomme.modules.php @@ -89,8 +89,8 @@ class mailing_pomme extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql SQL request to use to count - * @return int Number of recipients + * @param string $sql SQL request to use to count + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { @@ -101,8 +101,7 @@ class mailing_pomme extends MailingTargets $sql .= " WHERE u.email != ''"; // u.email IS NOT NULL est implicite dans ce test $sql .= " AND u.entity IN (0,".$conf->entity.")"; - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients + // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients return parent::getNbOfRecipients($sql); } diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php index afd8a05db02..073d45439eb 100644 --- a/htdocs/core/modules/mailings/thirdparties.modules.php +++ b/htdocs/core/modules/mailings/thirdparties.modules.php @@ -211,8 +211,8 @@ class mailing_thirdparties extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Requete sql de comptage - * @return int Nb of recipients + * @param string $sql Requete sql de comptage + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { @@ -223,8 +223,7 @@ class mailing_thirdparties extends MailingTargets $sql .= " WHERE s.email <> ''"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients + // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients return parent::getNbOfRecipients($sql); } diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php index 9b417ecd95f..b5dec9cbbe0 100644 --- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php +++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php @@ -184,8 +184,8 @@ class mailing_thirdparties_services_expired extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql SQL request to use to count - * @return int Number of recipients + * @param string $sql SQL request to use to count + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { diff --git a/htdocs/core/modules/mailings/xinputfile.modules.php b/htdocs/core/modules/mailings/xinputfile.modules.php index 3ece88d4c1d..77044ddb29e 100644 --- a/htdocs/core/modules/mailings/xinputfile.modules.php +++ b/htdocs/core/modules/mailings/xinputfile.modules.php @@ -77,8 +77,8 @@ class mailing_xinputfile extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Sql request to count - * @return string '' means NA + * @param string $sql Sql request to count + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { diff --git a/htdocs/core/modules/mailings/xinputuser.modules.php b/htdocs/core/modules/mailings/xinputuser.modules.php index b2874b43ca0..117a5722c3c 100644 --- a/htdocs/core/modules/mailings/xinputuser.modules.php +++ b/htdocs/core/modules/mailings/xinputuser.modules.php @@ -77,8 +77,8 @@ class mailing_xinputuser extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Sql request to count - * @return string '' means NA + * @param string $sql Sql request to count + * @return int|string Nb of recipient, or <0 if error, or '' if NA */ public function getNbOfRecipients($sql = '') { diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index 031ef60ff6e..690d3f3f261 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -96,6 +96,7 @@ if (!$sortorder) { $sortorder = "ASC"; } + // Initialize array of search criterias $search = array(); foreach ($object->fields as $key => $val) { @@ -107,6 +108,12 @@ foreach ($object->fields as $key => $val) { $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); } } +$key = 'sellby'; +$search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); +$search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); +$key = 'eatby'; +$search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); +$search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); // Get object canvas (By default, this is not defined, so standard usage of dolibarr) $canvas = GETPOST("canvas"); @@ -155,6 +162,10 @@ if (empty($reshook)) { $search[$key.'_dtend'] = ''; } } + $search['sellby_dtstart'] = ''; + $search['eatby_dtstart'] = ''; + $search['sellby_dtend'] = ''; + $search['eatby_dtend'] = ''; $sref = ""; $snom = ""; $sall = ""; @@ -268,6 +279,37 @@ if ($search_warehouse) { if ($search_batch) { $sql .= natural_search("pb.batch", $search_batch); } + +foreach ($search as $key => $val) { + if (array_key_exists($key, $object->fields)) { + 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) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); + if ($columnName == 'eatby' || $columnName == 'sellby') { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND pl.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND pl.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'"; + } + } + } + } +} + $sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql .= " p.fk_product_type, p.tms,"; $sql .= " p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock, p.stock, p.tosell, p.tobuy, p.tobatch,"; @@ -293,10 +335,13 @@ if (!empty($sql_having)) { $sql .= $sql_having; } +//print $sql; + +// Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $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; @@ -339,9 +384,29 @@ if (isset($type)) { $texte .= ' ('.$langs->trans("StocksByLotSerial").')'; $param = ''; +if (!empty($mode)) { + $param .= '&mode='.urlencode($mode); +} +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) { + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } + } elseif ($search[$key] != '') { + $param .= '&search_'.$key.'='.urlencode($search[$key]); + } +} +if ($optioncss != '') { + $param .= '&optioncss='.urlencode($optioncss); +} if ($sall) { $param .= "&sall=".urlencode($sall); } @@ -389,11 +454,18 @@ if ($sellby) $param.="&sellby=".$sellby;*/ llxHeader("", $title, $helpurl, $texte); -print '
    '; +print ''."\n"; +if ($optioncss != '') { + print ''; +} print ''; +print ''; print ''; print ''; print ''; +print ''; +print ''; +print ''; print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'product', 0, '', '', $limit, 0, 0, 1); @@ -428,7 +500,7 @@ if (!empty($moreforfilter)) { print '
    '; -print ''; +print '
    '; // Fields title search // -------------------------------------------------------------------- @@ -447,10 +519,26 @@ if (!empty($conf->service->enabled) && $type == 1) { print ''; print ''; if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { - print ''; + print ''; } if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { - print ''; + print ''; } // Physical stock print ''; print ''; print ''; print ''; -print ''; -print ''; +// Action column +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} +print ''."\n"; -//Line for column titles -print ""; +$totalarray = array(); +$totalarray['nbfield'] = 0; + +// Fields title label +// -------------------------------------------------------------------- +print ''; print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.ref", '', $param, "", $sortfield, $sortorder); print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "p.label", '', $param, "", $sortfield, $sortorder); if (!empty($conf->service->enabled) && $type == 1) { diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 13695752ad0..2743c4a5ea7 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -55,9 +55,10 @@ $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 == -1) { +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { + // If $page is not defined, or '' or -1 or if we click on clear filters $page = 0; -} // If $page is not defined, or '' or -1 +} $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -342,6 +343,7 @@ if (!$resql) { $num = $db->num_rows($resql); +$i = 0; // Direct jump if only one record found if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { @@ -439,6 +441,7 @@ if ($search_all) { print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '."\n"; } +// Filter on categories $moreforfilter = ''; /*$moreforfilter.='
    '; $moreforfilter.= $langs->trans('MyFilter') . ': '; @@ -455,6 +458,9 @@ if (empty($reshook)) { if (!empty($moreforfilter)) { print '
    '; print $moreforfilter; + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print '
    '; } @@ -462,13 +468,13 @@ $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // 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 '
    '; print '
     '; + $key = 'sellby'; + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + print '
     '; + $key = 'eatby'; + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + print '
    '; @@ -459,14 +547,21 @@ print '   '; -$searchpicto = $form->showFilterAndCheckAddButtons(0); -print $searchpicto; -print '
    '; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
    '."\n"; // Fields title search // -------------------------------------------------------------------- -print ''; +print ''; // Action column if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''."\n"; } else { - $colspan = 8; + $colspan = 10; if (!empty($conf->stock->enabled)) { $colspan++; } From d917ac46e7a01da0c4038753b2ef0635d6564781 Mon Sep 17 00:00:00 2001 From: BB2A Anthony Berton Date: Tue, 31 May 2022 14:14:22 +0200 Subject: [PATCH 097/128] php V8 warning class html form --- htdocs/core/class/html.form.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 143d11c41f1..dd9eabc59f6 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -8631,27 +8631,27 @@ class Form $possiblelinks = array( 'propal'=>array( - 'enabled'=>$conf->propal->enabled, + 'enabled'=>(!empty($conf->propal->enabled) ? $conf->propal->enabled : 0), 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".$this->db->prefix()."societe as s, ".$this->db->prefix()."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('propal').')'), 'order'=>array( - 'enabled'=>$conf->commande->enabled, + 'enabled'=>(!empty($conf->commande->enabled) ? $conf->commande->enabled : 0), 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".$this->db->prefix()."societe as s, ".$this->db->prefix()."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('commande').')'), 'invoice'=>array( - 'enabled'=>$conf->facture->enabled, + 'enabled'=>(!empty($conf->facture->enabled) ? $conf->facture->enabled : 0), 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".$this->db->prefix()."societe as s, ".$this->db->prefix()."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('invoice').')'), 'invoice_template'=>array( - 'enabled'=>$conf->facture->enabled, + 'enabled'=>(!empty($conf->facture->enabled) ? $conf->facture->enabled : 0), 'perms'=>1, 'label'=>'LinkToTemplateInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.titre as ref, t.total_ht FROM ".$this->db->prefix()."societe as s, ".$this->db->prefix()."facture_rec as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('invoice').')'), 'contrat'=>array( - 'enabled'=>$conf->contrat->enabled, + 'enabled'=>(!empty($conf->contrat->enabled) ? $conf->contrat->enabled : 0), 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_customer as ref_client, t.ref_supplier, SUM(td.total_ht) as total_ht From 0b9d4de20d44ff5717e9c38e452fe7dd7415f7df Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 14:20:59 +0200 Subject: [PATCH 098/128] Fix warning --- htdocs/bom/class/bom.class.php | 1 + htdocs/core/class/commonobjectline.class.php | 3 +++ 2 files changed, 4 insertions(+) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index fb7fd68e13a..5d2c0f267de 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1301,6 +1301,7 @@ class BOMLine extends CommonObjectLine */ public $childBom = array(); + /** * Constructor * diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index c45e3f1698c..c1ba05cc279 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -77,6 +77,9 @@ abstract class CommonObjectLine extends CommonObject public $multilangs; public $product_type; // type in line + public $fk_product; // product id in line (when line is linked to a product) + + public $product; // To store full product object after a fetch_product() on a line public $product_ref; // ref in product table public $product_label; // label in product table public $product_desc; // desc in product table From c9eda09964711a9cdc12b5be2c63331196ccbb92 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 14:30:47 +0200 Subject: [PATCH 099/128] FIX ODT generation of BOM document --- htdocs/admin/bom.php | 23 +++++++++--------- htdocs/core/lib/doc.lib.php | 4 +-- .../bom/doc/doc_generic_bom_odt.modules.php | 14 ++++++++++- .../doctemplates/boms/template_bom.odt | Bin 17674 -> 29535 bytes 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/htdocs/admin/bom.php b/htdocs/admin/bom.php index a36c3698306..f8c2cf0bc06 100644 --- a/htdocs/admin/bom.php +++ b/htdocs/admin/bom.php @@ -91,7 +91,7 @@ if ($action == 'updateMask') { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=bom&file=SPECIMEN.pdf"); return; } else { - setEventMessages($module->error, null, 'errors'); + setEventMessages($module->error, $module->errors, 'errors'); dol_syslog($module->error, LOG_ERR); } } else { @@ -174,7 +174,7 @@ $head = bomAdminPrepareHead(); print dol_get_fiche_head($head, 'settings', $langs->trans("BOMs"), -1, 'bom'); /* - * BOMs Numbering model + * Numbering module */ print load_fiche_titre($langs->trans("BOMsNumberingModules"), '', ''); @@ -200,10 +200,11 @@ foreach ($dirmodels as $reldir) { while (($file = readdir($handle)) !== false) { if (substr($file, 0, 8) == 'mod_bom_' && substr($file, dol_strlen($file) - 3, 3) == 'php') { $file = substr($file, 0, dol_strlen($file) - 4); + $classname = $file; require_once $dir.$file.'.php'; - $module = new $file($db); + $module = new $classname($db); // Show modules according to features level if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) { @@ -218,7 +219,7 @@ foreach ($dirmodels as $reldir) { print $module->info(); print ''; - // Show example of numbering model + // Show example of numbering module print '
    '; From 319eac2c4528d6e4d8c00fa4957402a6a7eaed36 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 29 May 2022 10:46:00 +0200 Subject: [PATCH 077/128] Fix trans --- htdocs/langs/en_US/main.lang | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index af9894a7897..05d0ec1e060 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1176,4 +1176,5 @@ CommercialsAffected=Sales representatives affected CommercialAffected=Sales representative affected YourMessage=Votre message YourMessageHasBeenReceived=Your message has been received. We will answer or contact you as soon as possible. -UrlToCheck=Url to check \ No newline at end of file +UrlToCheck=Url to check +Automation=Automation \ No newline at end of file From 6a9c07de9f3bc1832601f102152c603921ce3807 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 29 May 2022 11:15:38 +0200 Subject: [PATCH 078/128] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9250259aa20..c476f14a8cc 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ Other licenses apply for some included dependencies. See [COPYRIGHT](https://git If you have low technical skills and you're looking to install Dolibarr ERP/CRM in just a few clicks, you can use one of the packaged versions: -- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php?title=Dolibarr_for_Windows_(DoliWamp)) -- [DoliDeb for Debian](https://wiki.dolibarr.org/index.php?title=Dolibarr_for_Ubuntu_or_Debian) +- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_(DoliWamp)) +- [DoliDeb for Debian](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian) - DoliRpm for Redhat, Fedora, OpenSuse, Mandriva or Mageia Releases can be downloaded from [official website](https://www.dolibarr.org/). From d63043934496c5a3435129c75426eb0d8d7eff65 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sun, 29 May 2022 19:44:07 +0200 Subject: [PATCH 079/128] Fix API knowledgemanagement --- htdocs/categories/class/categorie.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 6c43e818ecc..28320ecf41a 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -37,6 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php'; /** From b8de54aac02bbe71f2d9fa75e1f8ed83ef97097b Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Mon, 30 May 2022 08:08:28 +0200 Subject: [PATCH 080/128] php V8 warning --- htdocs/accountancy/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index 18277eb6751..99ae0bd845b 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -86,7 +86,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S print ''.$langs->trans("SorryThisModuleIsNotCompatibleWithTheExperimentalFeatureOfSituationInvoices")."\n"; print "
    "; -} elseif ($conf->accounting->enabled) { +} elseif (!empty($conf->accounting->enabled)) { $step = 0; $resultboxes = FormOther::getBoxesArea($user, "27"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb) From 7dc93b35444f94c55b6b9e25876042d36f07ea93 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Mon, 30 May 2022 08:23:35 +0200 Subject: [PATCH 081/128] php v8 warning --- htdocs/compta/stats/index.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index e7ec8c61db7..f7b0bc215e1 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -144,6 +144,8 @@ llxHeader(); $form = new Form($db); +$exportlink=""; +$namelink=""; // Affiche en-tete du rapport if ($modecompta == "CREANCES-DETTES") { $name = $langs->trans("Turnover"); @@ -254,6 +256,11 @@ $sql .= " ORDER BY dm"; $minyearmonth = $maxyearmonth = 0; +$cum = Array(); +$cum_ht = Array(); +$total_ht = Array(); +$total = Array(); + $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); @@ -395,6 +402,12 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) { $case = dol_print_date(dol_mktime(1, 1, 1, $mois_modulo, 1, $annee_decalage), "%Y-%m"); $caseprev = dol_print_date(dol_mktime(1, 1, 1, $mois_modulo, 1, $annee_decalage - 1), "%Y-%m"); + $total_ht[$annee]=0; + $total[$annee]=0; + $cum_ht[$case]=0; + $cum[$case]=0; + + if ($annee >= $year_start) { // We ignore $annee < $year_start, we loop on it to be able to make delta, nothing is output. if ($modecompta == 'CREANCES-DETTES') { // Value turnover of month w/o VAT From 2b76e67d427c16dc4bf7769c603faa2643631a84 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Mon, 30 May 2022 08:31:38 +0200 Subject: [PATCH 082/128] php V8 warning --- htdocs/compta/stats/casoc.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php index 0bef7ff555a..1df7ae4db62 100644 --- a/htdocs/compta/stats/casoc.php +++ b/htdocs/compta/stats/casoc.php @@ -179,6 +179,7 @@ $allparams = array_merge($commonparams, $headerparams, $tableparams); $headerparams = array_merge($commonparams, $headerparams); $tableparams = array_merge($commonparams, $tableparams); +$paramslink=""; foreach ($allparams as $key => $value) { $paramslink .= '&'.$key.'='.$value; } @@ -202,6 +203,9 @@ if ($modecompta == "BOOKKEEPINGCOLLECTED") { $modecompta = "RECETTES-DEPENSES"; } +$exportlink=""; +$namelink=""; + // Show report header if ($modecompta == "CREANCES-DETTES") { $name = $langs->trans("Turnover").', '.$langs->trans("ByThirdParties"); From e8bc813a43ba86d1702680d73aeb638db22a6a2d Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 30 May 2022 06:36:37 +0000 Subject: [PATCH 083/128] Fixing style errors. --- htdocs/compta/stats/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index f7b0bc215e1..8da07e6c860 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -407,7 +407,7 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) { $cum_ht[$case]=0; $cum[$case]=0; - + if ($annee >= $year_start) { // We ignore $annee < $year_start, we loop on it to be able to make delta, nothing is output. if ($modecompta == 'CREANCES-DETTES') { // Value turnover of month w/o VAT From 489aa22e560ff25faa25a2947ddc254dc08595e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 30 May 2022 14:14:18 +0200 Subject: [PATCH 084/128] force refresh css --- htdocs/admin/ihm.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 697f8fa2130..6f7f373b7da 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -75,7 +75,7 @@ if (preg_match('/^(set|del)_([A-Z_]+)$/', $action, $regs)) { } if ($action == 'removebackgroundlogin' && !empty($conf->global->MAIN_LOGIN_BACKGROUND)) { - dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity); require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $logofile = $conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND; @@ -99,6 +99,7 @@ if ($action == 'update') { if ($mode == 'template') { dolibarr_set_const($db, "MAIN_THEME", GETPOST("main_theme", 'aZ09'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity); /*$val=GETPOST('THEME_TOPMENU_DISABLE_IMAGE'); if (! $val) dolibarr_del_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', $conf->entity); @@ -207,7 +208,7 @@ if ($action == 'update') { if ($mode == 'other') { dolibarr_set_const($db, "MAIN_LANG_DEFAULT", GETPOST("MAIN_LANG_DEFAULT", 'aZ09'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT", GETPOST("main_size_liste_limit", 'int'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT", GETPOST("main_size_shortliste_limit", 'int'), 'chaine', 0, '', $conf->entity); From 8b4054f8e91c07fcc49f882d98ce355c3f1908eb Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 30 May 2022 17:22:25 +0200 Subject: [PATCH 085/128] FIX : missing phpcs:enable --- htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 259dcdbdcfa..84e5b0caf41 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -787,6 +787,7 @@ class pdf_eagle extends ModelePdfStockTransfer */ protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0) { + // phpcs:enable global $conf; // Force to disable hidetop and hidebottom @@ -900,6 +901,7 @@ class pdf_eagle extends ModelePdfStockTransfer */ protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs) { + // phpcs:enable global $conf, $langs, $mysoc; $langs->load("orders"); @@ -1164,6 +1166,7 @@ class pdf_eagle extends ModelePdfStockTransfer */ protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0) { + // phpcs:enable global $conf; $showdetails = $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; return pdf_pagefoot($pdf, $outputlangs, 'SHIPPING_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext); From 5f40dee89a2063f1176e99d0e5f08c72b4dd8ad6 Mon Sep 17 00:00:00 2001 From: NextGestion Date: Mon, 30 May 2022 15:26:22 +0000 Subject: [PATCH 086/128] Fix error SQL in "import_insert" function --- htdocs/core/modules/import/import_xlsx.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 7be4ee8894a..b96e6706550 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -920,7 +920,7 @@ class ImportXlsx extends ModeleImports if (empty($keyfield)) { $keyfield = 'rowid'; } - $sqlSelect .= "WHERE ".$keyfield." = ".((int) $lastinsertid); + $sqlSelect .= " WHERE ".$keyfield." = ".((int) $lastinsertid); $resql = $this->db->query($sqlSelect); if ($resql) { From 396d1411e5ab3bf25222731c44d32a56019c1ed1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 May 2022 19:12:33 +0200 Subject: [PATCH 087/128] Fix default order --- htdocs/holiday/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index ed6e421d302..5978b6a31be 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -101,7 +101,7 @@ if (!$sortorder) { $sortorder = "DESC"; } if (!$sortfield) { - $sortfield = "cp.rowid"; + $sortfield = "cp.ref"; } $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); From 0489e51cc01dae365164d6eee4d7dc469eba2f1c Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Tue, 31 May 2022 08:39:48 +0200 Subject: [PATCH 088/128] Avoid AutoPrint in TakePOS history --- htdocs/takepos/invoice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 9f22cc20b40..586cdcfcd56 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -913,7 +913,7 @@ if (empty($reshook)) { $sectionwithinvoicelink .= ' '; } - if ($remaintopay <= 0 && getDolGlobalString('TAKEPOS_AUTO_PRINT_TICKETS')) { + if ($remaintopay <= 0 && getDolGlobalString('TAKEPOS_AUTO_PRINT_TICKETS') && $action != "history") { $sectionwithinvoicelink .= ''; } } From b95440b83f8bfbe50f95958876b69a36b4f983c5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 09:57:49 +0200 Subject: [PATCH 089/128] Fix picto phone --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9c9b457a533..96711456e2a 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7383,7 +7383,7 @@ abstract class CommonObject } elseif ($type == 'url') { $value = dol_print_url($value, '_blank', 32, 1); } elseif ($type == 'phone') { - $value = dol_print_phone($value, '', 0, 0, '', ' ', 1); + $value = dol_print_phone($value, '', 0, 0, '', ' ', 'phone'); } elseif ($type == 'price') { if (!is_null($value) && $value !== '') { $value = price($value, 0, $langs, 0, 0, -1, $conf->currency); From 1655890f848e2cdbed00d2f65a18553213d4cf35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 10:35:36 +0200 Subject: [PATCH 090/128] Debug v16 --- htdocs/admin/modules.php | 2 +- htdocs/core/class/commonobject.class.php | 2 +- .../modulebuilder/template/myobject_list.php | 3 +- .../class/recruitmentcandidature.class.php | 2 +- .../recruitmentcandidature_list.php | 108 +++++++++++++----- .../recruitmentjobposition_list.php | 2 +- htdocs/user/hierarchy.php | 35 +++--- htdocs/user/list.php | 6 +- 8 files changed, 110 insertions(+), 50 deletions(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index dbf4ca53686..0db1b26dc7d 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -528,8 +528,8 @@ if ($mode == 'common' || $mode == 'commonkanban') { $moreforfilter .= ''; //$moreforfilter .= '
    '.$moreinfo.' '.$moreinfo2.'
    '; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 96711456e2a..d5e164c46a0 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7378,7 +7378,7 @@ abstract class CommonObject $checked = ' checked '; } $value = ''; - } elseif ($type == 'mail') { + } elseif ($type == 'mail' || $type == 'email') { $value = dol_print_email($value, 0, 0, 0, 64, 1, 1); } elseif ($type == 'url') { $value = dol_print_url($value, '_blank', 32, 1); diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 92f7f22f328..595dd077b0e 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -500,8 +500,8 @@ print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitleSeparator(); $newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/mymodule/myobject_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); @@ -674,6 +674,7 @@ if (isset($extrafields->attributes[$object->table_element]['computed']) && is_ar // -------------------------------------------------------------------- $i = 0; $savnbfield = $totalarray['nbfield']; +$totalarray = array(); $totalarray['nbfield'] = 0; $imaxinloop = ($limit ? min($num, $limit) : $num); while ($i < $imaxinloop) { diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index 835cfe0b7cd..1b4074a6798 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -120,7 +120,7 @@ class RecruitmentCandidature extends CommonObject 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1,), 'firstname' => array('type'=>'varchar(128)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1,), - 'email' => array('type'=>'varchar(255)', 'label'=>'EMail', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'picto'=>'email'), + 'email' => array('type'=>'email', 'label'=>'EMail', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'picto'=>'email', 'csslist'=>'tdoverflowmax200'), 'phone' => array('type'=>'phone', 'label'=>'Phone', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>1, 'picto'=>'phone'), 'date_birth' => array('type'=>'date', 'label'=>'DateOfBirth', 'enabled'=>'1', 'position'=>70, 'visible'=>-1,), 'email_msgid' => array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'help'=>'EmailMsgIDDesc'), diff --git a/htdocs/recruitment/recruitmentcandidature_list.php b/htdocs/recruitment/recruitmentcandidature_list.php index 4ce262c8c92..9a0a21484b1 100644 --- a/htdocs/recruitment/recruitmentcandidature_list.php +++ b/htdocs/recruitment/recruitmentcandidature_list.php @@ -30,11 +30,11 @@ //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('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip //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) +//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 @@ -129,11 +129,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1, 1, '1'); + $visible = (int) 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, 1, '1')), + 'enabled'=>(abs($visible) != 3 && dol_eval($val['enabled'], 1)), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); @@ -318,7 +318,7 @@ if (! empty($extrafields->attributes[$object->table_element]['label'])) { } // Add where from hooks $parameters=array(); -$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters); // Note that $action and $object may have been modified by hook +$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); */ @@ -326,8 +326,15 @@ $sql = preg_replace('/,\s*$/', '', $sql); // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; @@ -543,7 +550,7 @@ $arrayofmassactions = array( //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); -if ($permissiontodelete) { +if (!empty($permissiontodelete)) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { @@ -560,12 +567,17 @@ print ''; print ''; print ''; -//print ''; +print ''; print ''; print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.((int) $id)), '', $permissiontoadd); + +$newcardbutton = ''; +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitleSeparator(); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.((int) $id)), '', $permissiontoadd); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); @@ -577,10 +589,13 @@ $trackid = 'recruitmentapplication'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; if ($search_all) { + $setupstring = ''; foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); + $setupstring .= $key."=".$val.";"; } - print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '; + print ''."\n"; + print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '."\n"; } $moreforfilter = ''; @@ -603,7 +618,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // 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 @@ -613,8 +628,16 @@ print ''; +// Action column +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + $searchkey = empty($search[$key]) ? '' : $search[$key]; + $cssforfield = (empty($val['css']) ? '' : $val['css']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { @@ -655,10 +678,12 @@ $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 ''; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} print ''."\n"; $totalarray = array(); @@ -667,6 +692,9 @@ $totalarray['nbfield'] = 0; // Fields title label // -------------------------------------------------------------------- print ''; +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} foreach ($object->fields as $key => $val) { $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { @@ -675,21 +703,25 @@ foreach ($object->fields as $key => $val) { $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') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } + $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label 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"; + $totalarray['nbfield']++; } } // 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); +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column -print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} $totalarray['nbfield']++; print ''."\n"; @@ -735,7 +767,19 @@ while ($i < $imaxinloop) { } else { // Show here line of result $j = 0; - print ''; + print ''; + // Action column + if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + } foreach ($object->fields as $key => $val) { $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { @@ -756,7 +800,11 @@ while ($i < $imaxinloop) { //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; if (!empty($arrayfields['t.'.$key]['checked'])) { - print ''; + print ''; if ($key == 'status') { print $object->getLibStatut(5); } elseif ($key == 'rowid') { @@ -789,15 +837,17 @@ while ($i < $imaxinloop) { $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column - print ''; } - print ''; if (!$i) { $totalarray['nbfield']++; } @@ -826,7 +876,7 @@ if ($num == 0) { $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 +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print '
    '; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + print ''; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -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 ''; - 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; + if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + 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 ''; + print '
    '."\n"; diff --git a/htdocs/recruitment/recruitmentjobposition_list.php b/htdocs/recruitment/recruitmentjobposition_list.php index cf4bdddb63d..4f63434f9cf 100644 --- a/htdocs/recruitment/recruitmentjobposition_list.php +++ b/htdocs/recruitment/recruitmentjobposition_list.php @@ -427,8 +427,8 @@ print ''; print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/^&mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/^&mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/^&mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitleSeparator(); $newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/recruitment/recruitmentjobposition_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php index fa68b3e6cdf..92d0490f1c6 100644 --- a/htdocs/user/hierarchy.php +++ b/htdocs/user/hierarchy.php @@ -29,10 +29,6 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php'; -if (!$user->rights->user->user->lire && !$user->admin) { - accessforbidden(); -} - // Load translation files required by page $langs->loadLangs(array('users', 'companies')); @@ -51,7 +47,6 @@ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("pa // Load mode employee $mode = GETPOST("mode", 'alpha'); -$userstatic = new User($db); $search_statut = GETPOST('search_statut', 'int'); if ($search_statut == '' || $search_statut == '0') { @@ -62,9 +57,16 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_statut = ""; } +$userstatic = new User($db); + // Define value to know what current user can do on users $canadduser = (!empty($user->admin) || $user->rights->user->user->creer); +if (!$user->rights->user->user->lire && !$user->admin) { + accessforbidden(); +} + +$childids = $user->getAllChildIds(1); /* @@ -73,19 +75,25 @@ $canadduser = (!empty($user->admin) || $user->rights->user->user->creer); $form = new Form($db); -$title = $langs->trans("Users").' - '.$langs->trans("HierarchicView"); +$help_url = 'EN:Module_Users|FR:Module_Utilisateurs|ES:Módulo_Usuarios|DE:Modul_Benutzer'; +$title = $langs->trans("Users"); $arrayofjs = array( '/includes/jquery/plugins/jquerytreeview/jquery.treeview.js', '/includes/jquery/plugins/jquerytreeview/lib/jquery.cookie.js', ); $arrayofcss = array('/includes/jquery/plugins/jquerytreeview/jquery.treeview.css'); -llxHeader('', $title, '', '', 0, 0, $arrayofjs, $arrayofcss, '', 'bodyforlist'); +llxHeader('', $title, $help_url, '', 0, 0, $arrayofjs, $arrayofcss, '', 'bodyforlist'); // Load hierarchy of users $user_arbo = $userstatic->get_full_tree(0, ($search_statut != '' && $search_statut >= 0) ? "statut = ".$search_statut : ''); + +// Count total nb of records +$nbtotalofrecords = count($user_arbo); + + if (!is_array($user_arbo) && $user_arbo < 0) { setEventMessages($userstatic->error, $userstatic->errors, 'warnings'); } else { @@ -142,12 +150,12 @@ if (!is_array($user_arbo) && $user_arbo < 0) { //var_dump($data); - $param = "search_statut=".urlencode($search_statut); + $param = "&search_statut=".urlencode($search_statut); $newcardbutton = ''; - $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', DOL_URL_ROOT.'/user/list.php?mode=kanban'.(($search_statut != '' && $search_statut >= 0) ? '&search_statut='.$search_statut : '').preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); - $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php?mode=common'.(($search_statut != '' && $search_statut >= 0) ? '&search_statut='.$search_statut : '').preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); - $newcardbutton .= dolGetButtonTitle($langs->trans('HierarchicView'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php?mode=hierarchy'.(($search_statut != '' && $search_statut >= 0) ? '&search_statut='.$search_statut : '').preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', (($mode == 'hierarchy') ? 2 : 1), array('morecss'=>'reposition')); + $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); + $newcardbutton .= dolGetButtonTitle($langs->trans('HierarchicView'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php?mode=hierarchy'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', (($mode == 'hierarchy') ? 2 : 1), array('morecss'=>'reposition')); + $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', DOL_URL_ROOT.'/user/list.php?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitleSeparator(); $newcardbutton .= dolGetButtonTitle($langs->trans('NewUser'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/user/card.php?action=create'.($mode == 'employee' ? '&employee=1' : '').'&leftmenu=', '', $canadduser); @@ -155,18 +163,19 @@ if (!is_array($user_arbo) && $user_arbo < 0) { $num = 0; $limit = 0; - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, '', 'user', 0, $newcardbutton, '', $limit, 0, 0, 1); + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'user', 0, $newcardbutton, '', $limit, 0, 0, 1); print ''."\n"; if ($optioncss != '') { print ''; } print ''; + print ''; print ''; print ''; print ''; - print ''; print ''; + print ''; print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''; diff --git a/htdocs/user/list.php b/htdocs/user/list.php index 0dc3317b1ef..3c97a7f7298 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -562,7 +562,7 @@ if ($search_api_key != '') { if ($search_supervisor > 0) { $param .= "&search_supervisor=".urlencode($search_supervisor); } -if ($search_statut != '' && $search_statut >= 0) { +if ($search_statut != '') { $param .= "&search_statut=".urlencode($search_statut); } if ($optioncss != '') { @@ -613,9 +613,9 @@ if (!empty($socid)) { } $newcardbutton = ''; +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('HierarchicView'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php?mode=hierarchy'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', (($mode == 'hierarchy') ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php?mode=common'.(($search_statut != '' && $search_statut >= 0) ? '&search_statut='.$search_statut : '').preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); -$newcardbutton .= dolGetButtonTitle($langs->trans('HierarchicView'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php?mode=hierarchy'.(($search_statut != '' && $search_statut >= 0) ? '&search_statut='.$search_statut : '').preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', (($mode == 'hierarchy') ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitleSeparator(); $newcardbutton .= dolGetButtonTitle($langs->trans('NewUser'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd); From 2d0958ba7f09f24bfda918a9761b3e7954d19b86 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 11:00:21 +0200 Subject: [PATCH 091/128] Look and feel v16 --- htdocs/admin/bank.php | 18 ++++-------------- htdocs/compta/bank/list.php | 13 +++++++++++-- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php index e1e468b0cec..ef365881feb 100644 --- a/htdocs/admin/bank.php +++ b/htdocs/admin/bank.php @@ -53,8 +53,6 @@ $type = 'bankaccount'; // Order display of bank account if ($action == 'setbankorder') { if (dolibarr_set_const($db, "BANK_SHOW_ORDER_OPTION", GETPOST('value', 'alpha'), 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } @@ -63,15 +61,11 @@ if ($action == 'setbankorder') { // Auto report last num releve on conciliate if ($action == 'setreportlastnumreleve') { if (dolibarr_set_const($db, "BANK_REPORT_LAST_NUM_RELEVE", 1, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } } elseif ($action == 'unsetreportlastnumreleve') { if (dolibarr_set_const($db, "BANK_REPORT_LAST_NUM_RELEVE", 0, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } @@ -80,15 +74,11 @@ if ($action == 'setreportlastnumreleve') { // Colorize movements if ($action == 'setbankcolorizemovement') { if (dolibarr_set_const($db, "BANK_COLORIZE_MOVEMENT", 1, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } } elseif ($action == 'unsetbankcolorizemovement') { if (dolibarr_set_const($db, "BANK_COLORIZE_MOVEMENT", 0, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } @@ -427,13 +417,13 @@ print ""; // Active if ($conf->global->BANK_COLORIZE_MOVEMENT) { print ''; } else { print '"; } @@ -483,13 +473,13 @@ print ''; // Active if ($conf->global->BANK_REPORT_LAST_NUM_RELEVE) { print ''; } else { print '"; } diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php index 90bc79483bf..8e6fb27d5f0 100644 --- a/htdocs/compta/bank/list.php +++ b/htdocs/compta/bank/list.php @@ -616,9 +616,18 @@ foreach ($accounts as $key => $type) { // Transactions to reconcile if (!empty($arrayfields['toreconcile']['checked'])) { - print ''; print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; $oldyear = $year; } diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php index 603627ee91e..3e33ddedf57 100644 --- a/htdocs/commande/stats/index.php +++ b/htdocs/commande/stats/index.php @@ -394,11 +394,11 @@ foreach ($data as $val) { print ''; print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; $oldyear = $year; } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index a945a03b85d..6ab316edb56 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -143,9 +143,9 @@ $usercandelete = (($user->rights->fournisseur->commande->supprimer || $user->rig $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($usercancreate)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->supplier_order_advance->validate))); // Additional area permissions -$usercanapprove = $user->rights->fournisseur->commande->approuver; -$usercanapprovesecond = $user->rights->fournisseur->commande->approve2; -$usercanorder = $user->rights->fournisseur->commande->commander; +$usercanapprove = !empty($user->rights->fournisseur->commande->approuver) ? $user->rights->fournisseur->commande->approuver : 0; +$usercanapprovesecond = !empty($user->rights->fournisseur->commande->approve2) ? $user->rights->fournisseur->commande->approve2 : 0; +$usercanorder = !empty($user->rights->fournisseur->commande->commander) ? $user->rights->fournisseur->commande->commander : 0; if (empty($conf->reception->enabled)) { $usercanreceive = $user->rights->fournisseur->commande->receptionner; } else { @@ -1627,8 +1627,8 @@ if ($action == 'create') { // Object source contacts list $srccontactslist = $objectsrc->liste_contact(-1, 'external', 1); } else { - $cond_reglement_id = $societe->cond_reglement_supplier_id; - $mode_reglement_id = $societe->mode_reglement_supplier_id; + $cond_reglement_id = !empty($societe->cond_reglement_supplier_id) ? $societe->cond_reglement_supplier_id : 0; + $mode_reglement_id = !empty($societe->mode_reglement_supplier_id) ? $societe->mode_reglement_supplier_id : 0; if (!empty($conf->multicurrency->enabled) && !empty($societe->multicurrency_code)) { $currency_code = $societe->multicurrency_code; @@ -1674,7 +1674,7 @@ if ($action == 'create') { print ''; print ''; - if ($societe->id > 0) { + if (!empty($societe->id) && $societe->id > 0) { // Discounts for third party print ''; } diff --git a/htdocs/mrp/tpl/originproductline.tpl.php b/htdocs/mrp/tpl/originproductline.tpl.php index d65f625048b..e641bd142fc 100644 --- a/htdocs/mrp/tpl/originproductline.tpl.php +++ b/htdocs/mrp/tpl/originproductline.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { global $db; -if (!is_object($form)) { +if (!empty($form) && !is_object($form)) { $form = new Form($db); } From d7eebeb9134ff1b3bbb4ccdb5ea680f2b65b18c3 Mon Sep 17 00:00:00 2001 From: BB2A Anthony Berton Date: Tue, 31 May 2022 11:41:38 +0200 Subject: [PATCH 095/128] php V8 warning class commonobject --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d5e164c46a0..eacfa003f70 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7389,7 +7389,7 @@ abstract class CommonObject $value = price($value, 0, $langs, 0, 0, -1, $conf->currency); } } elseif ($type == 'select') { - $value = $param['options'][$value]; + $value = isset($param['options'][$value])?$param['options'][$value]:''; } elseif ($type == 'sellist') { $param_list = array_keys($param['options']); $InfoFieldList = explode(":", $param_list[0]); From a7155676af0bba54276f3d5441f9b96483613c77 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 12:49:03 +0200 Subject: [PATCH 096/128] Debug v16 --- htdocs/product/composition/card.php | 39 ++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index ec96bba20d6..69c872c51a4 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -28,7 +28,7 @@ */ require '../../main.inc.php'; - +require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; @@ -144,9 +144,10 @@ if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->se * View */ +$form = new Form($db); +$formproduct = new FormProduct($db); $product_fourn = new ProductFournisseur($db); $productstatic = new Product($db); -$form = new Form($db); // action recherche des produits par mot-cle et/ou par categorie if ($action == 'search') { @@ -201,8 +202,10 @@ if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) { llxHeader('', $title, $help_url); $head = product_prepare_head($object); + $titre = $langs->trans("CardProduct".$object->type); $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product'); + print dol_get_fiche_head($head, 'subproduct', $titre, -1, $picto); @@ -218,10 +221,11 @@ if ($id > 0 || !empty($ref)) { $shownav = 0; } - dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 0); + dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', ''); if ($object->type != Product::TYPE_SERVICE || !empty($conf->global->STOCK_SUPPORTS_SERVICES) || empty($conf->global->PRODUIT_MULTIPRICES)) { print '
    '; + print '
    '; print '
    '; print '
    '."\n"; - print ''; + print ''; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; print ''."\n"; - print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; + print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; print "'."\n"; - print ''; + print ''; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; print ''."\n"; - print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; + print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; print "'; - $conciliate = $objecttmp->canBeConciliated(); + + $labeltoshow = ''; + if ($conciliate == -2) { + $labeltoshow = $langs->trans("CashAccount"); + } elseif ($conciliate == -3) { + $labeltoshow = $langs->trans("Closed"); + } elseif (empty($objecttmp->rappro)) { + $labeltoshow = $langs->trans("ConciliationDisabled"); + } + + print ''; if ($conciliate == -2) { print ''.$langs->trans("CashAccount").''; } elseif ($conciliate == -3) { From 93a53c4aea7beb9594b98e9cd8301054cbc2a79c Mon Sep 17 00:00:00 2001 From: Milen Karaganski Date: Tue, 31 May 2022 12:20:41 +0300 Subject: [PATCH 092/128] Fix issue #21063 --- .../fourn/class/fournisseur.facture.class.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 0630d2df6a4..948e1c01deb 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2354,14 +2354,6 @@ class FactureFournisseur extends CommonInvoice $info_bits = 0; } - if ($idproduct) { - $product = new Product($this->db); - $result = $product->fetch($idproduct); - $product_type = $product->type; - } else { - $product_type = $type; - } - //Fetch current line from the database and then clone the object and set it in $oldline property $line = new SupplierInvoiceLine($this->db); $line->fetch($id); @@ -2369,6 +2361,15 @@ class FactureFournisseur extends CommonInvoice $staticline = clone $line; + if ($idproduct) { + $product = new Product($this->db); + $result = $product->fetch($idproduct); + $product_type = $product->type; + } else { + $idproduct = $staticline->fk_product; + $product_type = $type; + } + $line->oldline = $staticline; $line->context = $this->context; From e303f27a198c2cdf9a101320d967d96fea3a5b9a Mon Sep 17 00:00:00 2001 From: BB2A Anthony Berton Date: Tue, 31 May 2022 11:36:23 +0200 Subject: [PATCH 093/128] FIX PHP8 --- htdocs/core/lib/files.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index f768833cd39..f9f7398a4b7 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -273,7 +273,7 @@ function dol_dir_list_in_database($path, $filter = "", $excludefilter = null, $s "position" => (int) $obj->position, "acl" => $obj->acl, "share" => $obj->share, - "description" => $obj->description + "description" => isset($obj->description)?$obj->description:'' ); } $i++; From 2d13b47441a7fb9173e73cc871c87b1808b81d4c Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Tue, 31 May 2022 11:36:54 +0200 Subject: [PATCH 094/128] fix php8.0 warnings --- htdocs/comm/propal/stats/index.php | 6 +++--- htdocs/commande/stats/index.php | 6 +++--- htdocs/fourn/commande/card.php | 16 ++++++++-------- htdocs/mrp/tpl/originproductline.tpl.php | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php index 0a182e6dcbe..576285594b4 100644 --- a/htdocs/comm/propal/stats/index.php +++ b/htdocs/comm/propal/stats/index.php @@ -335,11 +335,11 @@ foreach ($data as $val) { print '
    0 ? '&userid='.$userid : '').'">'.$year.''.$val['nb'].''.round($val['nb_diff']).'%'.(isset($val['nb_diff']) ? round($val['nb_diff']): "0").'%'.price(price2num($val['total'], 'MT'), 1).''.round($val['total_diff']).'%'.(isset($val['total_diff']) ? round($val['total_diff']) : "0").'%'.price(price2num($val['avg'], 'MT'), 1).''.round($val['avg_diff']).'%'.(isset($val['avg_diff']) ? round($val['avg_diff']) : "0").'%
    0 ? '&userid='.$userid : '').'">'.$year.''.$val['nb'].''.round($val['nb_diff']).'%'.(isset($val['nb_diff']) ? round($val['nb_diff']): "0").'%'.price(price2num($val['total'], 'MT'), 1).''.round($val['total_diff']).'%'.(isset($val['total_diff']) ? round($val['total_diff']) : "0").'%'.price(price2num($val['avg'], 'MT'), 1).''.round($val['avg_diff']).'%'.(isset($val['avg_diff']) ? round($val['avg_diff']) : "0").'%
    '.$langs->trans('Supplier').''; - if ($societe->id > 0) { + if (!empty($societe->id) && $societe->id > 0) { print $societe->getNomUrl(1, 'supplier'); print ''; } else { @@ -1696,7 +1696,7 @@ if ($action == 'create') { } print '
    '.$langs->trans('Discounts').''; @@ -1752,7 +1752,7 @@ if ($action == 'create') { $langs->load('projects'); print '
    '.$langs->trans('Project').''; print img_picto('', 'project').$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); - print '   id).'">'; + print '   id) ? '&socid='.$societe->id : "")).'">'; print '
    '; @@ -229,23 +233,33 @@ if ($id > 0 || !empty($ref)) { // Type if (!empty($conf->product->enabled) && !empty($conf->service->enabled)) { $typeformat = 'select;0:'.$langs->trans("Product").',1:'.$langs->trans("Service"); - print ''; } + print '
    '; + print '
    '; print (empty($conf->global->PRODUCT_DENY_CHANGE_PRODUCT_TYPE)) ? $form->editfieldkey("Type", 'fk_product_type', $object->type, $object, $usercancreate, $typeformat) : $langs->trans('Type'); print ''; print $form->editfieldval("Type", 'fk_product_type', $object->type, $object, $usercancreate, $typeformat); print '
    '; + + print '
    '; + print '
    '; + + print ''; + // Nature if ($object->type != Product::TYPE_SERVICE) { - print ''; + if (empty($conf->global->PRODUCT_DISABLE_NATURE)) { + print ''; + } } if (empty($conf->global->PRODUIT_MULTIPRICES)) { // Price - print '
    '.$langs->trans("Nature").''; - print $object->getLibFinished(); - print '
    '.$form->textwithpicto($langs->trans("NatureOfProductShort"), $langs->trans("NatureOfProductDesc")).''; + print $object->getLibFinished(); + //print $formproduct->selectProductNature('finished', $object->finished); + print '
    '.$langs->trans("SellingPrice").''; + print '
    '.$langs->trans("SellingPrice").''; if ($object->price_base_type == 'TTC') { print price($object->price_ttc).' '.$langs->trans($object->price_base_type); } else { @@ -265,16 +279,13 @@ if ($id > 0 || !empty($ref)) { print '
    '; print '
    '; + print '
    '; } print dol_get_fiche_end(); - print '
    '; - print '
    '; - print '
    '; - - print '
    '; + print '

    '; $prodsfather = $object->getFather(); // Parent Products $object->get_sousproduits_arbo(); // Load $object->sousprods @@ -552,7 +563,7 @@ if ($id > 0 || !empty($ref)) { print '
    '; $tmp = $module->getExample(); if (preg_match('/^Error/', $tmp)) { @@ -275,13 +276,13 @@ foreach ($dirmodels as $reldir) { } print "
    "; print "
    "; -print "
    \n"; /* * Document templates generators */ +print "
    \n"; print load_fiche_titre($langs->trans("BOMsModelModule"), '', ''); // Load array def with activated templates @@ -305,8 +306,8 @@ if ($resql) { print '
    '; -print "\n"; -print "\n"; +print '
    '; +print ''; print ''; print ''; print '\n"; @@ -362,13 +363,13 @@ foreach ($dirmodels as $reldir) { // Active if (in_array($name, $def)) { print ''; } else { print '"; } @@ -377,7 +378,7 @@ foreach ($dirmodels as $reldir) { if ($conf->global->BOM_ADDON_PDF == $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 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; @@ -419,12 +420,12 @@ foreach ($dirmodels as $reldir) { print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'."\n"; - print ''; + 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 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print "
    '; print '
    '; -print "
    "; /* * Other options */ +print "
    "; print load_fiche_titre($langs->trans("OtherOptions"), '', ''); print '
    '; diff --git a/htdocs/core/lib/doc.lib.php b/htdocs/core/lib/doc.lib.php index 97eaa7d0b9e..d1a7cea5d9a 100644 --- a/htdocs/core/lib/doc.lib.php +++ b/htdocs/core/lib/doc.lib.php @@ -128,11 +128,9 @@ function doc_getlinedesc($line, $outputlangs, $hideref = 0, $hidedesc = 0, $issu } else { $ref_prodserv = $prodser->ref; // Show local ref only } - - $ref_prodserv .= " - "; } - $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice; + $libelleproduitservice = $prefix_prodserv.$ref_prodserv.($libelleproduitservice ? " - " : "").$libelleproduitservice; } } diff --git a/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php b/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php index 463cbc46a24..946d9f32649 100644 --- a/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php +++ b/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php @@ -169,7 +169,7 @@ class doc_generic_bom_odt extends ModelePDFBom $texte .= '
    '; // Show list of found files foreach ($listoffiles as $file) { - $texte .= '- '.$file['name'].' '.img_picto('', 'listlight').'
    '; + $texte .= '- '.$file['name'].' '.img_picto('', 'listlight').'
    '; } $texte .= '
    '; } @@ -406,10 +406,22 @@ class doc_generic_bom_odt extends ModelePDFBom $foundtagforlines = 0; dol_syslog($e->getMessage(), LOG_INFO); } + if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { $linenumber++; + + if ($line->fk_product > 0) { + $line->fetch_product(); + + $line->product_ref = $line->product->ref; + $line->product_desc = $line->product->description; + $line->product_label = $line->product->label; + $line->product_type = $line->product->type; + $line->product_barcode = $line->product->barcode; + } + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook diff --git a/htdocs/install/doctemplates/boms/template_bom.odt b/htdocs/install/doctemplates/boms/template_bom.odt index 701753c3dba164ffa6f6b482e4418efe1993e557..573e97a0a8442cf83392f70460cc263c97943080 100644 GIT binary patch literal 29535 zcmbTd1yCGa*Dead9fCW-AxLnC5Zoa+K?8%k!{8d+A-KB_?iSoFFgU>_ID<2X_pARq z=iXD_{j2`lRo%6_r`O)Ap1tvbh30T~+^IoxREb z?}O;ACE;LiZe`)-{I70YIN4nt9BjXvIJ5uHq|9v{Ok4r~Q>ix<-TwQrNdAL{jt-7) zj{k`MH#+_&ITu$GS2vgcGafQB^1tBy-*CJ&{(<=aM#RL_6krQ@1IWRd-PFz5`5#<8 z?QG#-R27i^nGTqD|6JaV|8L01-hTbRyLEJSuy6*r{67@>_k91Wv;VqK{s&1bI};0l z3;P!5!ceW)=O8HFO|i`DI}4~f9k9~5(KHP@58c&|Guk*IaS@;nf#N%PmP@Mfxnz|S!# zien+J!DQ{q3WHp!*J=WN`G5Zm8+XkI7YG|)e2kr5-uQuDvS+x}Rd=Qzyy=r->3wGE z?KVGnxk;03oW*&ja@-;01wD9Wn}!nqscm$ZwEa9)Xz>_-(0E0uDO3B;Y&YIn&LP0U zzy!nnd$#`*eE(Xb09TWLtRy9Q-F}sdC~O*tPjFHm9QaEqen(#DCvW*YJx`K50S*;r zCI-QlU`LHXzrF2!i`7!FlqkpfUFT+QLc^1brnJhOAmD}|PwE|Yc^i&A;kOIByAOuJ zPtWvR!-anmQ3o>RttqwV8W?q&3PbS=)`F7mctY#!R;3gOh6u13Py!L~CK~SLMj_-x z*AElILr|{*uuO@IZ_?@r(OLYH*tp6ZzZD73DFp+a+_BtGd3mDx42o9_WAqx zm9;p;g&K=IC7gO^1?fJ9%%Lmm{63dO-5ZdJk}^%lYP+uOSd;-hM$ZkScPn*rUm0~K zv-Kz#ZWoI7hAwcn#!ON!^o_Cm?p)Z5_Xj&rCfiRvou9bovK68k8-2T$aK@5ze(F{$ z{&A_ZE3g^w-)%ek>iF?I zo~*WM5s%gcx13B$Zcrf5>Hu50z^HWvl+OE5h=96u(w6&w4itP!tJL_e4H zz9?=;E4osw$1S90pmsvJW+06mlfCxH$NN%Y1p4kDt60dS5!`yS3RU?3&MN*{R4xEl zS1Wr9mwzmy>)WO}wE(tXPf!1!btx%>;sw^vx@`#gFiY*eXj~Y(6Gf$o(Y^lu*)TOx zTOf2_mEPw=Wx;hL|8*2?qml?gPgqmB!y-qHEXSgjAaH6))gE)@1F9hJGdJ8Al`n*(Q+h}xS#aaW_hiS?wl_&&~l-Z|>`A|tb&FLiM$ z>7@UlgS2YU+~6J?%~<%|35+)e_t=I4kiK5b5S$7ci_MV_f!c zg|BCUrJ(iTlSUmhQ3h+eVkX_DiVC%{{H1?J`aZ{?R>{UEz2n^XRej=<3y+3wfwlzD zXs+_dG!X6YoqKuINWQKZWT%0grrrdYN9ByYgkfMz^vD;`_%TZo5sXhh`~2Z-V4;ag z4GaH$O|&HUsyH|!%AwwQ{x8CFjeo$^3k2Q7?*rF{&ZA1%mv9)c8~RGJR$||TxF4Y~ zZqTA_9p8gUMpaOcQ*VM-Fk;*$`K7qE2mLrr4?8kpTgX!U8a95Kr$buBj~p39t}dq- z7v?se@9*_9WPCJd;g8K2c(E!hW7t9tNV2BWr1vQ#`G4o@_7Z8LSL*cSTIJEimno=n z#H9!M#^ng?Z^9g zI=D}iKe@wy*QUD|GoOicZG_*5Y8FH#^Dv}nwqNMi!^*s96AV*+Udz;N?+bMnm%>QW z=xZb-PH)HJ`Fj>Bt~My2|FFo7QV&Jqv8y(ZlZVS{Ne;P)Pw)-OllE0^htw4Vh0G&Gn4IJkFv#veUl;(S&Sq*|}u`P!-?l=1yG z@QN8sryLazBAyF;bx2f$bfwI;Y)q~fk>q2 zBjnfm{;Pe>m3S<7o7%KV`)LXXb{(MLLIicJ_0?=>;|`5*J7qjc_}E{QAN$zdssGo! zVDk_+k)L0eBDX_ExUkm{+#D(0>db=gM5V|*A$5yXF5mfg-&?yGEYwY5Uo%{YL#lpW z8gf&D%dU+SPAYVl%uZ>DW}KtU8qC0~;@f(Mfy20otQN$OI5Np>lH_POlce3rTWu%7 zSG>3S?G}mWXEQxv7k2j#yJ&7T$Pz|K+a*Z`S3Rq;H7jo>qh3#62RT%X_Djosz}fkP zpg`7x)v{_mYBtK?;xrVn+P&)FT#ig?uDF3e@f!gxpH}b$dv2tXY&MoH?FJ^j$g~d;@u2z*219$#YizFUewAl#r^UsMt8Y-)&au zV)d=14UyYbCYS3_+{nz=Hm7UKe>PV{iX2rMBp8?{j(=~i{|=MEC1_rMWMN?bIseII zG%VfhzT2Bv*}Aa1{=3QMXm1grsw{(nN`m_K3Wl7locc-6u-2V3@5piAg`Jzm!deIjx?W%f}okI zsJx7vtdf?(SABH_S#_1KdTNTgTDs!OCNkQV3P!Fv`esTd?)oOyx&Su|EooDIT~{Lo z6C+b=6Mc{GN^a)5mKK&4HmG<+x?IuxG>ibV@0W`vS+ zLKz65928I{S|}qwl%D}A%me-S8OkdM6;^|OVTa1{K);GW4eWyqoI;H41FhXcZG96w zd_tZ55*5BcrFEfNQcxW&sFDd((-Lan1T|KKT4+O^^r1H9P)iS}yD8Mw1?uGr_4bC^ z1*Q1}MtX;(0%P)h6N+sEpukY5Zvr&H!6MAvI>g5_(a$!~&oRI+DA*nv>JE(v^hpV_ zPYd_TkMS-}@C^$I4T(&RijR#*NKcIlO^8j%NQg*FNePL~|B+f6m0h2bU6PPfACupd zQBa;%(wZL|Seo{uI4ik6I}(%=pO>3goflVLkkOnU(^{I=QI}m>T2@lkPzI{41hqC) zm(*9+w}2|!+S)>bp`nq`=wN7cG&Cp`8lDA>PJ%{dLsKH4NlDO@pU|JF(2Oi-dUaoR z{a{Q1^k)e)s~%bq3oT89)@MTtYWqrBM#{TpTRI1dDxjrJ(3Uc2Qwy}d9opFd?dX7Z z_I1?sPFMFWcJz-lkAS;pHmdrdZByILL(s0-Kb^DCzUquYP|iq8$v|hzY*$%tcVB-E z^j9PFR|j;g9Xi_y9qDgh=&N2DX<47`+L~q0cmL`HdUt(%eSLj( z`*?eQd;9SG0J(a&fj&LlyuQA^**_Et{Y4Vo1Op>gA}1-X;koj+%io98!}osL0{98C zJ|wD2WlCp|R`u$YY;W2deo5|=xSV^LZySvtub-zyqk5WS_YiJt{Q+q;C1vcu^u(en zlsQ-&4|emfOKefGE=${KcmY4dk!zJ^;fRPXsxs|v(wTFq?C+=A^Cw>rd57Cd(Vh%R zkC7bNk>83+*Gu<7*M``c63j3=<3id0pY6Y8#4eWNcjW+czd`8tyvLC9*yn;(#O}ZIz>ss_-;x76EpoAt z#Gcyobki~peeG3OVTEmekAi)^xXv-_Z*c)z9Y@E*H_r+u`xqckU_IYZJ|JF{S6x^x}N4=k#6cwA()|ebK|am4|-|hiFdK{k@9i=3Rg@{?BSpi zN~quMadd^|{~&d-`*N|ECW?V|$1v@4ciDh?28kxQS@=c=PbY zEEc%j<9a^#faP;l%w_0`2l|K*;c=gICu_lVud^J*YX>}K#l6nF#;@P{Jnyj;nQ z)lp0J5N&or+j^cM4|l~q&p0UhUeHak2OLijgV_BuR?qcrc<$3Smgw~kgWCG@=)vnB zBq*W^>Q2KRwCQFkcSbqOa8da=l+s`Nv4K6O=e#H9`J#Bb-zdfZ@kGr3wPRZNV$C84 zHcbp!^fto(wHIyk>DP7cV~4^fzdv;E>2If4$`wzR?urnd1OY)hB|Tfm#2#dmytKx4O*DTC3W%kqEa zTs!vCNM!G+3o)$D311R!6@NfoLmzsxh{6HG&zZe;H34WV;~%Gu+P;Pj&ndGksysiV zU7+d5DZ}!01wdGg{I=h(J+m8rwwbk8*y?|XgkLgjSAB?^HU&SW52sMtw%h;#(IlJw zTfJo*Z(a{cI!0~hU(HAS!jkSG+_ID<*PnAI_v!NNLNAr%tdt!*s!NYZ8T8ptus`({ zHtrlI`*t78#6R>zQOAYIWXd3Z{Ja5rZN&G*U)mUrSrUqB-OC0&0it+in(pN{9S{Ee zl9smL2;$wm9R$qFU6?#IH5w~0u(8266c$Y2|DR%JHK<{3k)&C&C-8xX&G?jacz3m7#4yQLhYr=6Q};CzYJkh z7xZQ9DSb>lRCGduqhPfw7gPzbIywwb<$rkePy0@X08NMj4D#q)@(}sHrPoh&PzWGQ zPm=v4-GGBIJ`rN}=1N(8J5(jv4_C-@Z#g{^Z8JX7KgP@0%9!d7g!Fg7^54}5?ZmRU z9r%RbUrUj{l1Ul_lraw8V@w#I{r);i!uX9+&Bl?H^boCpo0k#_&{K}ljL<)&E1c`g0bbW23501>A&{Dh% zi_K6NCcxK>`$9m=wv1=0N#+;9XZSm@{nf!C?BkRn4^Zcer(1h{8^0L3N`~Eu=tdJV z^nSN%!}2b|g+O%`gJjArKqT(IH(dtj_>7Pu=Yfc!F(5VNWpS&9Q#E5t#`}O+V-dU( z8NQ`UX?U#I469MmC&HmoLCMl8bjRdTG2ih~OnV{jZxUzBWeMBT@-mAmM3AftAKTvA z?G#PoefmcF#_rWBSuoA#?gOH=_7kV?!eBBR*)x21C9GA-QxY(_!)}H#LIJnR*%Sox zet$Jqv1xN>lkQahFDf7TD4!WAA!MMUuFs5^dst6KYG8y7g%N1}D0dHb6kW*Rc%zlvr8hqPhtX`$Tg;$l2eBuPR5Z<#_j2gQ8hqJc zi8%SycF)^}S#0P0=iSyfBA=EYaD_u}&WMbNM>^)8rqddgbv?XwLF)W8+97Y6pVjZw zO5=Dj(giH29^g+8os=d*zHYsS@N<14vb?n#8~$D-b5NaIUK!ptQi0Yu(cy`Nh}WIv zd2NW_dJf_`dC&S&YK?D?%CVitO;?JK!a;DK1QvzhMdpUk+2xD*c`Z^H$IMdr3eIcF za;?6v4H8V8>vPWCB=1WmT#tWG&*>_ZiM^(FF~Edh0&Jgh<6PF9y;N-TuhF zgOabkqA;`r2yzUz=n`)vf*S>lKON?!QuO;Pr31xG$J&gZ3h zUQe|>TXmX$L*Qr`>+?``*Wb;?EC$62~q$%-7X>Z~w!8-y0eyTr2=D7)GCMvx zeOjR^5QQsct>YE=DT+MqqEI|2s{cg<&9>Wxyjk6GG>C4={%(>S$cWft&9s(clY2o4 zY3lD^A`|_jYs)kshOfF@yS9jL#TGoD`ju-FvOLRlk}uV2K342#2WwM_isoF+G{aHT zoaM#svNcf%;~Ggbc{FUE`H^+|<>IMs`V9YDvM(BWQ`iM;{df!CB3{d`pkP$^3&z(L z509GleP-BKjIj16cu&uAmvUXyb%f8JI@yQwg4!CY=kYI*lUIxIFn27ISRQPFDKByN z`?0(V1`*F9DEIaz_t7V3&Netr*|>$1GO9~)mDoFLvr*(7f8wF}gegL%DdF?H{teF@ z#jphT^W^1geh9bxHYE`6WZ!UK2yVEE+xPj14)K;2xeW_3SZ#MYQky5#zj61dj%aVr zboXZcb-pGw^1~vGVCl9Opy3uH4Gt`XhCHKhTT&*flcAr4c{rU-3NMl1JS$Hq-6Pj2LZO1Z0zGCD&`GRHoz%ZB4@ z)K7k}d(A#tT*O#J6L6@p`L^*;5m77jXLFRvy1j!8T&)3m)C9dV{zi%AX557&AM^H4esD zv-jeH@&bE(hQ}kj6SjeuO3J{YIlOjLr&+Fd3USVg@bUQ3dT3vd>Yq>qH<8c*5^L6M z2}R%0mEvyTeQ=dE^59~(5z;=~x2ny;=9ti`9>VRaP?9sgZ~P8#VCB-iQ%@)d`r_ys zr#m-EdD)-M7JIC9v)>vT;BKm7yr4&P)js@;YahBb?9*itj)h_;=@XK5Y?FC4igDO( z<^ch}l=Kme_5uGKGe5e*B-FbWAB4f;WVSEt*3w?Ti1lNNb4M-RR@PLj zjs&qJmdoRx75%82%O`H9t#B*_yxaYFk;S$1w)DFt5dnGuSuTMK!7GweL^B zk9M$%dK~*SZT`mXUN%MEj0SpumyxI0%rlnX8>}-5mVA}kb zO=G%Uui1jx!hc7b-f7#USJ^RhvU{V50&~1nG>`x(L_so=>2ROjH1=mQ-#~b2<8DXcOkTTf5 z1+~(!iFv^B zczlYsye8=;84&NC6{-Gi4*^w50t4mq&Pguh#%f4rnwEilCwR8cDZ(v8TE>OOVpb|S zzhSB*tAT@$Q_0K9GxEE==WqeNLdGfnBXbxXZnB6KYl94;@^1jUB_HPWLo@=KSF>-{ z8NQ;jD&UZavzu!;;Zp4#tXc9%lI!(UelN?S;9f9EkZ4Iz(xD#p_GU_cu>F{@;5q}- zZmg7@>=C`Pax1>6Ycw5~o_QSUhtjZ>lGr6KV9C)&vy3u!ASU(FkV~IhYSlumH|%ET zc)SDqDI6R{0=ljeHOGM^r7UlAEI9+S`!1P@!p^UHf_uJs6EW&KgPd~Q(Clv&38i); z6peySX4og7(l6jbt2jO8F}mbyTv$Cc`K4$T*0HY?x9qr!)+prV$@3rcXbZLTsa4c{ z${U%Z0K~`CYtl^pP=Ylf0-ngdNndTPC804*FsF`h@%r!RT2S`o-a{JcW>a=u;MRR{ zVM%RQ73PL)Tp-Cx;YysELqy-`te+Buk+oqdjuV)$moCemEP{iB7ULx|P*|uc#fT+u zKGOBFaA=m8m`}l(b0M4S>)xAyEO7PmGEQ?zn_(KoBKS^5+Cy4lNvSyV7-UhNPMZwI z1W5cP1uRA`$w|x?{`No19fIR(WlSbPWFM%>c7B|_w ziwtphfl1wK>`kqdF35l$m%Z!6s*C+HEjLcS+Pteu=1a(0KxFacAa^z~{dUuPI!UcC ztre^%NN)h5F5r8I?o3-nJ0 z-EPML4hrV%o`AmybFJRy4)e>=f-de24U0iGY4SL7rY}4djhfLU!>o~der@Xjdt>CC z{hDHnb)qJE;EoMwcy@{hd=20MpDb|#4MeT=$XMu(UOB|dtOZ0CB3Dl?Zc;5-O9@Gd zTyOTChUhX-V`3+s%(udmR&(71U9=3-Pfu#AbUs-tLBirs_gHv>%_KpkG&Vz2W2e=l z8=pNr`>b6WXU**4HLSe5@I8u$rCHy9=B+s#&05s2n;_56*!L}3i;b=|KGNfqlUzc! zsAtuTA>v8wvVB{V%sAwCkenu06!=7uC+x&7X$_C%!~BS(Hb@OTj!Y=70mDID?ZJ($ za`HS40ZYlL-|9^;t2kbuB(U>e?~Q93S+Of-ub+kL7T=k z{OQ;Z;Lt@(Shuvko#O1>*=pkR4FTtk5mhMI;N+JjX6Z@IZt7bQ(u6#6gELL?Pj7F( zPQfxKW}7@Ag|?p#TCq2F%|=@o3(vhjCv`-MvXK*wT3c0!39~p#3`XV1nel|~+Ct3| zJ&<4EA`FS$?$J0{_80~FyI*0uIYecp%f>Xmmlo7u&E%n~LU<7^8^yu%(+?*g3&vbh zL&tZ0l=x! zVEb0bWELG~3GNXefW`Pm)fY*6bKnjQQqoiYX*$Cb@{^wQ1 zc2#ST6oBD@H3&S0|p z?F6~^!_2V8*4j@4E8r)mXag%NXv(?gmyM6PCSS zBaSrG{6Kpz#w{*zlEyTICSNJv)(szex;E6IX| zj6lfF?QpIV+0G-wbJ$V-@7BbQ1G9j?Xy`4=J|XMt%uISh^$~Ij?tCUf))!^C{dUnLOj)uD z#+vWs5v+AFMh!7m3^gZz160b(0IHg^6_qn9W%8-tzmGu2KF_*W3>O7l1vv}93ur{u z9)K%T7j>023&BI4)xcpz&^+&z~{xNw?wEN20D9$&dQTJ_BC`Dwn+Q&{9U2N~~H%?}Ln>*#6_ z=U@lpbO?>(p%Fy4vjGvhM7|eYOMt9Klk44!^G}cd%+s{b`;kVC6@mr)vl`;i!PT^7 z(uKkc?PL9FNmb{OIh-j{g~F0%VUwY;^9`=^&rY0tA&qQ>3W=!e<|^DOYI;TsSQR^|K@lV5%b(P{fD^Jjz6ns<6ADW7@-#QZT5N7)!fYfMHU zRYl8+XY5K?|LrRVCn@)JFQg(CEDv?7Ja0*y8fB^0XHi3dfas_^7yes_27b@rUFa+c zk#9MUuJ1`6|Lzl&Uo9q6FE3YF&>FL<$+M5zq`QSG^Y(R#Fk{4@{jgO4e&Nui^yh3a zcS)*u%(d6}A>oItWq~paMv~DSqGBoff>8<{n$KXDs&PYtF++m(ZxORK9oI|&U0RgY21FoiA?};i3qdq zRS79VR^m^Ixxu)<&Em4IGii{cA9M^L-R4pT^Gfd*gg`H)1KBr>Bhp*dZrxZvIS0&| z!vzoC_hj&<+{6{d6v@}|Qr2&AI!0NtPn$;Bwy1av1xaUmumZw3X+q}aZF5sb$wTyx zGUZ)6(1yMnKxi3(#@((|0U75qlJtK|A{sshDjn+sq&dC z-}mO+t-2l?C|Z~I0rMx*L5^DSPj-4Vk>A>7S+zX~tjSu?t)J$`3Dk;7!5nq1M?=H) z^J?nzsu1Bz>Twnukjx?=ZZp1%3crE;GE$L6Rw}O~P*}<)rkPtx05r8{mW89M=WZEB zn3TSYKK79R>TR+@N>lm3m-2?53zfNF=JnKU2`^ z=he}KLP_UdB^Op=%Br{XUS_;VaW!{5uUQq`*V_6|W~fU571EfGL`Vp8`rNU_qw}iw z3-3uVKL^1^pm+Qo;3@b?oPLFwFHogvKv>I{CI=v_a8hRY(Uw$XH>+B=Y#9}zz{4OZ zkk1CRRg1Pt@2Y$tB8@;ptp?ee^%_JL-WWvS>h{*~^~O`N)q!>BVT+aaye2Oct7v5k zs)))bVPXLcRbO}`u0mBmMCo5aa`YdXMmKKg!5>o=((Rtm77p4+y<511KdDOs#2TCO zE1AD9@Y~}rfJ_xOqe(}07E4YRqZLgS*i*XhS*l`qz%Kme)Od8eM@0i_S-;KB8$$~f z@U->EcharrF;_kaxq9<%g-IYLR7hG=z*5p zHF8!G>0R@$u+_wO6PI~%L=6QGr@AO35{z+tRPX!hnk<2{S;qpMmfQ-Gsk5Yo_|@sFMKmou^CEG!WPJjMw%+KA7(cgy1gPKZ1S=GUFgb8=HEJ;++a$)nVe`XqV9tn+#4%O z>6Z$S_6jZVSYg%p#6^c4*t~F;$x>T1_Kk1wjTjv(lNh|bO+0T+&$N}MKu}j8y1i*^ zU<0~VumKGjf#ck@qZAeNSFXP}l!fr=r48uR3Z^SDeua)(%HJ?Xd!#EnCz}fH=lx$7S zZl9Q3H>^w`RSL_@@W_ir9C5Aj?_eS<_Vut*l{Y%;$q4pT%0`WXtPJO}#eDytf^zF#N&MjpAEwba)TcAgp^w$Oe$s|p$70gum(j;f8Sc@wO|Mi%ocp#5ruIj5YxkM?6ab5xYcn`7nT zh$SH3NtSTuXBKCd5g2&I&Hy-QRe9?kmp+lFv?USU^1zkz?P#5(i_ik?R3SGmukELk z9q#k+BJ#|FssITN?o$Ghk4l?^^yv6tWIA>Wo&%x0`}|SutCf57&tyeiG0iiD>fNh1 z+qAU^P2~#?wR}6)APY8eu`{kvmM#~Y$=1b=zeY#$WkXpA89As?Rc)f8G#-RkpY42x z3T<|{-Z99|MCgG7!7dgt*e(OOQKc_$N`ZF}Xo08Jjf}&8R3X&wpT!cDw5;}Y!=$(_ zHNoHgOnb{%vsIiQe*6h6?qrmZQM}amGXfFpeSOEEMl~*+nf#G1J}!WOT1_bSQ|Mzx>+ zy-u1Wa^Sg!OZXcQccrX8Dm*DP6otv!U{TUJ-uPMVL%SppFETzTr|F=0@`*ouAh3!Z ztvc>)oMBJ*O(giCnBc`xLja+J(@*=Vjt(9M}N)So%^l%W8+7oJr8i0f9 z5S@!nU0FNpDt&k@thEN7J@PAYiuH}9;7j{0#uB9x9}WjeiLaosi&dGO8hJvC;=R1I zu1t|^rb-(t<(;D`h;Y1MA_uv;n(@l%gS6y$#%aDNP#o)95a!6W8cJIxa%)+Jp8ubv zbljQ8UuEdk?98b;o@JK28_Dow!l(?aMGtulgLJUdrPKkq6&H1CuF>RCk9(k&4gd0z z(T$H7#ns;^yTC|%RqQ8H^I%&(FNN~fV6~mrCe?AhS?%APK70vvm0mLjvBEWi?)=AA zNIVoC!-G@<5@1rw+)Kfdq;YPsSm`LX68pG zM#}6fDkOlHZ9)t)Ihp0Slc}~TU-ZA0viok;Nu}u8Ztj#$o~dh>#e!^Cy5dP)oDAZX zxTca-)Yq5Gpgd2rp@H88-$TSqaU>0u&Am)m`<5!D)6|_3Dgu1a^>W^MM3Ycki>5^G ztAknyZiLbH5)OLy->3ZOKS=V~Z9eP2TQPGmcQLPRhumqVwW@ zk$+gpznaR9)~h1rmS<1-{pgz~pQiWJLcw=+QMUJ3njl%DQ|p~9+FE+Il5Z{2((snY zsh1Hifl|RqBTcidE(}WPoBB=wPCS@SUM(^*&$X za|h(jh_kk8+z4Y(wsA@lgni+qY;#<|`+}>kf^6nVumV_mUw)HW^nRWCPANLfU~OV+ zrmb*a7zeK8>Ti@@l8B1|#Ff}aTcm-IYV342XVLop zB2H*?&EQX15eTe^3S0sG=Tc~aVaN*K!F)A3&OuekONf(+9bzg^cS3u)DBSxEnzTjS}bWk@)c%0In)<~#-tf0{;o_F*1P zqu%4s{WDI6$Nzy|X3;ZZxzdg+!&Z(4?iNM=HVZ*5B#YXQd)R3yC@v3 zNV&V&fOa;n%lAAbA*R;&h{(myMNbvj&at-UV#@iIu9xnE51t<~`HY_-ZCdPAr4&Nki@7)C6Yq@0H#lw^$0nEc%0I#H1P1Zuzl}ITGu4 z1vNw}PZ&HqgEHG}LTwuJOoGY6*VM=y<9#|g#p=pII06|Zt&)?0AZZgZkt8b11m*@s zFX^o^H#sWtPf~*~#9~{FOuH%B`LsNIWTSZrM#_1AN#lN5l?LLpE^{VLcuR)YC8^om z-lp2i!)gDnvBKlFv3swsO1fNff>;}~GHE-i2k&FUUXm1m=G8d%eH>19cX#To#G#ce zlCl1ij`QZ2kiV@}3Zm28nFNRn1+|ck6Qt={DM55-fqxVLDv?({@UGs8%~G_$etNJ% zWL43qp-;nUzVGzo35f8mG{Bm8viwE|mA@tIzHe@3>gSY3T32nC2IO7p1K1Cxw?~tE zpex#}7G=~BWo+Xxxutp>3s8$cYAA2pzd_MNfO%@biEHmC=VJ>cr#Xlgwy)j-HcN&YjLKx6g^ zp$q@;rc%|Yp)hsBh9_suCJW%dl&x+s6mIs*G-jGerZ!>nEl7^roCVR) zV&o+L6s(f*(0+RR0ZbYM3g-lRebq_pLQU=}*X6DSk%5%GR`X90VsXp!x)o-?&o|QM zDz-ufX+5FZktwv!&nkN{&IHrU9V zDzj$n6$Z12EySgLHmiW6#lL28UqHj(!2?cFV}?#irvMSECd0^JJ}TfhP9T?*)beb4 z7xww6OzI$@`PUoi+Dc3M1$1Dtn1{C>FLEz9CL>ux47t8^c@30Ylo4o?-bKd45wPW6%!4ABVuScVuHzjRzBYO=R zbDm?A<NOza1Xf5Odf}11SPl+QD z-%4w{Zs1Y1owp*$6bc4BDphjV1Nim5NGkmCm2(#{pPXXblG*gxqFbT4KDCs`XK?1S zGKBweBsNuq`}0nGN1pbi)ORHaFDGzL+PwCY*;w>c$7BKjIifQjfbT7fzMOC(9Xn;! zIrxdWU@>h$bzMf>vSD%lM+>aLG?Z;i)t4MDkuEYt!}VqZ@uwW<19X*m*b3C8qZBlA zUl)R}0^Sf{(i=Zr1WdyL*guhtd;QFlr2*qgO{L|pBkCZ~T~lxfjeALEfmfgHFZ8%- z`fHjTFzl~wa;wES>{iX!#u{Nfc_X=i{2R!igHhmEts2DIHF6ycB8=uxh5V{&`PEO7 z0#H{}O%iD*TR_yc1QCYVJa`tF=K;;El1`<#!QU`HfK7#GkY?egq<9(O-_{KJ(U&Ts zILmYq3AL)Tt@ezG=2dEGJ;U)+^5~;zFJE_O$rdTdh%Hv2*)*AT3*9k@p=R7rm3krG zZLIJ_6tG~XqGCUKns2V}5%s;((k@@d-QB#_pV>rEYetjz@wEEpGnfXhdrb>GjxpWw zbS;5a!vn6wn&G!^uzq7B47*an-;%oCd_eY5h5eL+h8rOzPx&v*v@TW7s?m*xQ6Ji$ zX2@8{BAzF2&VxQu7GlW=q>~RV_=4uNzXB5zPY?9N4!=uOh43eXcN!?L61%KuftRwW zB^ZXD(ZV0ix;SapQj<=*+`;NgfZ8(2!dqC9Rh}Jt24H@SC@|BkHUxk*%o>-mvcj4I zWJTa<;AQtq*${W*!3EO-qf7rq7BCl%QY zN~k`jp3DtPRiIA-^KM{Mu?nVm^@&ATvem(~>BYn-6m;+^ZFzAE{5esEZAv9f9US2K z4`AFk`fDPGDZ-51bjggJL>FP}h6TT+BN|PsaLwY5)J`-A59O(>UhLh1hCISda>C6d z^^pXzsF;)a@+Y?-)t~f?zUd|l{kY9vc`~RzN^bFUQ<(nd7uU55Ciw2Gm7%jH4$^iQ zTC8@rnjT_JC|YYs1=~o{5LE(`%tipn9h0C}$AW_!ra2a31|R$ecuBUPqFUiP$*HAc zhd#Fz6~o3vbp{OBmV{3EpzuaCfD7#>8*T$S!ZpNtr0ltE5C#S7DsI45~YFbix|=3>GT*0)`XbT1G}X`SCq|TbNAcIy!G|bmkEc^<{5{lU#*`_VZdH zs7n4iA5S!#K+^?xlppidg{Zw%I+CS9!wqg=G`jrLhz|)R zns0G4@6Tl2zWr$sKK6Ivl@J}(2WoMS3J^{!^UftALIx8%5+8c~km`FpY0lAxrQ<~M zIFgvGn8w)$3a~0|-f6KbqFP!LmIL>W@~`M3N%S8vyp%f1eHA=DinHQ-XcKcr3O^7R ziQI7>C?w2(Wb&7Au@nEXB+#Hf4YC>0lhCHNA1r%YYiBJC?TzMZjaGk0T?MaLjvLZe zW7sTkt>$Qn5$8fsxA0?Siras?2#Pa%^ms1UCNewi^JjE^vf#*rZ9BRU{abdRUu4bA zB>A9s?yeum0&JC9h(1X%L3odXf}SYiFyg{n{?%Al5hPb~QxzX0o>X~W|Gz3b%jh_g zWNpi`WHB={gT*Y1nVFfHnb~5CnOPPya|f@9G z;AkhSZ1-}_5B!ohIJ4r}>I?+0U<9;78b zjW8pXc7Xod>EDzgzxViEBqEhN|FB2B)fDN_Av>D|k!a=93N5sM#N9L&hG6MD7^v|A zD^G9;vK@M1t+YLm<%!sJG)DCNP*s^;v)@>i72oVt)A6UV zE0^5U`Jju5_1ey513r7S%*QOJZYT4*@uu(3u3O`P^LB!!7tzu)HK8;3*V8kPHOKv_ zb@9m5gCqW|R;NjBi9sBmn`g9|^V4&$wuiMrM42r+sLghKe2-=INA4D#1UH$u2iwth zOzm<#1j|7bL!NU4Sh>kj^MJL=PUA_+xa6SOEcJG-=8H&0JCQ;evjPqv2Odf~&L21q$mCO;74yW%%gP`iL?2B& zXL%%3c}bp45DPm>-;#7w8oD4)8A;Z9I=Id%w8}GU^pI>R8lQi$2Bxd)67D^DCr!=Gag80FIOWydm?i z8k0Z*ijkT|nxe=R`ho~wQx_NSOAdb?k>CgF1-PEdhEmdpChgR+r zOcVUiQ5_FxHgc-f^)pRLB4tqu-Gb5{NA-oa>wpS3FZWHO<n~1d?qdDD|>}y^(~*`G8NvbEw5(HhsBfo=XzBQ0e%! z$RWieal>owC`2K{-byq@IholySbe2$e+*{S0+VxVJ;y!bLX>6W>7V3->yk+hVw}Xr z%i@yjZ4-n~p&|%nXOPp`;>X~Yr;ABKy23GrJkvWnTnikz^0aD)3lp^8@;{FmQs*>K z2~B|46NWdrc&nBcm&=zY1+ea4WP)w^o0)TJDBl z1`u)k0B5{Bw&ud*2EcI@j`D0THM{YzvuMf*DOk4kn9_Xh9Jc7saQkL+XO+VHwhVq} z1(Glq1QqEf=wZwwB~eG8&hGhKJ|vG!*}ig6#rF=~_rCB*?(c+RR0O>R-#57SYmQTS z){c^R*L#Mu!k|xsDD~EU^#60pRRq`%Z12HHhm&dtF7R3UE-ra;^fR zqRc9cL%@`LqaH$y&m4wQm4tOGLeO1?ip1U00S$LoyEDk@%WL(7SVv${; zcg1ru`I_=!dCt;)X;JRB>|m+Km|?;rA=)dpfnEv{79_Fde(*o8~XT;H3>_@E2+LKJ$eR)-UG3q%NCYn(2LV5wRz&POx!;GOsGzb zv!!>aIz*OO%XN??$iE#WcM zb%wYOJvlfQtxr+Mo%;@I50qAW!6evZoXd@=LR})secT*56T=WDZe#Ff0Gg&ZGz=`X z`|vN<8Henwr2OKT9>jY0OvFJlFw;tv)*pb1u$mWxaAt5laKr9&s0 zM8uRbkg9~hY)&`AF;`J*Mr9k8l&iFyQd8ElB&p7(mnY77Qu@42nCMNYC$DN_^$L3R z*Usam&%X;=e!V7vdF@OoV4&EYs;C3r5{IZp_z$gMslz{Iga5txz{a0-;u1C12?3(z zGn^L>wn2zpHMiR3LaV51J;1L=aJZfg-pzT=9Xc%ZDSiw`to@8SD2%vWx}f`dU--=0 z>};Q2NiS%FFu3`K)pQfxEj`ACf&sV?{7^~Jqcw8NbJOZI=ofwbkm=d--hchFi}Nmf z{qk9K!|k<4$Nh5l^(hE=(VTsEvRLiHcc=BFb^NMSrC(PK<&taR>2?>h3*_Uti6L3R zYj|Eoc0bzg=DI&^ZaX8QeO*<#o2$Kjy6tN29Q8rC|0=y*bzCjmQ8E)d(nUUN?W=bvpB&)wg`&xwz`UtM`Sta%K$=Ps zS6%pdr4R6j!Q5ag(-Q=D6h$~b z$qJ{p!_oTi^JPYiD2~dF;>V1lMQuBfx!;7r4oV%NU7(T^m}v*?SFvn!d8)hU1Lk`a z8Ttbskh*^R8R7Kii#>aNd#=`9<}>A!$EfjyCAY`oIxJs)`vJG(gDoHB3gagqYrEZv zk(&?$r{hy(qG{s>hi}jJpu;vWr?p#o>IFY1(w@(6jaL>%ze|Yi1=n5A%jrIUUh`}&^r_XCZ9Tg_xeP3A&h0z$B_0AE5S*+L z9Q_`QpKpc#9wYYQT*035*}hGMsmGGkXyhylypeZ<2#QjMMh4jV$r%Tz&9m_CjELED z61Qn_GhfH~xE95JFF7P8={Zb}R-MVMe;nH~x^eJS>75$J6Wl32@TAn4-i4kOq^7QW z-hOxojF1QR6yEcDiz5U)cZOwjP4Es*=@0zL4zO5OQFQ^Uj)L6pF8ALyK`-;%D8&1vp(?-FFW z1uU(`{UCbnkEBC0;j7VFy!%wuqUJBwc67+SzuGw1cN!jJY8N~r(G9VPe-jL)8gkLrmx(U>;rR5PLRugtmzY~qlkr;;W zh^Kq3cfH;_J}5~-Ifk|#O*yRZp&?X}u*OlDgi2juRN)J?RT|PK0+fQR1KRY<^zSf| zh3Gpemxz*$>g7GpEy$5Ka)Ift-s-#gJF<32=Yp!Ad&)6sFZrcw(O6`hpmbp+6>3TQ zEYaqU?Gbdnw%%1t)JwQCfmn)s!C1uB3XhDV)=D-gf{;G%%k8VDr@-My^=Uqrg7Y0x zAnX(BQzN9G1-nD<`7TdRz5lk1`$82xd@wTk(e{-buYlc!GUN_8F+{NdUO3OU;dM>N zNpuF#?R;-*koz$*!xq9I4yHQNq9)L^8puUQ>WwE^FA{ZYsz756L{vDDN-vPjTknye zvb%W~6L4L^1eR>%uRoeF?T9>Z@1RT)t5z3=ys7bPKtkQx7n^1>9IcYo4%ZA5S-9~W z5K9H{jm*YLc0MU%t}$Tot^@&}|LznCGrAXX7(uW5Olf#}T*ZNP2maXj{F(Wev_WlYB>#acs@(HOy1CoHCjujeFb9c#-jCJ+V#ye`#iE~Zh}v> zs_j>EQKr3^_6VQtjF`?$+vB3+zg0~L-*F5+ro)nU+gd@(FlVR#P{pma$9mEe#pGy`vkE*4Q0Ip~wNoT5c~KCmBT zA5!*f8O0C?S)7bQQaS;>fNAH}5j^5&Jp&*`pkT_SfE+3BrwP5*IAD7Zk)0oh&^kKEINxHCR zHONP%0_kL!snNo{)U2q<#@&r2bryKd7k3bKSfrSB8$^V`&0*};TDkn~CiG&D8Clw0 z=0Z;^J5#VMZ6YnfPzLL6L*qJ+$efk5)|tM#z^&AAIAuwhI3{qPD$g=~MLupj1}d1! z6+b2yI93njjafwR+#4r<+K<&Oq12a_gyi&rYnXZ&nyJ1$}=A%ynHq?$*m$t9&s7cj>9y!_MD$rgMRKSnR&xRbVgi){<^u(GpEjpu5&(ZL|BAX#I?-xwi6izi

    O@2W=SRsq1!{3wH-Y}ptfn1sI=U;tW-zR9S%hE_$6)=+4m%@Rm zHPpOsjuUzDz8xRP=j?czR!^EK6TT8%eGUyNXi}Ez%|DjG?xR;4R20CFQZJXwd0NW% z_*vL0zJ$ywI0_c%LEzjslUStXg!+?OKvg<-w2f(&HQ9fwdAhk@!K#j8XHDYvNbL${Z_?7HP}ufMAA_?99bnPQeh{zL^NC( z)-pdF$viIpCvk4+opolst2cNZxtCRn2-*H>p^-y!TAOU__;mw*`>f{IvEQ>2VB?9HkC1blz~LU$kWsfN zuh$%h1qBFNw*(63A4Fg+PzW#y=|~ z7j$90*I4_)djm|N_+e=k*#cK<#G6q^?1-E&SQqwtd}bNUMK@6~b@n3|>nId0c?b>S z@ACCu!JB_5+5f-I-=*$qWwxOSToBFAGYfkA-D#ryeS*pZ5Z@<`UvAINN{ zEr#jnV?5Hj27tTUb@QFhOraEuyrrNV7%qlLGDS#b>rS@sE=veHckUkD{M@D3GD!Qr zrV8)in~l*dQUL&Onk#@LG89qlHlESFB^Mdzgz-`E!y7w zu4&-y%y%W(OUzGoWxK_kM_7-xk`A(zGb;|tjC*7<;99sc4iT-V0G3p+x#1~z1r4l`7WKwjm%NEu~qrb1WvhSP9_3$RPbC=!-eV6W>xcsv2e z+Q7ZX`Uq;O5NohE16icNsu6R)ap1U{Tq;yu`d$XJINc`}3!6IfGCe=WBHpL=UiJL^ zoB>UFyp2dG1UGVa84)7*xr@*4zU#@NRKM{G8=g5bjC+jM)*VI@0YZTxqqE+zd(gSY zdO&^wfvukc{<+UGFOXtBTeew+cIgY#dkMtuS@XM8qjY;@Ns(q1qu?0UY#8mp5$%dj zJW#)H9xSiPgASILBAA|RAuV8RKeLg&-3z=5e*{`kQ!t8}bHD<*l_86JHa98oF}||K zZ74sgv2uTv7wquaB*UuEim#4ZD?aBnmdDuah<3-FA|=3u zBXc8hJYHOjNRGnI z7P3r$`8eT9xj93J6R^AmJBC2i&Os_NwK0r>9*~uTc(wDwb%OEy{sry11lLDc!$4sp zmXZRH1B(xwte!5@clV2yJwt({?*oVth>K==Hr{>MZ=zrj>!eu%VDDj4 zj$Zh>G>e9*+`b}lL^a?Z^iBDs`g&M$oKEDPK724;?fG~I(VNi(%KUqYDuZN~{$gn% z7}GV5-V;0iMIl%(rwq-vej!vFw(Y6V3V4P@F-P((4N;z#`a{KId1-ijb1nT{Jc6MY zWAu~C0j0=c{pRCdTNp2q7~;hyPj114>R<|l32b_=w4A%be0rLJi@X9?bvh$zk`jhk zp+48_6**>2?Cd0xh~QS7L3GlI)4X^jde9ZRaK^X_%5k?OCm6bURFcJ1P(g_SmXI^A zR!bgH-Wa9BT9^Kkc-lc8w+o{bPK?hwlyvqx@HH~;nu$DmvnDEC0Tb73rtftpU9nnY z3AJ(GTfbj_t;$O?^63>1)F#ynzzya^v7!3bM7AV|k}QpMY>pWcz~^@idnE8vG>xWX zu0uO?Hz_``HHkr{e~wE?l3RN0OW~3om>_rP*nG_FmYC)J)wyDgQvitZ23Kle=aRsMEx>GvVqGA z%+%x;QhB^QE>?;N%tpP2piqd2zXpq&htB#=Dk6-dV|(5%QMH<@LMlS+#yC2nleG$@ zf-oT&lPedscD#l|KdE8?o~CYUgyMI$x?1vIaam4h7?k3zX@=`t zvP3dQ#cUO}@H*qbvqr`DYmM;RF$y<~o5Rnvncd|a!hW8&yKj7}oiZUXXAqWS%CzG2 zaIn6Gz;cVIbm?n_>H}2N9iFl5;i(f$H}F2u>~LSVvn_ba)Y(Ae@yF5<$xv!gpZE!t zatVjv#30p*Ae&&L3Qov6R&CN7KMp0`<1^0P6H{z)-0hjEmTho{yPsngtk>)}~3Aec|ss(tMjkIgmmW#()u$xE? zxQ+p`>}g^3G&ANd$VlLY(x_kLJ^4%e@Q|VaCzMP_sSc0WPTWvqN86@*r7ImA`{F9v zdwPWX*;Rqn#S4-+xY3ubDv#8Tp9=f{ZoRPOT@#$jxThMkVK4U@WgG@6Hhfw~SDB6I zC-M_B`!Y;t^<~NrmMzLIIWJe1T%V7bcy8GY9Im?0QV+il)XJ{kNW5tEdG8hg&LP?>W$<-Wr_k6CCvl5HHvvX-@s*s)kNCmW-@B&+*w_>{4Dy&l|oa%nbHSt3PlHwV#A7FCpHVe zz4lSq$bE{O=cVM7UF9E;JWk%i&tzn;U>0oNc!fier z_J6g5eID8Rq>NRr&~+s(S+G$K#rk1h;{BY-Q2=GIEo$FFh#yO_bIsKLdOJY>qvthJ&h<*%XYZ3^mLY^bNl z7QKWG3@u)9h36Zg8=H*+HSYEXfB1)d%6^~m+Gd|B^VG`AnUVMbKHVM;UM3z&Ruq%I zkn#j2_&{+s_n{PSyP4>9ME+a=t$LNPkj^i@a#}II5+;>c(mv~`EedqpA zukvYq6MKu+l`3@+ZMNSjau$1WfMdOX{WmkWj&1_~V%g*Zx_kI}~%;Sfz z9AKrk47y7Q@g|tuDcE^1J}-;xr_Y&f(y+FU22}`sC5GB@)*&~zz;B~|ZsNEqzq;91 zr}>tYXrK=C&|)Ij^#mS2A0a59XyV4_8)Fjn=lm+>t%{G|rNV zWP7z&S#n4$I|hWbq$^W;JX`X()%#V=v}!*#%@+m)uKle8h>@MG^FK%f zC)!?i%N)qBub)CD0C=tl6r**QH9j)v5=*CO;_12>^r!Y5m<_@}YZC=2MTZW6?=4Pz zJncxGAn>h+twQ0P{qB&51IH}McfS^`;CVXJ%*p-2ZC5Wm7%}{72^Q`H?-mae1a7{} zmjg~X(5=l{xlZE%5(6(59hilhq; zg3p?!gDLmQTMj{(v7tNq!6@+z1&(4=FzZ7Iws)6U(L+}LwLf*Z*eSG}U9$Z2 zbh>VL-2*^^U{EW0`wXWxx`o0vQ<>r%9(5;hDQK0gyY@B^rA%74T~}AU)^Hi)us?Hb zmf7?v-IxmCVWdXRpD(AC(bfoB(i)NuvkZtJ=HwMoMf?bPqKOzaW0m|dA_-eDT_nLsVErhZWoIATnZRiyeptQCUQWjAqLcr4!3V*H%h^W^+tETtzU zBgbVHMY!m0P%w;%PO4pbAfmu&_}w0CGYE7dCHN9qOgb2%s#}DRrhdU9`vLsrv#(^u zE#(#~^b;B&@wK3*0BW4NvZW`|$GMGE-f|YXw#r<%`A}t(dD2F}XDpv<71S~889joP ztD?_rtHEd6J1`BS5h!e~V-4oc05+2!tw zyoY!m9>ZAhCrm=?ypF5gC%H%WK}THsH=;u_ZEdG-YABtL_}U8w&3u+uM?H9O5bgV( zsyXpZVf{7b)L$YZJ~;D;td(FTtj5iT30B|JLh{(L91c%m-ap)}j%w41PzHJ0hH)TT zZZM#umk?c4n((wE|J zhSAifXU9@78Zpiflzs*epY6dt+HYSC+9pbE7IL&x7#Mqu&FE4wG-^AQ|LE6Utmlna zygqdExyrp=!NqW3GAhqK8xBNZ?L`^G)wKdr9yvmyo4qwa=y*xRzP43TMNXLqI?bvX zDaWT_)P%-CS+j&LK8(brUQ)_ix`nX!+b*K1zh2Vl06DD*h;$C%FBsRtD8Ax)D;o09Mari$4nm7*STjPCU-adkG8l9_Y zT@`CzeAdk!78`p-hx_#M0IE}|fMf#Wq4c$h3=LL9`>XkBtz+Eid4|rCGPn|$Q#C^O zr)rFvp3c+|(msuMiqSpj$ybn+cB0ms;v_|;%CGE;p_;+fy7N5lbj>wW1bJVfR*fph zDd4M?ADi+s*v}imFEgmZPG_<)-|}AFc|PBKCi|zi8z8zXL9a~Y#G~QACv>NVt_%0) z`ZW4ronSad>*^RIq@n7KIw(_!_ze{<+SDJOp^ZLTnezH(m^W3Ib7xh};fZ36`x%m+ zA=$#2Z`w|o&l2FfbFb4e>FRl9^4qcHDDaHSWM_=yG(OTLJYA17ZV&JsTzQ`M*08&1 zl{P3mq|bX_!8~a&K~(eh0RI5PemKA;WfeZ*>cp9u`fAa zgVq`@G>QcE=I;zPyJel}<$zafiseibY4Wbjw_jG08NB!o6*C{(${wysm2=J^Op`$_ zn3RIJzJ*wEwr_CqZNVVbK2NW#G$#*y@lCYv%ZG|J>LZ}LpTc!J=pkYXHB*gc?dDrS z7NN3l)9vJW`Sb8(2RJTu1h@u-eNC~mtx#Jyt5D9t6v%5EN8$(wd~s1rq_y$K>2( zPXeKso`@|LL84hkJ~Jf=n@aP((`LA1%JeDLn)fU=EMWT8s_5ZAwx;Y}vHa01n+5y8 zQK6)Av6=^Pp{ykOCesZg4bDG9G|`8rTA{$8I3%RObC*OWdG@nv$_R25%!gmMO5Zoq zMHMC)kQTAR{`3ju{76zXFt6YJr3Dr&c%CqjzJMvBup#tf!=7ZZJSq`crYFX-hy15W zm8LN3G6Rz40F*B;||1|3&3k+yF`b2o)W;Kr)XY}HE&Fmh#-<~ zwweZKabxbEIDm-JSf=kek)X*PHAp~os9jT)B1Peb7Jp}eBhOh$hVBeON?lG`t!0S% zZSP?TvY!=h!okS?1}mgTSB}q6jz>I541gQ|ql@i(LDUGAokD8Q!38&f4`3MXVC?g9 z?KN6+QXuJ|UNn7wAF^34evbtYJ#9ZHyP`%1f-5$Mb7_@}+=*AH4NORlTW;_vBWi}I z07(PE%^)|syx5GL`c^IxYrm6$6*Cf0kL8&tWXFrA+eg*m%%g0jS|l<`##bWcVH@IU zMl?7nNuaPpl~c{=vG9N(Qy~Hh5U2#NkaL#=J%pS6+^2yl@>Z79Qy`cgUUht!?VNGjNq_M&=2#01vCW-4dTe=o0n|`@v^oshfttUB^a#;L(PTa1F}3 z98#$4>KR`9f73qBi&EllSAwz(sgruTc0-}-Tv;Elc@mfpc{#!GejJ=q_Pm81z3;cs zYwkbJU_q$VX+JsA#hh8))g|oj+||Xs%rez_V72C~T-ca^cp1Xw^#Sk9_mza9GjMek zZnn3Uz3s<(Z3i$mZAg>F&Uz%2#%h>LqTC+~H-!TBsI`B79HB6Dwj!3&H7?VuVw6S6 z5O3t7vVqqq@2=YWdFknY`oKbpXjI%)M-dl$)^@?;O0Vq4EieVfl5YGU%QVN8f!&cz zU?i;GiIL~m9%k4|mI-;BlHKxJXc1pe=|WYMp5a@gXsLH;4D*aX7M2zKs%sNAc~;`y zxjo-ldj7@NrzmILOl@xcqsxQeuN}8Yt2GVh+lD$<^1to4(cX64G9t`|!OlHI_aQ=1~sT*+~xriAFa$##0vNFl)dKSVY3%n((JDm`P=X z)apMsP&i<_S77U4A|k^aF1nT`KZBUdynvp5?KmC7LWYNAv7k*Wi~Rw*lb8C}QGe<38~NeS zW0|++zk}BPB-;INy#)OSFMks5{xbg) z4*a{HzY_6&_w(1M(Lb|5w!5A0z*cobu--G2s55qwEu`sZ6wl>hQwl+7> z)3GzLvZQmc)Tg!5u{E)!wX!y_)VI>Jw=l4@qqQ?|vXlKcFs4Jsv{D=pklzXO9ZbR4 z-a^+>$Hd&0&hC#*T5C(AU|DGqco=M$_fz1-Ld0#0?na?HV269vl!992OfH9T66r5*Hd2A0Cq!9iE(+6p~aBoL-fbmK&Q{nUS5A zmRpokSe;qboSP7mmzGqW8J?S-U6hknnH5=Em{ePtnVXZFn^#-_$j<|m7U$;x@&ToQ zypocV!qS?u%F=@By8No+UByxmg>^N>WZqm>XMpwt81!ntgCHmZmO$ks&8p& zs%>p;_4fz*g#knTfgzzl{}^CU3@|Je7#9MJjRi(015=}cDXGBNEMR&rFtY@hRt3xo z1Lnp9b5en&iNLZTLwZNukU~6YvYxh7)|8z?iuxSL?RaewmU(?-E*VWcC z*j78#)-u^z(%s(KT?*`~0d}_nM;d^mEx?&};6Qil++b_ZyY&tA5BB#BjSTm74-O2D z4)ufO!fCn5BE-u4X=#$tWFF~j!(@` zkIuZ?+|u0Q+}zU2(%j6_!s5!}-15pwR}Zjn2sqda9G(D0f$$BGZVnY0pQ9A zaC%{Lc4cQ~{cw40YjNY(%q(#A{cjDpu(dkAb+Nj&KeKZ^zxTYnf3>&+Ts^v8Ieyul zAKqG--CA2dUZ1&GAKKj5+*tu0tpcw$fIFLOr#o|}yDQhfmUnixclM7CejV%`o*eFN zzo+BloO2cqBo~k;io@_DFGEut;z-plLj`H%VAiCB#Hl_azI~|gXC6hfQXnG z*=DMGSx7k{hoP`Qs(QV^+X8n-Q`E(eCv`2IL?TxxSU7?EK5aevPG={d1in;|)AnS_ z_^fndV+Z(hcJF?_e)&A<`qMSDTur&GWM1*O*nY0rRI~1X?{RR~f)VJ>IS#=*hlKDJtA#%Q4b5L>4 zue|DVarU*s?OML05%?V6!u#ysk_ns`@vvEPw0eGHxz~RE)fKt+h^YNGy3l@AXPfE% zmYDgtxR$x{4Dv=qS@HELV*OYKIKpxdJh@t-ecjYl9?g~kA~&PHUdr7>XTGi%zMb7` z^AnWgw(V3)@ZS8AIctT}3}|;<>gsqIkf3XVcmH(+X$7>tP0f7TL(_g4Kiz1&(W`jf zzFMJk-$bNbXuXN1d)-C^-r#7r?!-*E!)vh5pNHm;0 zPIm=HdR)UcY+OUVxjoG1x>~uPKRiK(io`G66w19fme#T$DW^t?z>(n2vE3J}5QyXt z-?29!{EEXP`=o?mrC`+dZ}>~{PUSIx>}THN}p9&@w} z$g14y(~v=$aciBbob_rdbCOBiUw-Zg4=-C?o2!Hmt0IbMJf^TszOI=mNS3QOtX0fG##XL&9|~U$`|y5Gv%;j z7qIe7o(}Ua}S$aL&OY$uIP3|b zjl;X;%2-r;luVuW!@3%JZu4BC-Yldt29sCa_M@SJt^HdzN!yah(~Ij?(m0uv(a&qB z7dcXJ0?~ZEA6DZ~DnI`qTftKA?96LhLff@B!92Iw+QX4ace_q*ZM9YyFORB-H&N|M zr5@>v`9h@_pQ*U_DTc}@VoP4UiaRv5cn?~L&zCITL@2nnd*Szu1@TxE zQ&H$8XOZ5^E=4pw$Hy~0PK&kuwOuvN;ExS0D^_3{br1@f~>Dbz0AUk^=gX z7;I+UkiQdx_V*0)Xi>DlEG*=RJZHjK6v8w`e^D1*HNmt_GGgQigbOj`eqwgzP^c=g zb|D4NwK=mZrgpCucXf=@8s*B0*OMD4FwkjqBTS^l*73D7XiI*BlE^JznjAGn56+yl zo=f>66(xQ0;2QC^ZDLCC@*;9Yp(Vg5rA_^3bhL|z{-<;DM|9YH484k}+L%#SiNHnN zhfI8@QNJ0VAvQVEG;a%G<=~VZNXa<=uEmz@*s}tYFrLT_$y6)1+rIshap=G$1xo1L zk6i>)gBT%_{wQiDI-fD5tubAZyKv88Mfj`ZM1!-fU$$$r><1T&Ij1@^_R#>v)aQ8x zQRmR0hS^E`JxKd8l|i55vZC&IDU@vc5>8ngfomhuMM0A4-8>Y$T4C2U?)PHk%EJDsX4<6`c)W+)1D%gf*zT#7_c94 zHETz-0IIlnwaz)80j-`)c#H7O!SJX$M}52m%T@i&&acCczeYInIC+Y5ii-t9jpR6p zg3%NKvm%KibK;ie0oOjZAh~iWUa`gBg^XmB)fo1Bq-j_Xw93iag7?ak9Iq#FtRVUv z)7|poe?G77I}|3b8zxh$;~A#l(%yqKEFsC1>3zC3$~QpfDXt zBQ_1qBBtbUdSYH7-Ss31fdmuN1^aAk}zjjcM>O#UP+Ne&^tYy~9CHOQ9Gcj=C=Dn#2DGIK6o?!r1Syq>4xtC!<@VpC3RC2H2Yts?CoSB4 zu`=EmFTZ&>U-_&JLxWCCXK6hCZMU!ZSu!s;8#AzJP5679!6%Ne)PO+x3$TRnm1Gbp zhjP866dWf~)8LWB1B*^$wO+2J~k zIOLM#dra^P#+afDN)Wb^CVHHb&sdA$V=L5H8OO(2G<&Lp%G#X2p6a-@?c1-FaA$7# zX=$F{ma;lz=&N@U=6@W>==CTvAi4Ar{LvgeW9mQ~iMsDyI9Rkd*wESVvRbWzsutiT zJ$y{cX>K?yoFO|_o19e$;IQnp_Kn7`F0H9eu1}JT(CM{nsHnS~QE5d(e8j!8%Xz*lydCOz zEtI;v%5MuuF23f@^x`K)hasJrfax}OJ{HB-{}J+ubl_)yDB%53k^(Iv0&#Y!V;6uA z4=s}6*Y3S2A*B#rqnXNT1ZvcRhyAF~vh{Hr@Ga55Q!aD(KE+~{cCyXEH}^glf5O48 z-@I`cqb4b>-+O1wUKHH8iu19cmra?kABQJfDJ(6HFI47WmpQM2H({C@+7*9kq|{d&$cUh$y3A$C^2AR-ao#?ckaq3 zf4C_a+mZv#`?j7OAg027YX#@3;>E4cLC?7xE)j$Qd7_F9xu4-7d~`h2?VXH9x`CkX zZr%WH)WXJ5Y+U30(-}&j-Iw%m%#6JMGi9OHXV%89?6TULRC*4mw7V-0rmgN?Vy*{P z?L_ahk7UY=g!#dJNit~p3P48u6irdr5jC@RI64>XLZ!upkbvf5r3T(Y)AXlaCff&% zjEYV7W)+i4S-$vwH${_+gNG3l4`E~4NAo;k-pHmg!vczHu{txV9pl`WALYFYPW{!F zE*&dFD$C~T^Kyd777R&lI5d*Geeu-6)Dpaei4*(N=!0aDKd$<^N0A9B_L0F%bACcO^*GA; zDxVoKNNtpi8YYIyxS3(j#8?^@p^zz5hzZctu2g#oW0BOP)&qGEg-Ww+s~3&@Vo_A2 zFxgZymy)AkDh>~{$n#DvwmDN|U9r1L#vDFiXplE_Np=2CQaW1Cx=dG{pKi-7VA0Ck z$&LjRd%lCOi(tWExmY#zi5-16wb+F_bf_@DF##@f=wdorWzmxuLa6AGbS<-I7lq~O zmcTUX{3kY~xBsqj&5&{lb#z6eX!|zz`MwAT^VOUYvy2ogZN__ZfnfCShJO4eh?Egz zx*G~5nHRaDjb7Xe^76{Thr};Q+}HoWF&j8^aDZ6JGiDEU(60EY)s%kWYo2* z_wC$LsMrSN#u5>f4#a|1l9!8Lo&K?2HaoRGFy$ob>eJ&a=i~SHp+FnUW6BC!v5*Bc zB!Y1KQvmbT)&wq-uT(~coZ*BHIc0v|ya3ra<#0(k=>Q>NYELhHSfKfap#$d-R^7-^ z-!3dM%1l(>5VIQHY!c4bnHeopfHaQ8bh5E*J9 zdq2!h*w06pH(C;**LI5{X&*4PTH{|z%$({rm+z*ix5Dw*ou_k|%e#|Ls%_maRtyV< zD)iG%)T<{4s!tU)w>l?kuM|bR9NXWAo-&w7S9~z6r&Waya8@WRZ*BcbzMygS_=3K9 ze`?#{YMp14Dc@p!FTDz9-erRxJ8@7x;I_%RpzV%}`E%5$4d1)~{MeCsVIf3gaJWxb z>`q2{$mYsUDSS|fpl3zc;55;>n)J%NCWfrY}LfblBQN~u;!$h^8DQNoKQEOPW~ z`N-O=3sRQp9B&l|LUtu2X8nTh;?~_+7O5f|!ROLvQTYbYRqJz9rU6jX4JGYP$fCM( zEtD0mFc)9mm>(_B%lPyh1Qo0T_OxF>aE+nTqKy`zWcB%i7^nw6I7fLkQVC9pQbT{| z7ZgQ~Ue|<{je{7ps+tQ&b7P=r7q>N2EVU0Y}P&K2gi=zoY zRth(xw|C)aWFT{!$J*11Rmc&=Po<89f3Yo3z*3is%ugZ2%8vj-6oe8IfCAJlMxlOw zog(nnJw08yobr=JN86L5^6lF=<@PJyxtUeVos(IKbOkFm*D{~TL7mz13U0~DGN)1l z4(IaXeMrSdZQMg^_0#P4-HKtFY|cH{%INkFJ2V;6VDkduA6Lgaf2m-4^WL{D#Su({ zz#~9zuc?!h2RAcR z0tTu~S_&5#YwEDakv5p8t8WtgSDokOLTR#_xhaRLxw*pIj`7oR6N#I+DP@SnIBd<` zz#7PHoWX>4s)^CZhapUqOu{w#4;et&46;j%YcP;HkFq5Z1mu#qZ+(^on>00C&Dmf; zzq#;u_ztwvf~)b}#wE#w^-Q&ri_1Ry+lr8z`bXHX5?$GRAC?J4YSe^&=4q7>5cZPLCVYT*Mz@&mvv#>$U5O&b zdIqT;hJ;vc_1;lKb~CZ*Zfs#5WeR!gXADGKI*Fjf-ryVuHGURnjks%#6MYFlM6-(& zFPla7)MmNYN^=h{_3gr9C%QcMHwQOfFLu^SXIEt?e6uQCJW?3hPjzKp*~*!|vG^Fd zWc`fWP{LcrTPw-4k+v0eNfoznk`>#(5T^cQ?4H=PSa7*ADhgY%YAaPxyOfmM@_`M? zbvP8wnx`6ThRr$_A{bIgX1IdtdCT3!GLI)_$~e=sB`%tfI!vl!+sjnREUCc`4(0xe zp+5-dz1?v)YwvRd??5B=KuX%EH7#}KYB#ub*c zYU1EO0GQmfDp9C&rz^kJV(6n>QS{+ zG!MzRw!F8Btb|u5Tb~H?e zvcGBi(wkV_wzAM0_QQx*izA#h&Yia#?oaf9FG=D-5D{n3NEZ;G-@-akA+^@_5SqDJ z4NC)aCP9d>-QDKsK<}Y5aBc-70qtIB^avlXjLweh!EFQ(ukLRJIToTbjK5AKx@vI< z&k3)~X(iGX9rXz(b{w6)!J36$KC-o?@Zq854_E9Uu}rC4l9dEE$Jqe89SN7JWr#$g z{kl+2_*UyP80f&fy_UYozF49zqr=tH3S?a@HV{MUh)){ET{c~ky+#9wkYMOX!F`GCIn;QczI>Q*yQ`ppZ#KJ4FE_=v8Ewf=shOx58mP8yBCn$Mt zp9*xlB;N-kf`oM3ykI)*9ZS2eBSN0l`!LQ+0fw`(?0aMy^KLuH__B5dZvM+Nm8|Z zN%KX0<|DU`J&8>9o4E|fC5&XloOe}Pa3~cH6P3$amtZn~GjsMdne^>T@ z&*(q3@9*MS>sT6?|Ce@xeb1_%m8ISPZi`b5*T|JdWMD@ozrELXc@g!%E4p~IhI4Rrd2_J>vP#6F%)h0(XBJAepHtiE$giw&m7qVR;Az;W5$AxV zb_64#Wo;_An%ms%xXQ)@qlNf|SX3yKE7LD?g3FdLC)$7}apcTqGT+>Asb_2Qdu~&= z^f*S}sIo@6o({ptP@{pP1=S9G<+tW1vGp8r9b8F<83*`J#ze(#3^U_FedeKNX&k!C zP1#8!TX>C6?@4G0B=|8QDNU7)zUXaLqr%o3qS;n#J*EU#_=^P-%2^I~KC`kS3^A+% zVCDQaqI9>pv&~#zoAC=hRV7#W3BpzS>JD>}E%wC{x^<_YHl z_~8QdV0Y!S-Ve0hVS|LbR8?}&*-5v&Yv7D)Eih2|KGKz$ieamHYMA0oK<5q~wK@KJT>$5hR23@@JJglk6oF-wD z@NFs&bq5YGCSuhxV#9aUj@;L=e8*RvLKFL4v9l`mzFm&1fNxifb9wS1?|D{Skn~2# z`6RsT!v$_akuy;DsoM$)vdj8m1R=+}E7h1LcJ42b$4xcJj3xSA3ly}IR%#aKG4W1~J%k)q|mfU^vo9< z86A2ZuCz+P`q(xTyRLmddE3`^>@v&4V=_C(i<1U_H+6diYIjPo65gBv7x3zC*H$Vc zHq+Ivt%xQnB*ep+^5x(3Geje7biWgQ8VO^_N4UkHPyuS`Wd6z^0S)dmXv$U{xS54zCXDt# zoA%O?N83~wEfp)c0n;t`r($mo=^QJ^NCmkiqNWD&oP*ausSV012F?4T#EptWWtpBE zO>@LwA&xkTWc+Yrm?8U1AV|BK!uC3b?nQyR+LBLgLzvPOX3AZC`;>}2a#dvu3zkH@ zfyRj=O4~)X((1&Jfkz%aijD9|`kdDZtyjsU zDG-KQP2%b!4s^shZt$#M1aZH$cUG>23NCSeHtJtM+)pUcac_~y$XI(^YvR|`N&DvQ zrFbqK7;!Dy&hgsswu5(nsrR^la`;%Fb|f$i<}6WCAB+L#&n+jnp|{uerN_#_WX3S& z%P&{=hnrTdPOy93{a7TU_rRpIy2`XbO{;s2KT&vGiri~QzvcQDx7+HcF0&=*#kQ}y z$|x;?YH5*pYXhfuh!K_^`+%~f4N0Eb^IOd8y0tg1<)V`c*NdqmL=SC|Xj{r^i9_J9Sa!wh`wE5H9MrV2?T+PI0q%f*RI)p! z=;3uJv#;d)svzAa#^Uml8oM(FnG|WO?$r8-dO)vSZc8~r{QRqwtxmnDc1ne{Sb-_~ z6fZLy9mSGa$$|_wEsc|mhIDnY7KhAyRi=)${V7~Rdm~)RguuPw=@gW@s=l2w4nY#o zGEA2T8sL)4yFVEti#W>1WG;;*oY}-p)!QiVBozfQEsBo1$#c}p?b;rXAROJns5v@B z%?y6D-MvG{f;G_5%dXLJRx2hMX9FGSR?BEYtuV2>198{onXbiUC0swNBS)qA2o3{U%VUBN&*2iwdmRRM<6Z_1<_wOwHI1 zUIpO+xc0P`N*|#O=E>-A&Ajl@O4;1HA!Z>3var~CaiR6Z+%}SQeRVE^!0Ty)lgLQX zNw+zfyfb~{pGv=INV#$5_BUOcC10tlV~SDrh>DwG?l!~OY6*)6mvyyA6~TS*oB!-X z+rt==R~zut7#F6Vk|?ZC!$vF~1kFSy5BqigW}Y@|-M@nI+^gr!E{7pVZ7sWf+KP zfBr}f>=Y1??JW(f>nEkXQOVF`?Rlc2IzHnDx*h^%<}?9(c}4 zpUqCMWwrAbymHpTq9tqCh%>HB5ep%eY$%z5VQygV8SfK`P+d{#tj|ZAJgN+iY*aZf zBZ*O}ofpN|!I9-CBSEi)BBm}Tu29!Sh57ZQ2Af-flUCEeiOUG%-Ingr9nqLb8yUhu zJXEeVksUUKg)tbpCHv^RovB;Z%g*fadMYANbDt~zQzd`;@zH<3So9I=4rbbVPI^^Q z3IvyQ4pPP}>r)$Ep2kvaP_)o;*KE`ZxRRG0$hckXbrD0?8)jK)$_=h^JDSd68fR+u zsa8bWZI}~$;N>)-9F1B$2F=1t8tvX88cc>ara;MV7A4}dTli2*zo)VJ2L=VmI!tSu zarsZO)>)#c(!Jz%@G|IdUt&17C=8AOU zd-f0&JbrCUj^Xnzm=~(AcNqJ4>W9OX!=7n52FSd?$hQB*xfYE*0NBuKb5C|EbK=Sq zyU6SJZ84;DQn~jSi5Qh}!MK&md`k7$P;T7GZ^xA^BC)Toig9`}Q33b7uV%~*7!1Ap zqO2IrA$$Z5-MqU8nx)XmK%GYlesaq;YlFkuM;Q}&0U?3UXz9r6=f>z9**2t)$6msD zn@f33SJfvwmU!1wVW1p$MIpfJ6+ptj{gFZa>h_It>2T+TIk+ zxloJ)zLW{I)$9mDo)b!@#2d+@WNk#J>S|QB$ANKNf1GF?Cxr#VVfxE2h{O&T&`Hh2 zCw-Xkn5RqFPt6bIIAcV|;&pN;sM6nZ#R|@e<;!XST{w@2NpHnRG+!6N$DE2o>PLZB^P%9i)o6*tm_sT0`3R{;HZ$&m} z-w=P#WtP2+(D~m-)-2M0%w_&*iu5lvsDYi%?>SI>oJ>S2J!ap%Ellqyx;Y%EF0$}Z zj%hwX&Ez|vWv~iwn__V=iI7J*ax!%8g$89TNA=0Q84tIouWeJH=9x{AF-ZnfdYDvn- zlFtG&zK`(UcbG@pgN$$h1Bm9rqvkIvO|Ks0jUqP5w z*j_fi^R$%b#i{wYxKZ=;5<(Htmm4)thQ*)bbygEr!Uq$smu#-J9ZL>qYqHy1KRP^P zKc>ergp>syKz;eex0`K8@ZNZvUrnPH#rSNm9+@?huH)GTrrXOS3P2cRv5p)Tjf(dxJp_jA}zD_?NiHyUr z&#JXqn}YbExjjsV#5ixEURwQ8#>jBmbeGEFgtj!hCPJ~96deqjVEphkf5(B4SLNgl;CwtVVyI0}Yj zpg9iLj~8NMqu4dxiS%dHjJR?rG*1r+vPO83hOI3Nr`eq!ud<1AshRw57{9wkQ4C?y z7AOeF_YeQATl}8&Tj*Gt7#i5x(c0)6j>V2y`qCr$opbvej4ytpgMhFhA8s|_a0 zfuOre`Ly015vwGZSA3K?yHhUAv=LF8da8pv7+PJ_rNFF5K{70ATz5#t*+Sctzw*vS z*HaOs;9Z*f=4VniJ6ck5Xeap7u))Z~ymrCf8%w0`NDWB(}%*Iyd}1&trhZ*sfq zhRrd)4Q;3_XLpNzj_qT9p$zeY`U)*MCi9V);YdMat z?9=UmA8j+fIov-ks3Im7*Mr~+_Ov$JD$g{0H{9ZlUC#7e>}UEeH;CeXq%oe!9JO#c z0}tM4CxBSn6}1k6=HJG1jh>2vW7;nVBX>B4@32KM9&q$A`2 z6S(O#Gx`AhDWjX_+1rylO$x>82uWMbMCy;4Y&v)-QO65MR+;5o221h&n^$|~%uJ+! z#F6XAm!8%q(79R-z?`XpqvNY_kWF{tK=E*fM+povTgVCQl5Se{NN8w@&7J3=dEFpe zc@s6uyoXBaMx!RhpvQQV_u|vOx&0FDX}KWfaRu%^PDT7(+x>=P`^>dB7;AT4ZM$9q z^cpgGVSay~g|l++rEUv71Me>H_2B3oOnb3nIaMJv5X_BprQ>AeNNSHV^JWX~06d7i zKZ`}r2F69A2U89tHoxBw8vZfPPG5dYqlZXXHt69xiR3^-xYEmbLH(I%v`t`9c4WtG zJ-9xhIDC74g*A!p`h2fzvt*ufPR*k!u<|=#b(VJ@t>jVV+oknSU0BG5SWfn!PoZ5i z`fO8}VTk;dDKZa;y-tET^*t5=!)b9b&E~-XlWbAFCivr=JT_!)7~k7+?PY4_qPvPV zn`qlxJf07r+1^EEzkCAoAsO>n_?dnD59N^4p@>&yR2xUL%_sUAnocH96_q^DmZ1_zyKC9m1k_!wG#@S)`MO&-L@L&I}i~h3Oa|WA@Bn zz8I>OC>8%|%jBxhXpkdDeby&ZkL*S{l#$()7n!1-gl?5|ostjceup42O4q>@AIG?& zVWRgspM66jCBmD3iHRG+0|8dl794ES*lubwG<%iw!l$TIDcB>BmSh0y_lv17#Bn;L z7^NScFYWG;>Lf01L*tPRo(H*1;}R;4L4e?pPJYLh&6nIoB?>+!n6~m49?9eD*Dp{N z!-D-KxCP)A3|p}48!hty0Jtxwym9 zy~aN{XK}>7Dg=-koZl9ceF8`SzFJE!jcP362$NZbphqeg+T6|?C7+j#zxmYsfLmJ! zuP-;c>)jKq$2r%weaAi^cb!&lvVy%In`AHpCXoz|#R5U}0jbv_+L8gepj-KeeY6nx z5v^PZcgfr5@aI@E@9E3ftiZ6 zMd?%KKnuF#FQ=Re`1TB20}cb|dK+n7V)p>{&Q-6Un22sT0x%2o^Z<}@@NJ|7-p>;w zqrbTJSnwIQI6f;GG0l6oGkSCBUn!8K`=IwF^AlV%lfA)4l2fU7?~Vv~#~EuNT03>e z*VL)H&(iy6>P2lh&U9HZ4s&g&Bp|xGFF*Y2)sEp~F{S$v1f+xVzrCA&|38kcowK>Y zzuruz>c{`$TGurn~r429>KAufI-&|I_4L@(Kov%-y zCiFU`Pd1KP)4I`0Q|vP#jX$cP5VXbYnT4=#9pf4#RS2~fK#Z47F7IiT0B%rN78QQ> zoruG_q00M{SP7t86ik#RX&(Az_bBKL!6r3tt8*$o49a^-ye1h!e9Fu3V<34v5V4{Y ztkR-J2<&;OOp~uy_d`TPgcT}7ji74J(FbgcZ$n5|rG?RTJ2zIgVxb!sd&Dd#Qqa}F z8^&hyf!UW1XFA04Y@4uwNVSTXS6h+q7dR&l*khR5F^}Lel%uDDukF9l97KSEABR0@eISS$n_4Ig(fxzaxwsNEc2+F@w79k--vA-htE?L&C=$X@ zFh;hxcRn0hgHGZQLLjBB8!J2d8?>~ApOVB8UcmRSJG?_(3?@|$c{ocx*ZIGgHU_lO zWA;bZz^`(X2bP$L&ePWj8&DkvXhNzoH`({j*N;Y(crp$*z7L6<6Oj)Z0XqYi=$HkX z*nAZXRheQk@Y}v-`CNUif4C8_n#WYTdge;&DJI-Z!m8LO4+8+lP4y*f8!t!%%< z`OLc2$Z&Ws!y^jJ@4b?8dI-8&58~HRcGuO=1#C}nFF=&cF?Ojd6cmKj5#hu;z@fQ* za!puxxq}tOOM(WACQs~w$jxLx#i#HWKak3LyEbHu-fbbsY_>2kv|YU`B`CC{?F%pUFGrIUpdD(EN-bIWGD6`MC^ z8Ga$gKyy^p(N5zu4XiVg1h;`XW=E>Je;*C09J0%JV}7@0>r^5hI?Meo%K_npDn>t7 zN=|bZ4@p783P)5F)WuJX4nIKX?6Vg@r>&#mPtZmq&QWfTutN6mk*4vcRA-IS0g#r< znACiV5%CGUiNFsvIhO7lLN0%i5yh}0$#NG_X|nDj0|YqP!%a3*DPkY|aG(wU7}Y^# zs|zW3X7cE?bzNYRDowVPrK)e?!y?YCX?IAr<8a7wdhM64+BzX@K5mj~Dijy(iLDUE zNFjg&A=C7*4D9>T|YOy`B2`g^>jTaDWI#r1kyVJRusf+2dE%T7xS>i^)Y?yNB8>l}K zj=Z1e$5-*rMR-mtiEu0#}Bue(tK z`e#Cpcn-&dmR%dy?3ji2pjX(To4Mqkz31X=a*l)NUiNhq&uh08yyh7a&bg(vuwoF- z_b+%?(2evPFd|ymm%}VWVIhG!dZM@_8J-10VsEdYK41D?$3Ht8#r&M#ZSMEW-S?Rs zLh_YF=mJ;eiJF|9V14JROTDg0!-&N?()y#4H_t!ipAPFXV4-3SeDCWRtWs#n#XuZl zHM>sp?Pq_Y>6jlmrtmLuQAV%jz^CvUC}|D0mhn~_wvc^s9?-YyDh53sYzpXVVMV7a zhgmyiC+~&OB1B1&*Sz5n3f-g5#I$KYG(k`TNEF7MTv381>v&K#eO^KN_St>xYv=f) zphvY-KP8F(73j$7?Jo=C6lNGmsY-(Zq$Wxv)E+yoc9$L{Io z4z^!edgJ)+KJL-Oczngn_l#F4ih0cGWdZRy>XrUL*ryJ#LxC_%n0DigSO{NdD%{M+ zjW2SPVaifcRMPkGb=r^kDb(7KJ(`d0p6Yj8iNUq@LaL_K6t09;c0{;a9OyL-&Uv{N zHt8&P#EfY%?)3Pk>x$Aykpd5MA78R$ellv>IBvzMHk93;lD{C{pxtufs#S5PxbG$m z3_15fQ>gYeD`F2&mh0eNPpd;i`KkK26f$G0OS7KKZ<$M1ea+hvZ>k-xRNzV9-qwte zBUEtSCRGC`rrpTmNzS(2v1m6YiS^M@n^3+zkIT>En3++4t_q=Xjsw)FGw~tdl_h>F z$$w+GzTSdgB6~Os_3O~O^kVg^r|s7%WM}RpSf44;s*P)7(TmaE5B%3 zx^pNMOxd6%S2`b>pY#SwZD*(;8vs)ie&og^lQd#ifAqo zzL~PHirM{qDlBlK5ssIFYdMRp6OV2kb#vB3;_FrVQQ!wlwA?>Kk~{-SuopaxyO^d} zU<|IWs4|SBGwO;l0$?i+i#)c5-0*e|+yMzg| zBXxFvljGDkyl&es(^Dn*y>%jG578^dSV61xAO+lBg7$daORZkx4n6dy+`|KifI<+2Z zKDZ_lxg>3bmrhB7A;Dxae(9)W>@Sd{7Zg0W6D;{$r8)e@nSU=Wyz5}Osy;(;-B(~K z4`4aR1X#Ma1%p2pM)qKG9FbTeRe(b8-#@XJj|>ct4Q(;GKhb8+*DuMNg@dUId#IYE zm5<~h5oD(t8iw`==VxZ?m64OHdRFRTve!58hX;PR&^p&3_rHV~CQP@ackFa>!J;85MCHoYv!~1<)I{x*) z4P4RQ2d+{=3VbwT(!zBAhn#w6SIXj~EPFm9`QLN+_ti7jsw$F8qsP1W+<>5Pvx_=a zJ_K*CV5t9$DHb;J2@XU|6Lm+M=9prVS3D}iT0dtUZTI5%(5v{3t; z%OJ=>6XF)p%~GmzMU3|Wg_tjtPnbkAP=PC6EsxxDenjpNdkssa26mZ~TSjAJ5IRpY z2V1wi9crsdz$yS$<*=3&W)DwCVYxg+9d=oT+P3N3>Z4tC{mEy1DpLHXW_VCDaDx-B zQcSya7E@+oX@%>bA79$-@oV5o6Py+an4pC~@s(ymVuJ zTN}NA>5bCrwP5JJ&Q9bxGvm<{Z#pul67IyjCi|3O$=kcWt#Km!^3+tn@w-7-NlZAT z-&wAkf02ZsV5lJfc`bqWR{4wlv9f@y#J_v}ebInFU8LSO|I-ozf1v!qT>n*O^qZpm z)9BtsIe(QY{o(n?3J8Cm`9CtGKlfeVJ^!xB`Ku`D-^=l*-`{a+{sHH&BBlSq`J*Ji zasE&m{gx^HX~+M7^B+V@|E-YkD1R}2y#Kq9|1Mej&&B+$1^Uz6{sHMv3Df^uldDe|KR-5 z3;r6T`7MI_(_-Io{vwI`qox0F{40z9FV))r@kDr^{J$^m@vnf+-@X1yUjO^;Lqh%U zeE;7)|4J?VyQex`ybu|vJw#Q U?8k2r;wO;e_a~S5x8HmJ3;U(mBLDyZ From 5ada47195a49c29be7d732ff5b05205de3cc25b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 15:48:50 +0200 Subject: [PATCH 100/128] FIX Link to social network --- htdocs/core/lib/functions.lib.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 299dacd91d6..7454923f94a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3012,8 +3012,16 @@ function dol_print_socialnetworks($value, $cid, $socid, $type, $dictsocialnetwor } } else { if (!empty($dictsocialnetworks[$type]['url'])) { + $tmpvirginurl = preg_replace('/\/?{socialid}/', '', $dictsocialnetworks[$type]['url']); + if ($tmpvirginurl) { + $value = preg_replace('/'.preg_quote($tmpvirginurl, '/').'\/?/', '', $value); + } $link = str_replace('{socialid}', $value, $dictsocialnetworks[$type]['url']); - $htmllink .= ' '.dol_escape_htmltag($value).''; + if (preg_match('/^https?:\/\//i', $link)) { + $htmllink .= ' '.dol_escape_htmltag($value).''; + } else { + $htmllink .= ' '.dol_escape_htmltag($value).''; + } } else { $htmllink .= dol_escape_htmltag($value); } From 74346c6480c93af00462feaf3b73d660d77b1ebc Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Tue, 31 May 2022 16:59:57 +0200 Subject: [PATCH 101/128] Fix sql error when PRODUCT_USE_SUPPLIER_PACKAGING enabled. --- htdocs/fourn/class/fournisseur.product.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index fb7b9197695..79f7792944a 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -448,11 +448,11 @@ class ProductFournisseur extends Product // Add price for this quantity to supplier $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price("; $sql .= " multicurrency_price, multicurrency_unitprice, multicurrency_tx, fk_multicurrency, multicurrency_code,"; - $sql .= "datec, fk_product, fk_soc, ref_fourn, desc_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation, barcode, fk_barcode_type)"; + $sql .= "datec, fk_product, fk_soc, ref_fourn, desc_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation, barcode, fk_barcode_type"; if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { $sql .= ", packaging"; } - $sql .= " values("; + $sql .= ") values("; $sql .= (isset($multicurrency_buyprice) ? "'".$this->db->escape(price2num($multicurrency_buyprice))."'" : 'null').","; $sql .= (isset($multicurrency_unitBuyPrice) ? "'".$this->db->escape(price2num($multicurrency_unitBuyPrice))."'" : 'null').","; $sql .= (isset($multicurrency_tx) ? "'".$this->db->escape($multicurrency_tx)."'" : '1').","; From 4e939a7c5def3e981a5e1d0bbce329f747b09ee0 Mon Sep 17 00:00:00 2001 From: NextGestion Date: Tue, 31 May 2022 15:38:23 +0000 Subject: [PATCH 102/128] Fix error in "Subscription" list (toselect value) --- htdocs/adherents/subscription/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index d96adbc3b82..6056e1320f0 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -628,10 +628,10 @@ while ($i < min($num, $limit)) { 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($obj->rowid, $arrayofselected)) { + if (in_array($obj->crowid, $arrayofselected)) { $selected = 1; } - print ''; + print ''; } print ''; if (!$i) { From 98ebe0cff40a6becfb9ac5edc172239ce96266eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 17:58:47 +0200 Subject: [PATCH 103/128] Trans --- htdocs/langs/en_US/exports.lang | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index 9dc400f91f7..c6dd04fd488 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -82,7 +82,7 @@ SelectFormat=Choose this import file format RunImportFile=Import Data NowClickToRunTheImport=Check the results of the import simulation. Correct any errors and re-test.
    When the simulation reports no errors you may proceed to import the data into the database. DataLoadedWithId=The imported data will have an additional field in each database table with this import id: %s, to allow it to be searchable in the case of investigating a problem related to this import. -ErrorMissingMandatoryValue=Mandatory data is empty in the source file for field %s. +ErrorMissingMandatoryValue=Mandatory data is empty in the source file in column %s. TooMuchErrors=There are still %s other source lines with errors but output has been limited. TooMuchWarnings=There are still %s other source lines with warnings but output has been limited. EmptyLine=Empty line (will be discarded) @@ -92,9 +92,9 @@ YouCanUseImportIdToFindRecord=You can find all the imported records in your data NbOfLinesOK=Number of lines with no errors and no warnings: %s. NbOfLinesImported=Number of lines successfully imported: %s. DataComeFromNoWhere=Value to insert comes from nowhere in source file. -DataComeFromFileFieldNb=Value to insert comes from field number %s in source file. -DataComeFromIdFoundFromRef=Value that comes from field number %s of source file will be used to find the id of the parent object to use (so the object %s that has the ref. from source file must exist in the database). -DataComeFromIdFoundFromCodeId=Code that comes from field number %s of source file will be used to find the id of the parent object to use (so the code from source file must exist in the dictionary %s). Note that if you know the id, you can also use it in the source file instead of the code. Import should work in both cases. +DataComeFromFileFieldNb=Value to insert comes from column %s in source file. +DataComeFromIdFoundFromRef=Value that comes from column %s of source file will be used to find the id of the parent object to use (so the object %s that has the ref. from source file must exist in the database). +DataComeFromIdFoundFromCodeId=Code that comes from column %s of source file will be used to find the id of the parent object to use (so the code from source file must exist in the dictionary %s). Note that if you know the id, you can also use it in the source file instead of the code. Import should work in both cases. DataIsInsertedInto=Data coming from source file will be inserted into the following field: DataIDSourceIsInsertedInto=The id of the parent object, that was found using the data in the source file, will be inserted into the following field: DataCodeIDSourceIsInsertedInto=The id of the parent line, that was found from code, will be inserted into the following field: From a253938db9a51fa0e4537700256c8bd670618440 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 18:08:53 +0200 Subject: [PATCH 104/128] Better error message --- htdocs/core/lib/functions.lib.php | 15 +++++++++++++++ .../core/modules/import/import_xlsx.modules.php | 2 +- htdocs/imports/import.php | 14 -------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7454923f94a..c3227489507 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -183,6 +183,21 @@ function isASecretKey($keyname) return preg_match('/(_pass|password|_pw|_key|securekey|serverkey|secret\d?|p12key|exportkey|_PW_[a-z]+|token)$/i', $keyname); } + +/** + * Return a numeric value into an Excel like column number. So 1 return 'A', 2 returns 'B'..., 27 return 'AA' + * + * @param int|string $n Numeric value + * @return string Column in Excel format + */ +function num2Alpha($n) +{ + for ($r = ""; $n >= 0; $n = intval($n / 26) - 1) + $r = chr($n % 26 + 0x41) . $r; + return $r; +} + + /** * Return information about user browser * diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 7be4ee8894a..a058fd0174a 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -446,7 +446,7 @@ class ImportXlsx extends ModeleImports // Is it a required field ? if (preg_match('/\*/', $objimport->array_import_fields[0][$val]) && ((string) $newval == '')) { - $this->errors[$error]['lib'] = $langs->trans('ErrorMissingMandatoryValue', $key); + $this->errors[$error]['lib'] = $langs->trans('ErrorMissingMandatoryValue', num2Alpha($key)); $this->errors[$error]['type'] = 'NOTNULL'; $errorforthistable++; $error++; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 427e6a4dea6..4209b5e9e96 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -2349,20 +2349,6 @@ function show_elem($fieldssource, $pos, $key, $var, $nostyle = '') } -/** - * Return a numeric into an Excel like column number - * - * @param string $n Numeric value - * @return string Column in Excel format - */ -function num2Alpha($n) -{ - for ($r = ""; $n >= 0; $n = intval($n / 26) - 1) - $r = chr($n%26 + 0x41) . $r; - return $r; -} - - /** * Return not used field number * From 21e5189e182559586fcf208d286df82b2e5e21e2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 18:17:43 +0200 Subject: [PATCH 105/128] Add phpunit for num2Alpha --- htdocs/core/lib/functions.lib.php | 2 +- .../modules/import/import_xlsx.modules.php | 6 +++--- htdocs/imports/import.php | 2 +- test/phpunit/FunctionsLibTest.php | 20 +++++++++++++++++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c3227489507..fc743889b28 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -185,7 +185,7 @@ function isASecretKey($keyname) /** - * Return a numeric value into an Excel like column number. So 1 return 'A', 2 returns 'B'..., 27 return 'AA' + * Return a numeric value into an Excel like column number. So 0 return 'A', 1 returns 'B'..., 26 return 'AA' * * @param int|string $n Numeric value * @return string Column in Excel format diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index a058fd0174a..c3339a0a138 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -1,6 +1,6 @@ - * Copyright (C) 2009-2012 Regis Houssin +/* Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2012-2016 Juanjo Menent * @@ -446,7 +446,7 @@ class ImportXlsx extends ModeleImports // Is it a required field ? if (preg_match('/\*/', $objimport->array_import_fields[0][$val]) && ((string) $newval == '')) { - $this->errors[$error]['lib'] = $langs->trans('ErrorMissingMandatoryValue', num2Alpha($key)); + $this->errors[$error]['lib'] = $langs->trans('ErrorMissingMandatoryValue', num2Alpha($key - 1)); $this->errors[$error]['type'] = 'NOTNULL'; $errorforthistable++; $error++; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 4209b5e9e96..bf335b9714b 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -1743,7 +1743,7 @@ if ($step == 5 && $datatoimport) { } //print $code.'-'.$label; $alias = preg_replace('/(\..*)$/i', '', $label); - $listfields[$i] = $langs->trans("Field").' '.$code.'->'.$label; + $listfields[$i] = $langs->trans("Column").' '.num2Alpha($code - 1).' -> '.$label; } print count($listfields) ? (join(', ', $listfields)) : $langs->trans("Error"); print ''; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 1bf3b6378fb..82205369c86 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -166,6 +166,26 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase print __METHOD__."\n"; } + /** + * testNum2Alpha + * + * @return void + */ + public function testNum2Alpha() + { + $result = num2Alpha(0); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, 'A', 'Check num2Alpha 0'); + + $result = num2Alpha(5); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, 'F', 'Check num2Alpha 5'); + + $result = num2Alpha(26); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, 'AA', 'Check num2Alpha 26'); + } + /** * testIsValidEmail * From b479cc4e9db2d7f429144633cd7faf37ca7a5e3a Mon Sep 17 00:00:00 2001 From: NextGestion Date: Tue, 31 May 2022 17:31:11 +0000 Subject: [PATCH 106/128] PHP V8 warning societe/index.php --- htdocs/societe/index.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php index 8cae5ef49f8..597fc4b80ea 100644 --- a/htdocs/societe/index.php +++ b/htdocs/societe/index.php @@ -177,7 +177,8 @@ if (!empty($conf->use_javascript_ajax) && ((round($third['prospect']) ? 1 : 0) + $statstring .= ''.$langs->trans("Customers").''.round($third['customer']).''; $statstring .= ""; } - if ((($conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS)) { + $statstring2 = ''; + if (((!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS)) { $statstring2 = ""; $statstring2 .= ''.$langs->trans("Suppliers").''.round($third['supplier']).''; $statstring2 .= ""; From c8ff7ff02abc467be9aa4a920a736e23cbd62cde Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 May 2022 18:31:36 +0200 Subject: [PATCH 107/128] Fix look and feel v16 --- htdocs/imports/import.php | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index bf335b9714b..c4eb34ce1e5 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -799,6 +799,7 @@ if ($step == 4 && $datatoimport) { $minpos = min(count($fieldssource), count($fieldstarget)); //var_dump($array_match_file_to_database); + $initialloadofstep4 = false; if (empty($_SESSION['dol_array_match_file_to_database_select'])) { $initialloadofstep4 = true; @@ -971,6 +972,7 @@ if ($step == 4 && $datatoimport) { print ''; print img_mime($file, '', 'pictofixedwidth'); print $filetoimport; + print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"'); print ''; print ''; @@ -1052,21 +1054,19 @@ if ($step == 4 && $datatoimport) { print ''; // Set the list of all possible target fields in Dolibarr. - $optionsnotused = ""; $optionsall = array(); foreach ($fieldstarget as $code => $line) { - $text = ''; - if (!$line["imported"]) { - $optionsnotused .= $text; - } - $optionsall[$code] = array('label'=>$langs->trans($line["label"]), 'required'=>(empty($line["required"]) ? 0 : 1), 'position'=>!empty($line['position']) ? $line['position'] : 0); } - // $optionsall is an array of all possible fields. key=>array('label'=>..., 'xxx') + // $optionsall is an array of all possible target fields. key=>array('label'=>..., 'xxx') $height = '32px'; //needs px for css height attribute below $i = 0; @@ -1119,7 +1119,11 @@ if ($step == 4 && $datatoimport) { $j = 0; foreach ($optionsall as $tmpcode => $tmpval) { // Loop on each entry to add into each combo list. - $label = $tmpval['required'] ? '' : ''; + $label = ''; + if ($tmpval['picto']) { + $label .= img_picto('', $tmpval['picto'], 'class="pictofixedwidth"'); + } + $label .= $tmpval['required'] ? '' : ''; $label .= $tmpval['label']; $label .= $tmpval['required'] ? '*' : ''; @@ -1599,6 +1603,7 @@ if ($step == 5 && $datatoimport) { print ''; print img_mime($file, '', 'pictofixedwidth'); print $filetoimport; + print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"'); print ''; print ''; @@ -1745,7 +1750,7 @@ if ($step == 5 && $datatoimport) { $alias = preg_replace('/(\..*)$/i', '', $label); $listfields[$i] = $langs->trans("Column").' '.num2Alpha($code - 1).' -> '.$label; } - print count($listfields) ? (join(', ', $listfields)) : $langs->trans("Error"); + print count($listfields) ? (join(',  ', $listfields)) : $langs->trans("Error"); print ''; print ''; From 976f6d42b8b3dfe1c87e1b28901df33e968b5235 Mon Sep 17 00:00:00 2001 From: BB2A Anthony Berton Date: Wed, 1 Jun 2022 09:15:21 +0200 Subject: [PATCH 108/128] php V8 warning --- htdocs/core/lib/usergroups.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 3883ae11fb4..dac412f92a6 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -485,7 +485,7 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) print ''; if ($edit) { //print ajax_constantonoff('THEME_TOPMENU_DISABLE_IMAGE', array(), null, 0, 0, 1); - print $form->selectarray('THEME_TOPMENU_DISABLE_IMAGE', $listoftopmenumodes, $conf->global->THEME_TOPMENU_DISABLE_IMAGE); + print $form->selectarray('THEME_TOPMENU_DISABLE_IMAGE', $listoftopmenumodes, isset($conf->global->THEME_TOPMENU_DISABLE_IMAGE)?$conf->global->THEME_TOPMENU_DISABLE_IMAGE:0); } else { $listoftopmenumodes[$conf->global->THEME_TOPMENU_DISABLE_IMAGE]; //print yn($conf->global->THEME_TOPMENU_DISABLE_IMAGE); From 008396b3dfbd80f4cc8d045f0a6123fba9126467 Mon Sep 17 00:00:00 2001 From: Manu Date: Wed, 1 Jun 2022 09:18:54 +0200 Subject: [PATCH 109/128] Fix a few CSS errors --- htdocs/theme/md/style.css.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index d8a6a1d928c..2ef550a1fe0 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -473,7 +473,7 @@ section.setupsection { border-radius: 5px; } -.field-error-icon { color: #ea1212; !important; } +.field-error-icon { color: #ea1212 !important; } textarea { border-radius: 0; @@ -3372,7 +3372,7 @@ a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { border-right: 1px solid transparent; border-left: 1px solid transparent; border-top: 1px solid transparent; - border-bottom: 0px !important;*/ + border-bottom: 0px !important; } a.tab:hover @@ -3474,7 +3474,7 @@ input.buttonreset { padding-: 0px; padding-: 16px; padding-bottom: 4px; - margin-right: 0px 0px; + margin-right: 0px; } .notopnoleftnoright { border-collapse: collapse; @@ -3714,7 +3714,7 @@ div.refidpadding { } div.refid { font-weight: bold; - color: rgb(--colortexttitlenotab); + color: var(--colortexttitlenotab); font-size: 160%; } a.refid { @@ -3946,12 +3946,12 @@ table.dataTable tr.oddeven { /* For no hover style */ td.oddeven, table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td, form.nohover, form.nohover:hover { - background-color: var(--colorbacklineimpair1) !important; !important; - background: var(--colorbacklineimpair1) !important; !important; + background-color: var(--colorbacklineimpair1) !important; + background: var(--colorbacklineimpair1) !important; } td.evenodd, tr.nohoverpair td, #trlinefordates td { - background-color: var(--colorbacklinepair1) !important; !important; - background: var(--colorbacklinepair1) !important; !important; + background-color: var(--colorbacklinepair1) !important; + background: var(--colorbacklinepair1) !important; } .trforbreak td { font-weight: bold; @@ -4088,7 +4088,7 @@ input.liste_titre { white-space: nowrap; line-height: 1.5em; } -} + .noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { white-space: normal; } @@ -4117,7 +4117,7 @@ tr.liste_sub_total, tr.liste_sub_total td { } .paymenttable tr td:first-child, .margintable tr td:first-child { - //padding-left: 2px; + /*padding-left: 2px;*/ } .paymenttable, .margintable tr td { height: 22px; @@ -4284,7 +4284,7 @@ span.boxstatstext { span.boxstatsindicator { font-size: 110%; font-weight: normal; - font-color: rgb(); + color: rgb(); } span.dashboardlineindicator, span.dashboardlineindicatorlate { font-size: 120%; @@ -6945,7 +6945,7 @@ div.clipboardCPValue.hidewithsize { .clipboardCPTextDivInside { position: absolute; background: #EEE; - color: 888; + color: #888; border: 1px solid #DDD; opacity: 1; z-index: 20; @@ -7215,3 +7215,4 @@ div#topmenu-bookmark-dropdown { div.flot-text .flot-tick-label .tickLabel, .fa-color-unset { color: unset; } + From 06def03a1fcc28beaef2e2e6d54f757c52fb2eb7 Mon Sep 17 00:00:00 2001 From: Manu Date: Wed, 1 Jun 2022 09:36:57 +0200 Subject: [PATCH 110/128] Fix a few CSS errors in md theme --- htdocs/theme/md/style.css.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 73337ba0284..8e71dfcd06f 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -488,7 +488,7 @@ section.setupsection { border-radius: 5px; } -.field-error-icon { color: #ea1212; !important; } +.field-error-icon { color: #ea1212 !important; } textarea { border-radius: 0; @@ -3570,7 +3570,7 @@ td.border, div.tagtable div div.border { left: 0; top: 0; max-width: 150px !important; - //background-color: inherit; + /*background-color: inherit;*/ background-color: gainsboro; z-index: 2; } @@ -3583,7 +3583,7 @@ td.border, div.tagtable div div.border { right: 0; top: 0; max-width: 150px !important; - //background-color: inherit; + /*background-color: inherit;*/ background-color: gainsboro; z-index: 2; } @@ -4164,7 +4164,7 @@ tr.liste_sub_total, tr.liste_sub_total td { } .paymenttable tr td:first-child, .margintable tr td:first-child { - //padding-left: 2px; + /*padding-left: 2px;*/ } .paymenttable, .margintable tr td { height: 22px; From 682da1fabe42f86ef5ecd56ecde185c48e6d67c0 Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Wed, 1 Jun 2022 11:33:15 +0200 Subject: [PATCH 111/128] FIX if password doesnt match rule it created a user without password --- htdocs/user/card.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 821d6748eb6..cc32cba558c 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -333,18 +333,26 @@ if (empty($reshook)) { $id = $object->create($user); if ($id > 0) { + $resPass = ''; if (GETPOST('password', 'none')) { - $object->setPassword($user, GETPOST('password', 'none')); + $resPass = $object->setPassword($user, GETPOST('password', 'none')); } - if (!empty($conf->categorie->enabled)) { - // Categories association - $usercats = GETPOST('usercats', 'array'); - $object->setCategories($usercats); - } - $db->commit(); + if($resPass < 0) { + $langs->load("errors"); + $db->rollback(); + setEventMessages($object->error, $object->errors, 'errors'); + $action = "create"; // Go back to create page + } else { + if(! empty($conf->categorie->enabled)) { + // Categories association + $usercats = GETPOST('usercats', 'array'); + $object->setCategories($usercats); + } + $db->commit(); - header("Location: ".$_SERVER['PHP_SELF'].'?id='.$id); - exit; + header("Location: ".$_SERVER['PHP_SELF'].'?id='.$id); + exit; + } } else { $langs->load("errors"); $db->rollback(); From d345957b84eec122f1bee13fe850975ca45df14e Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Wed, 1 Jun 2022 11:36:47 +0200 Subject: [PATCH 112/128] Fix: import update on xlsx --- htdocs/core/modules/import/import_xlsx.modules.php | 2 +- htdocs/imports/import.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index c3339a0a138..a7fcf6f0d0f 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -920,7 +920,7 @@ class ImportXlsx extends ModeleImports if (empty($keyfield)) { $keyfield = 'rowid'; } - $sqlSelect .= "WHERE ".$keyfield." = ".((int) $lastinsertid); + $sqlSelect .= " WHERE ".$keyfield." = ".((int) $lastinsertid); $resql = $this->db->query($sqlSelect); if ($resql) { diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index c4eb34ce1e5..05d1dd89a88 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -1120,7 +1120,7 @@ if ($step == 4 && $datatoimport) { $j = 0; foreach ($optionsall as $tmpcode => $tmpval) { // Loop on each entry to add into each combo list. $label = ''; - if ($tmpval['picto']) { + if (!empty($tmpval['picto'])) { $label .= img_picto('', $tmpval['picto'], 'class="pictofixedwidth"'); } $label .= $tmpval['required'] ? '' : ''; From 69e8c1abe472910083cfb1a53fbaa583618d8d1e Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Wed, 1 Jun 2022 11:44:07 +0200 Subject: [PATCH 113/128] New : update in import for socialnetworks --- .../modules/import/import_csv.modules.php | 35 ++++++++++++++----- .../modules/import/import_xlsx.modules.php | 35 ++++++++++++++----- htdocs/core/modules/modSociete.class.php | 9 +++++ 3 files changed, 61 insertions(+), 18 deletions(-) diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 08eb9a6f42d..8c3e5bfeab9 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -750,13 +750,6 @@ class ImportCsv extends ModeleImports $i++; } - // We db escape social network field because he isn't in field creation - if (in_array("socialnetworks", $listfields)) { - $socialkey = array_search("socialnetworks", $listfields); - $tmpsql = $listvalues[$socialkey]; - $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; - } - // We add hidden fields (but only if there is at least one field to add into table) // We process here all the fields that were declared into the array $this->import_fieldshidden_array of the descriptor file. // Previously we processed the ->import_fields_array. @@ -838,8 +831,18 @@ class ImportCsv extends ModeleImports foreach ($updatekeys as $key) { $col = $objimport->array_import_updatekeys[0][$key]; $key = preg_replace('/^.*\./i', '', $key); - $where[] = $key.' = '.$data[$key]; - $filters[] = $col.' = '.$data[$key]; + if ($conf->socialnetworks->enabled && strpos($key, "socialnetworks") !== false) { + $tmp = explode("_", $key); + $key = $tmp[0]; + $socialnetwork = $tmp[1]; + $jsondata = $data[$key]; + $json = json_decode($jsondata); + $where[] = $key." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; + $filters[] = $col." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; + } else { + $where[] = $key.' = '.$data[$key]; + $filters[] = $col.' = '.$data[$key]; + } } $sqlSelect .= " WHERE ".implode(' AND ', $where); @@ -896,6 +899,13 @@ class ImportCsv extends ModeleImports } if (!empty($lastinsertid)) { + // We db escape social network field because he isn't in field creation + if (in_array("socialnetworks", $listfields)) { + $socialkey = array_search("socialnetworks", $listfields); + $tmpsql = $listvalues[$socialkey]; + $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; + } + // Build SQL UPDATE request $sqlstart = "UPDATE ".$tablename; @@ -933,6 +943,13 @@ class ImportCsv extends ModeleImports // Update not done, we do insert if (!$error && !$updatedone) { + // We db escape social network field because he isn't in field creation + if (in_array("socialnetworks", $listfields)) { + $socialkey = array_search("socialnetworks", $listfields); + $tmpsql = $listvalues[$socialkey]; + $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; + } + // Build SQL INSERT request $sqlstart = "INSERT INTO ".$tablename."(".implode(", ", $listfields).", import_key"; $sqlend = ") VALUES(".implode(', ', $listvalues).", '".$this->db->escape($importid)."'"; diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index c3339a0a138..3887caccb8e 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -795,13 +795,6 @@ class ImportXlsx extends ModeleImports $i++; } - // We db escape social network field because he isn't in field creation - if (in_array("socialnetworks", $listfields)) { - $socialkey = array_search("socialnetworks", $listfields); - $tmpsql = $listvalues[$socialkey]; - $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; - } - // We add hidden fields (but only if there is at least one field to add into table) // We process here all the fields that were declared into the array $this->import_fieldshidden_array of the descriptor file. // Previously we processed the ->import_fields_array. @@ -883,8 +876,18 @@ class ImportXlsx extends ModeleImports foreach ($updatekeys as $key) { $col = $objimport->array_import_updatekeys[0][$key]; $key = preg_replace('/^.*\./i', '', $key); - $where[] = $key . ' = ' . $data[$key]; - $filters[] = $col . ' = ' . $data[$key]; + if ($conf->socialnetworks->enabled && strpos($key, "socialnetworks") !== false) { + $tmp = explode("_", $key); + $key = $tmp[0]; + $socialnetwork = $tmp[1]; + $jsondata = $data[$key]; + $json = json_decode($jsondata); + $where[] = $key." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; + $filters[] = $col." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; + } else { + $where[] = $key.' = '.$data[$key]; + $filters[] = $col.' = '.$data[$key]; + } } $sqlSelect .= " WHERE " . implode(' AND ', $where); @@ -941,6 +944,13 @@ class ImportXlsx extends ModeleImports } if (!empty($lastinsertid)) { + // We db escape social network field because he isn't in field creation + if (in_array("socialnetworks", $listfields)) { + $socialkey = array_search("socialnetworks", $listfields); + $tmpsql = $listvalues[$socialkey]; + $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; + } + // Build SQL UPDATE request $sqlstart = "UPDATE " . $tablename; @@ -978,6 +988,13 @@ class ImportXlsx extends ModeleImports // Update not done, we do insert if (!$error && !$updatedone) { + // We db escape social network field because he isn't in field creation + if (in_array("socialnetworks", $listfields)) { + $socialkey = array_search("socialnetworks", $listfields); + $tmpsql = $listvalues[$socialkey]; + $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; + } + // Build SQL INSERT request $sqlstart = "INSERT INTO " . $tablename . "(" . implode(", ", $listfields) . ", import_key"; $sqlend = ") VALUES(" . implode(', ', $listvalues) . ", '" . $this->db->escape($importid) . "'"; diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index a6d9b95d19c..322988e7a7b 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -693,6 +693,15 @@ class modSociete extends DolibarrModules 's.code_compta' => 'CustomerAccountancyCode', 's.code_compta_fournisseur' => 'SupplierAccountancyCode' ); + if (!empty($conf->socialnetworks->enabled)) { + $sql = "SELECT code, label FROM ".MAIN_DB_PREFIX."c_socialnetworks WHERE active = 1"; + $resql = $this->db->query($sql); + while ($obj = $this->db->fetch_object($resql)) { + $fieldname = 's.socialnetworks_'.$obj->code; + $fieldlabel = ucfirst($obj->label); + $this->import_updatekeys_array[$r][$fieldname] = $fieldlabel; + } + } // Add profids as criteria to search duplicates $langs->load("companies"); $i=1; From adb37a5f5f7fe1962f27e4c9ebc5cdb5d6efb043 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 1 Jun 2022 09:53:51 +0000 Subject: [PATCH 114/128] Fixing style errors. --- htdocs/user/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index cc32cba558c..b7c30417a71 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -337,13 +337,13 @@ if (empty($reshook)) { if (GETPOST('password', 'none')) { $resPass = $object->setPassword($user, GETPOST('password', 'none')); } - if($resPass < 0) { + if ($resPass < 0) { $langs->load("errors"); $db->rollback(); setEventMessages($object->error, $object->errors, 'errors'); $action = "create"; // Go back to create page } else { - if(! empty($conf->categorie->enabled)) { + if (! empty($conf->categorie->enabled)) { // Categories association $usercats = GETPOST('usercats', 'array'); $object->setCategories($usercats); From 65913cdd150a42cac782c4b3e7998b93762e9181 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 12:51:40 +0200 Subject: [PATCH 115/128] Fix list of event empty. --- htdocs/comm/action/class/actioncomm.class.php | 3 +++ htdocs/comm/action/list.php | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index a406bb56463..48abc53a166 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -389,6 +389,9 @@ class ActionComm extends CommonObject const EVENT_FINISHED = 100; + public $fields = array(); + + /** * Constructor * diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index 34dd94664e7..f0a7e1febf8 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -642,7 +642,6 @@ $s = $newtitle; // Calendars from hooks $parameters = array(); -$object = null; $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); if (empty($reshook)) { $s .= $hookmanager->resPrint; @@ -687,7 +686,6 @@ $viewmode .= ''; // Add more views from hooks $parameters = array(); -$object = null; $reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action); if (empty($reshook)) { $viewmode .= $hookmanager->resPrint; From 2a3f0affafe39cd2c6037264bb96f9df0acd6bc3 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 1 Jun 2022 14:13:24 +0200 Subject: [PATCH 116/128] FIX : try for travis --- htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index 84e5b0caf41..74b0ea032b9 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -866,10 +866,10 @@ class pdf_eagle extends ModelePdfStockTransfer } /** - * Used to know if at least one line of Stock Transfer object has a batch set + * Used to know if at least one line of Stock Transfer object has a batch set  * - * @param Object $object Stock Transfer object - * @return boolean true if at least one line has batch set, false if not + * @param Object $object Stock Transfer object + * @return boolean true if at least one line has batch set, false if not  */ public function atLeastOneBatch($object) { From 67ac6b41f0f22f7cd01c92db7f67cdcc85919550 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Wed, 1 Jun 2022 15:07:14 +0200 Subject: [PATCH 117/128] Fix #21037 : select extrafield in knowledgerecord_list --- htdocs/knowledgemanagement/knowledgerecord_list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/knowledgemanagement/knowledgerecord_list.php b/htdocs/knowledgemanagement/knowledgerecord_list.php index c4440028e49..cd375c9db9c 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_list.php +++ b/htdocs/knowledgemanagement/knowledgerecord_list.php @@ -220,7 +220,7 @@ $sql .= $object->getFieldList('t'); // 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.', ' : ''); + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ",ef.".$key." as options_".$key : ''); } } // Add fields from hooks From 2a89e396fe3f24f431ec75d9f2f98377560fc81b Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Wed, 1 Jun 2022 15:17:19 +0200 Subject: [PATCH 118/128] Fix #20878 : improper use of dol_move --- htdocs/projet/class/task.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index c9cecd8dc6e..79152c6cfb9 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -481,7 +481,7 @@ class Task extends CommonObjectLine $newdir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->ref); if (file_exists($olddir)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $res = dol_move($olddir, $newdir); + $res = dol_move_dir($olddir, $newdir); if (!$res) { $langs->load("errors"); $this->error = $langs->trans('ErrorFailToRenameDir', $olddir, $newdir); From c3036d455a69cdadfd7f5ecc151eb5fb3402980d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 15:56:44 +0200 Subject: [PATCH 119/128] FIX #20902 --- htdocs/projet/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index c5fc08a6402..da45abb6168 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1275,7 +1275,7 @@ if ($action == 'create' && $user->rights->projet->creer) { // Close if ($object->statut == Project::STATUS_VALIDATED && $user->rights->projet->creer) { if ($userWrite > 0) { - print ''.$langs->trans("Close").''; + print ''.$langs->trans("Close").''; } else { print ''.$langs->trans('Close').''; } From 1ef66c208fad2260cb2a4814585d952dff8e5cf5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 19:34:29 +0200 Subject: [PATCH 120/128] Update card.php --- htdocs/user/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index b7c30417a71..f0b362b383e 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -333,7 +333,7 @@ if (empty($reshook)) { $id = $object->create($user); if ($id > 0) { - $resPass = ''; + $resPass = 0; if (GETPOST('password', 'none')) { $resPass = $object->setPassword($user, GETPOST('password', 'none')); } From 704266445c267e0484f46e8e7b923b7ffe8521f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 19:45:46 +0200 Subject: [PATCH 121/128] Debug v16 --- htdocs/langs/en_US/stocks.lang | 4 ++-- htdocs/product/stats/bom.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 5df6510c929..dbd15ec4da2 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -272,8 +272,8 @@ QtyWasAddedToTheScannedBarcode=Success !! The quantity was added to all the requ StockChangeDisabled=Change on stock disabled NoWarehouseDefinedForTerminal=No warehouse defined for terminal ClearQtys=Clear all quantities -ModuleStockTransferName=Stocks Transfer -ModuleStockTransferDesc=Creation of stocks transfer objects, with generation of transfer sheet +ModuleStockTransferName=Advanced Stock Transfer +ModuleStockTransferDesc=Advanced management of Stock Transfer, with generation of transfer sheet StockTransferNew=New stocks transfer StockTransferList=Stocks transfers list ConfirmValidateStockTransfer=Are you sure you want to validate this stocks transfer with reference %s ? diff --git a/htdocs/product/stats/bom.php b/htdocs/product/stats/bom.php index 1937b99b871..a8e76a178bf 100644 --- a/htdocs/product/stats/bom.php +++ b/htdocs/product/stats/bom.php @@ -199,7 +199,7 @@ if ($id > 0 || !empty($ref)) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."bom_bomline as bl ON bl.fk_bom=b.rowid"; $sql .= " WHERE b.entity IN (".getEntity('bom').")"; $sql .= " AND bl.fk_product = ".((int) $product->id); - $sql .= " GROUP BY b.rowid, b.ref, b.date_valid, b.status"; + $sql .= " GROUP BY b.rowid, b.ref, b.status, b.date_valid, b.fk_product"; $sql .= $db->order($sortfield, $sortorder); // Count total nb of records From a035449cc58251117f4279b46e91a4c7bcdf77e9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 19:53:13 +0200 Subject: [PATCH 122/128] Debug v16 --- htdocs/bom/bom_net_needs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/bom/bom_net_needs.php b/htdocs/bom/bom_net_needs.php index d08cce70382..baf4b096324 100644 --- a/htdocs/bom/bom_net_needs.php +++ b/htdocs/bom/bom_net_needs.php @@ -188,7 +188,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $viewlink = dolGetButtonTitle($langs->trans('GroupByProduct'), '', 'fa fa-bars imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&token='.newToken(), '', 1, array('morecss' => 'reposition '.($action !== 'treeview' ? 'btnTitleSelected':''))); $viewlink .= dolGetButtonTitle($langs->trans('TreeStructure'), '', 'fa fa-stream imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=treeview&token='.newToken(), '', 1, array('morecss' => 'reposition marginleftonly '.($action == 'treeview' ? 'btnTitleSelected':''))); - print load_fiche_titre($langs->trans("BillOfMaterials"), $viewlink, 'cubes'); + print load_fiche_titre($langs->trans("BOMNetNeeds"), $viewlink, ''); /* * Lines From 3751fc92caf57372c8d8d5563ea201e54d468ec5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 20:47:14 +0200 Subject: [PATCH 123/128] Clean code --- htdocs/bom/class/bom.class.php | 14 -------------- htdocs/comm/action/class/actioncomm.class.php | 6 ------ htdocs/comm/mailing/class/mailing.class.php | 7 ------- htdocs/compta/bank/class/paymentvarious.class.php | 7 ------- .../compta/cashcontrol/class/cashcontrol.class.php | 7 ------- .../prelevement/class/bonprelevement.class.php | 7 ------- htdocs/contact/class/contact.class.php | 7 ------- htdocs/societe/class/societe.class.php | 7 ------- htdocs/user/class/user.class.php | 7 ------- htdocs/user/class/usergroup.class.php | 7 ------- htdocs/zapier/class/hook.class.php | 7 ------- 11 files changed, 83 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 5d2c0f267de..640db9bc372 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -820,13 +820,6 @@ class BOM extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('bomdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1515,13 +1508,6 @@ class BOMLine extends CommonObjectLine } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('bomlinedao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 48abc53a166..31b9f04586e 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1629,12 +1629,6 @@ class ActionComm extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, '', 1).'"'; $linkclose .= ' class="'.$classname.' classfortooltip"'; - /* - $hookmanager->initHooks(array('actiondao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - $linkclose = ($hookmanager->resPrint ? $hookmanager->resPrint : $linkclose); - */ } else { $linkclose .= ' class="'.$classname.'"'; } diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index c944d9ab216..4ea794bfbd4 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -728,13 +728,6 @@ class Mailing extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('myobjectdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } diff --git a/htdocs/compta/bank/class/paymentvarious.class.php b/htdocs/compta/bank/class/paymentvarious.class.php index 77aded9c594..8bad5dbebd0 100644 --- a/htdocs/compta/bank/class/paymentvarious.class.php +++ b/htdocs/compta/bank/class/paymentvarious.class.php @@ -694,13 +694,6 @@ class PaymentVarious extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('myobjectdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } diff --git a/htdocs/compta/cashcontrol/class/cashcontrol.class.php b/htdocs/compta/cashcontrol/class/cashcontrol.class.php index 63dae3a3a1c..d7744f777fe 100644 --- a/htdocs/compta/cashcontrol/class/cashcontrol.class.php +++ b/htdocs/compta/cashcontrol/class/cashcontrol.class.php @@ -439,13 +439,6 @@ class CashControl extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('myobjectdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 8cde488a2e0..22a9a2bffc8 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1243,13 +1243,6 @@ class BonPrelevement extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('myobjectdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 922da9c30a8..9fa3602ee4b 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -1475,13 +1475,6 @@ class Contact extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('contactdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } $linkstart = 'initHooks(array('thirdpartydao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } $linkstart .= $linkclose.'>'; $linkend = ''; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index cb76b25cc5a..45610d7b8dc 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2805,13 +2805,6 @@ class User extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('userdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } $linkstart .= $linkclose.'>'; diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 5c83e8ce94c..41ac859f558 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -761,13 +761,6 @@ class UserGroup extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('groupdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } $linkstart = 'initHooks(array('hookdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } From b5197a07c1e5c52194e920c56b9c6e228d79ade6 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sun, 29 May 2022 19:44:07 +0200 Subject: [PATCH 124/128] Fix API knowledgemanagement --- htdocs/categories/class/categorie.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 5ffed2e5e4b..2dabe2893c0 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -37,6 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php'; /** From 169ebdef10d2d5047ae9178e9dd8e20f390fdc5e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 21:46:07 +0200 Subject: [PATCH 125/128] FIX #21051 --- htdocs/categories/class/categorie.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 2dabe2893c0..786af013dc6 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -186,7 +186,8 @@ class Categorie extends CommonObject 'contact' => 'socpeople', 'account' => 'bank_account', // old for bank account 'project' => 'projet', - 'warehouse'=> 'entrepot' + 'warehouse'=> 'entrepot', + 'knowledgemanagement' => 'knowledgemanagement_knowledgerecord' ); /** From 76da86112c03d38b97368429c14f060ba3b613c3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 21:46:42 +0200 Subject: [PATCH 126/128] Doc --- htdocs/categories/class/categorie.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 28320ecf41a..05b1822f45f 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -826,7 +826,7 @@ class Categorie extends CommonObject /** * Return list of fetched instance of elements having this category * - * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member', ...) + * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member', 'knowledge_management' ...) * @param int $onlyids Return only ids of objects (consume less memory) * @param int $limit Limit * @param int $offset Offset From 93499d611c874adf83165baae5c6189c214009f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 21:57:03 +0200 Subject: [PATCH 127/128] Update index.php --- htdocs/compta/stats/index.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index 8da07e6c860..b99002fe609 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -256,10 +256,10 @@ $sql .= " ORDER BY dm"; $minyearmonth = $maxyearmonth = 0; -$cum = Array(); -$cum_ht = Array(); -$total_ht = Array(); -$total = Array(); +$cum = array(); +$cum_ht = array(); +$total_ht = array(); +$total = array(); $result = $db->query($sql); if ($result) { From 958833484f976c0db991ec0e430ece483967ad2d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jun 2022 22:01:03 +0200 Subject: [PATCH 128/128] Fix bad var --- htdocs/core/class/html.formmail.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index fd0a7c7a63f..103c67081a8 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -1604,7 +1604,7 @@ class FormMail extends Form if ($conf->adherent->enabled) { $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember'; } - if ($conf->donation->enabled) { + if ($conf->don->enabled) { $tmparray['__SECUREKEYPAYMENT_DONATION__'] = 'SecureKeyPAYMENTUniquePerDonation'; } if ($conf->facture->enabled) { @@ -1621,7 +1621,7 @@ class FormMail extends Form if ($conf->adherent->enabled) { $tmparray['__ONLINEPAYMENTLINK_MEMBER__'] = 'OnlinePaymentLinkUniquePerMember'; } - if ($conf->donation->enabled) { + if ($conf->don->enabled) { $tmparray['__ONLINEPAYMENTLINK_DONATION__'] = 'OnlinePaymentLinkUniquePerDonation'; } if ($conf->facture->enabled) {