Add default workstation in service card

This commit is contained in:
atm-lena 2022-07-05 13:58:35 +02:00
parent 49e4a070dc
commit 4e1dc2792c
6 changed files with 192 additions and 2 deletions

View File

@ -648,4 +648,7 @@ ALTER TABLE llx_paiement MODIFY COLUMN ext_payment_id varchar(255);
ALTER TABLE llx_payment_donation MODIFY COLUMN ext_payment_id varchar(255);
ALTER TABLE llx_prelevement_facture_demande MODIFY COLUMN ext_payment_id varchar(255);
ALTER TABLE llx_product ADD COLUMN fk_default_workstation integer DEFAULT NULL;

View File

@ -107,4 +107,5 @@ create table llx_product
mandatory_period tinyint DEFAULT 0, -- is used to signal to the user that the start and end dates are mandatory for this type of product the fk_product_type == 1 (service) (non-blocking action)
fk_default_bom integer DEFAULT NULL
fk_default_workstation integer DEFAULT NULL
)ENGINE=innodb;

View File

@ -91,6 +91,7 @@ WorkstationSetup = Configuration du module Poste de travail
WorkstationSetupPage = Configuration du module Poste de travail
WorkstationList=Liste des postes de travail
WorkstationCreate=Ajouter un nouveau poste de travail
DefaultWorkstation=Poste de travail par défaut
ConfirmEnableWorkstation=Voulez-vous vraiment activer le poste de travail <b>%s</b>?
EnableAWorkstation=Activer le module Poste de travail
ConfirmDisableWorkstation=Voulez-vous vraiment désactiver la station de travail <b>%s</b>?

View File

@ -52,6 +52,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php';
require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php';
if (!empty($conf->propal->enabled)) {
require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
@ -552,6 +553,7 @@ if (empty($reshook)) {
$object->duration_value = $duration_value;
$object->duration_unit = $duration_unit;
$object->fk_default_warehouse = GETPOST('fk_default_warehouse');
$object->fk_default_workstation = GETPOST('fk_default_workstation');
$object->seuil_stock_alerte = GETPOST('seuil_stock_alerte') ?GETPOST('seuil_stock_alerte') : 0;
$object->desiredstock = GETPOST('desiredstock') ?GETPOST('desiredstock') : 0;
$object->canvas = GETPOST('canvas');
@ -704,6 +706,7 @@ if (empty($reshook)) {
$object->status_batch = GETPOST('status_batch', 'aZ09');
$object->batch_mask = GETPOST('batch_mask', 'alpha');
$object->fk_default_warehouse = GETPOST('fk_default_warehouse');
$object->fk_default_workstation = GETPOST('fk_default_workstation');
// removed from update view so GETPOST always empty
/*
$object->seuil_stock_alerte = GETPOST('seuil_stock_alerte');
@ -1996,6 +1999,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
print '</td></tr>';
*/
}
if($object->isService() && $conf->workstation->enabled) {
// Default workstation
print '<tr><td>'.$langs->trans("DefaultWorkstation").'</td><td>';
print img_picto($langs->trans("DefaultWorkstation"), 'workstation', 'class="pictofixedwidth"');
print $formproduct->selectWorkstations($object->fk_default_workstation, 'fk_default_workstation', 1);
print '</td></tr>';
}
/*
else
{
@ -2475,6 +2487,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
print '</td>';
}
if($object->isService() && $conf->workstation->enabled) {
$workstation = new Workstation($db);
$workstation->fetch($object->fk_default_workstation);
print '<tr><td>'.$langs->trans("DefaultWorkstation").'</td><td>';
print (!empty($workstation->id) ? $workstation->getNomUrl(1) : '');
print '</td>';
}
// Parent product.
if (!empty($conf->variants->enabled) && ($object->isProduct() || $object->isService())) {
$combination = new ProductCombination($db);

View File

@ -42,6 +42,7 @@ class FormProduct
// Cache arrays
public $cache_warehouses = array();
public $cache_lot = array();
public $cache_workstations = array();
/**
@ -172,6 +173,63 @@ class FormProduct
}
}
/**
* Load in cache array list of workstations
* If fk_product is not 0, we do not use cache
*
* @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0.
* @param array $exclude warehouses ids to exclude
* @param string $orderBy [='e.ref'] Order by
* @return int Nb of loaded lines, 0 if already loaded, <0 if KO
* @throws Exception
*/
public function loadWorkstations($fk_product = 0, $exclude = array(), $orderBy = 'w.ref')
{
global $conf, $langs;
if (empty($fk_product) && count($this->cache_workstations)) {
return 0; // Cache already loaded and we do not want a list with information specific to a product
}
$sql = "SELECT w.rowid, w.ref as label, w.type, w.nb_operators_required,w.thm_operator_estimated,w.thm_machine_estimated";
$sql .= " FROM ".$this->db->prefix()."workstation_workstation as w";
$sql .= " WHERE 1 = 1";
if (!empty($fk_product) && $fk_product > 0) {
$sql .= " AND w.fk_product = ".((int) $fk_product);
}
$sql .= " AND w.entity IN (".getEntity('workstation').")";
if (is_array($exclude) && !empty($exclude)) {
$sql .= ' AND w.rowid NOT IN('.$this->db->sanitize(implode(',', $exclude)).')';
}
$sql .= " ORDER BY ".$orderBy;
dol_syslog(get_class($this).'::loadWorkstations', LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
$i = 0;
while ($i < $num) {
$obj = $this->db->fetch_object($resql);
$this->cache_workstations[$obj->rowid]['id'] = $obj->rowid;
$this->cache_workstations[$obj->rowid]['ref'] = $obj->ref;
$this->cache_workstations[$obj->rowid]['label'] = $obj->label;
$this->cache_workstations[$obj->rowid]['type'] = $obj->type;
$this->cache_workstations[$obj->rowid]['nb_operators_required'] = $obj->nb_operators_required;
$this->cache_workstations[$obj->rowid]['thm_operator_estimated'] = $obj->thm_operator_estimated;
$this->cache_workstations[$obj->rowid]['thm_machine_estimated'] = $obj->thm_machine_estimated;
$i++;
}
return $num;
} else {
dol_print_error($this->db);
return -1;
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Return full path to current warehouse in $tab (recursive function)
@ -320,6 +378,105 @@ class FormProduct
return $out;
}
/**
* Return list of workstations
*
* @param string|int $selected Id of preselected warehouse ('' or '-1' for no value, 'ifone' and 'ifonenodefault' = select value if one value otherwise no value, '-2' to use the default value from setup)
* @param string $htmlname Name of html select html
* @param int $empty 1=Can be empty, 0 if not
* @param int $disabled 1=Select is disabled
* @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0.
* @param string $empty_label Empty label if needed (only if $empty=1)
* @param int $forcecombo 1=Force combo iso ajax select2
* @param array $events Events to add to select2
* @param string $morecss Add more css classes to HTML select
* @param array $exclude Warehouses ids to exclude
* @param int $showfullpath 1=Show full path of name (parent ref into label), 0=Show only ref of current warehouse
* @param string $orderBy [='e.ref'] Order by
* @return string HTML select
*
* @throws Exception
*/
public function selectWorkstations($selected = '', $htmlname = 'idworkstations', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label = '', $forcecombo = 0, $events = array(), $morecss = 'minwidth200', $exclude = array(), $showfullpath = 1, $orderBy = 'e.ref')
{
global $conf, $langs, $user, $hookmanager;
dol_syslog(get_class($this)."::selectWorkstations $selected, $htmlname, $empty, $disabled, $fk_product, $empty_label, $forcecombo, $morecss", LOG_DEBUG);
$out = '';
if (!empty($fk_product) && $fk_product > 0) {
$this->cache_workstations = array();
}
$this->loadWorkstations($fk_product);
$nbofworkstations = count($this->cache_workstations);
if ($conf->use_javascript_ajax && !$forcecombo) {
include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
$comboenhancement = ajax_combobox($htmlname, $events);
$out .= $comboenhancement;
}
if (strpos($htmlname, 'search_') !== 0) {
if (empty($user->fk_workstation) || $user->fk_workstation == -1) {
if (($selected == '-2' || $selected == 'ifone') && !empty($conf->global->MAIN_DEFAULT_WORKSTATION)) {
$selected = $conf->global->MAIN_DEFAULT_WORKSTATION;
}
} else {
if (($selected == '-2' || $selected == 'ifone') && !empty($conf->global->MAIN_DEFAULT_WORKSTATION)) {
$selected = $user->fk_workstation;
}
}
}
$out .= '<select class="flat'.($morecss ? ' '.$morecss : '').'"'.($disabled ? ' disabled' : '').' id="'.$htmlname.'" name="'.($htmlname.($disabled ? '_disabled' : '')).'">';
if ($empty) {
$out .= '<option value="-1">'.($empty_label ? $empty_label : '&nbsp;').'</option>';
}
foreach ($this->cache_workstations as $id => $arraytypes) {
$label = $arraytypes['label'];
$out .= '<option value="'.$id.'"';
if ($selected == $id || (preg_match('/^ifone/', $selected) && $nbofworkstations == 1)) {
$out .= ' selected';
}
$out .= ' data-html="'.dol_escape_htmltag($label).'"';
$out .= '>';
$out .= $label;
$out .= '</option>';
}
$out .= '</select>';
if ($disabled) {
$out .= '<input type="hidden" name="'.$htmlname.'" value="'.(($selected > 0) ? $selected : '').'">';
}
$parameters = array(
'selected' => $selected,
'htmlname' => $htmlname,
'filterstatus' => $filterstatus,
'empty' => $empty,
'disabled ' => $disabled,
'fk_product' => $fk_product,
'empty_label' => $empty_label,
'forcecombo' => $forcecombo,
'events' => $events,
'morecss' => $morecss,
'exclude' => $exclude,
'showfullpath' => $showfullpath,
'orderBy' => $orderBy
);
$reshook = $hookmanager->executeHooks('selectWorkstations', $parameters, $this);
if ($reshook > 0) {
$out = $hookmanager->resPrint;
} elseif ($reshook == 0) {
$out .= $hookmanager->resPrint;
}
return $out;
}
/**
* Display form to select warehouse
*

View File

@ -238,6 +238,11 @@ class Product extends CommonObject
*/
public $duration_value;
/*
* Service Workstation
*/
public $fk_default_workstation;
/**
* Exoiration unit
*/
@ -1147,6 +1152,7 @@ class Product extends CommonObject
$sql .= ", volume = ".($this->volume != '' ? "'".$this->db->escape($this->volume)."'" : 'null');
$sql .= ", volume_units = ".($this->volume_units != '' ? "'".$this->db->escape($this->volume_units)."'" : 'null');
$sql .= ", fk_default_warehouse = ".($this->fk_default_warehouse > 0 ? $this->db->escape($this->fk_default_warehouse) : 'null');
$sql .= ", fk_default_workstation = ".($this->fk_default_workstation > 0 ? $this->db->escape($this->fk_default_workstation) : 'null');
$sql .= ", seuil_stock_alerte = ".((isset($this->seuil_stock_alerte) && is_numeric($this->seuil_stock_alerte)) ? (float) $this->seuil_stock_alerte : 'null');
$sql .= ", description = '".$this->db->escape($this->description)."'";
$sql .= ", url = ".($this->url ? "'".$this->db->escape($this->url)."'" : 'null');
@ -2290,7 +2296,7 @@ class Product extends CommonObject
$sql = "SELECT p.rowid, p.ref, p.ref_ext, p.label, p.description, p.url, p.note_public, p.note as note_private, p.customcode, p.fk_country, p.fk_state, p.lifetime, p.qc_frequency, p.price, p.price_ttc,";
$sql .= " p.price_min, p.price_min_ttc, p.price_base_type, p.cost_price, p.default_vat_code, p.tva_tx, p.recuperableonly as tva_npr, p.localtax1_tx, p.localtax2_tx, p.localtax1_type, p.localtax2_type, p.tosell,";
$sql .= " p.tobuy, p.fk_product_type, p.duration, p.fk_default_warehouse, p.seuil_stock_alerte, p.canvas, p.net_measure, p.net_measure_units, p.weight, p.weight_units,";
$sql .= " p.tobuy, p.fk_product_type, p.duration, p.fk_default_warehouse, p.fk_default_workstation, p.seuil_stock_alerte, p.canvas, p.net_measure, p.net_measure_units, p.weight, p.weight_units,";
$sql .= " p.length, p.length_units, p.width, p.width_units, p.height, p.height_units,";
$sql .= " p.surface, p.surface_units, p.volume, p.volume_units, p.barcode, p.fk_barcode_type, p.finished, p.fk_default_bom, p.mandatory_period,";
if (empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
@ -2352,7 +2358,7 @@ class Product extends CommonObject
if ($separatedStock) {
$sql .= " GROUP BY p.rowid, p.ref, p.ref_ext, p.label, p.description, p.url, p.note_public, p.note, p.customcode, p.fk_country, p.fk_state, p.lifetime, p.qc_frequency, p.price, p.price_ttc,";
$sql .= " p.price_min, p.price_min_ttc, p.price_base_type, p.cost_price, p.default_vat_code, p.tva_tx, p.recuperableonly, p.localtax1_tx, p.localtax2_tx, p.localtax1_type, p.localtax2_type, p.tosell,";
$sql .= " p.tobuy, p.fk_product_type, p.duration, p.fk_default_warehouse, p.seuil_stock_alerte, p.canvas, p.net_measure, p.net_measure_units, p.weight, p.weight_units,";
$sql .= " p.tobuy, p.fk_product_type, p.duration, p.fk_default_warehouse, p.fk_default_workstation, p.seuil_stock_alerte, p.canvas, p.net_measure, p.net_measure_units, p.weight, p.weight_units,";
$sql .= " p.length, p.length_units, p.width, p.width_units, p.height, p.height_units,";
$sql .= " p.surface, p.surface_units, p.volume, p.volume_units, p.barcode, p.fk_barcode_type, p.finished,";
if (empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
@ -2451,6 +2457,7 @@ class Product extends CommonObject
$this->accountancy_code_sell_export = $obj->accountancy_code_sell_export;
$this->fk_default_warehouse = $obj->fk_default_warehouse;
$this->fk_default_workstation = $obj->fk_default_workstation;
$this->seuil_stock_alerte = $obj->seuil_stock_alerte;
$this->desiredstock = $obj->desiredstock;
$this->stock_reel = $obj->stock;