From f4e63bb0462fde1cc339f1ebd81d61ba6af211b9 Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Mon, 26 Oct 2020 10:52:22 +0100
Subject: [PATCH 01/74] NEW: ref in product customer price: add fields in
database
---
htdocs/install/mysql/migration/12.0.0-13.0.0.sql | 3 +++
htdocs/install/mysql/tables/llx_product_customer_price.sql | 3 ++-
htdocs/install/mysql/tables/llx_product_customer_price_log.sql | 3 ++-
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql
index a73ca40d86f..0a3b9379cbf 100644
--- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql
+++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql
@@ -423,6 +423,9 @@ ALTER TABLE llx_product MODIFY COLUMN finished tinyint DEFAULT NULL;
ALTER TABLE llx_product ADD CONSTRAINT fk_product_finished FOREIGN KEY (finished) REFERENCES llx_c_product_nature (code);
+ALTER TABLE llx_product_customer_price ADD COLUMN ref_customer varchar(30);
+ALTER TABLE llx_product_customer_price_log ADD COLUMN ref_customer varchar(30);
+
-- MIGRATION TO DO AFTER RENAMING AN OBJECT
-- drop constraint
diff --git a/htdocs/install/mysql/tables/llx_product_customer_price.sql b/htdocs/install/mysql/tables/llx_product_customer_price.sql
index 7cd481c3c75..f0d5edf9c2f 100644
--- a/htdocs/install/mysql/tables/llx_product_customer_price.sql
+++ b/htdocs/install/mysql/tables/llx_product_customer_price.sql
@@ -27,7 +27,8 @@ create table llx_product_customer_price
datec datetime,
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
fk_product integer NOT NULL,
- fk_soc integer NOT NULL,
+ fk_soc integer NOT NULL,
+ ref_customer varchar(30),
price double(24,8) DEFAULT 0,
price_ttc double(24,8) DEFAULT 0,
price_min double(24,8) DEFAULT 0,
diff --git a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql
index 4d79353e884..29906fe7ff2 100644
--- a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql
+++ b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql
@@ -26,7 +26,8 @@ create table llx_product_customer_price_log
entity integer DEFAULT 1 NOT NULL, -- multi company id
datec datetime,
fk_product integer NOT NULL,
- fk_soc integer DEFAULT 0 NOT NULL,
+ fk_soc integer DEFAULT 0 NOT NULL,
+ ref_customer varchar(30),
price double(24,8) DEFAULT 0,
price_ttc double(24,8) DEFAULT 0,
price_min double(24,8) DEFAULT 0,
From 721e931ba7119817694b77f36bd3388430f239c2 Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Mon, 26 Oct 2020 11:04:06 +0100
Subject: [PATCH 02/74] NEW: ref in product customer price: add field in CRUD
class
---
.../class/productcustomerprice.class.php | 33 +++++++++++++++++--
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php
index 25a3c5cd836..49386e8a379 100644
--- a/htdocs/product/class/productcustomerprice.class.php
+++ b/htdocs/product/class/productcustomerprice.class.php
@@ -54,7 +54,12 @@ class Productcustomerprice extends CommonObject
/**
* @var int Thirdparty ID
*/
- public $fk_soc;
+ public $fk_soc;
+
+ /**
+ * @var string Customer reference
+ */
+ public $ref_customer;
public $price;
public $price_ttc;
@@ -107,7 +112,9 @@ class Productcustomerprice extends CommonObject
if (isset($this->fk_product))
$this->fk_product = trim($this->fk_product);
if (isset($this->fk_soc))
- $this->fk_soc = trim($this->fk_soc);
+ $this->fk_soc = trim($this->fk_soc);
+ if (isset($this->ref_customer))
+ $this->ref_customer = trim($this->ref_customer);
if (isset($this->price))
$this->price = trim($this->price);
if (isset($this->price_ttc))
@@ -171,6 +178,7 @@ class Productcustomerprice extends CommonObject
$sql .= "datec,";
$sql .= "fk_product,";
$sql .= "fk_soc,";
+ $sql .= 'ref_customer,';
$sql .= "price,";
$sql .= "price_ttc,";
$sql .= "price_min,";
@@ -190,6 +198,7 @@ class Productcustomerprice extends CommonObject
$sql .= " '".$this->db->idate(dol_now())."',";
$sql .= " ".(!isset($this->fk_product) ? 'NULL' : "'".$this->db->escape($this->fk_product)."'").",";
$sql .= " ".(!isset($this->fk_soc) ? 'NULL' : "'".$this->db->escape($this->fk_soc)."'").",";
+ $sql .= " ".(!isset($this->ref_customer) ? 'NULL' : "'".$this->db->escape($this->ref_customer)."'").",";
$sql .= " ".(empty($this->price) ? '0' : "'".$this->db->escape($this->price)."'").",";
$sql .= " ".(empty($this->price_ttc) ? '0' : "'".$this->db->escape($this->price_ttc)."'").",";
$sql .= " ".(empty($this->price_min) ? '0' : "'".$this->db->escape($this->price_min)."'").",";
@@ -257,6 +266,7 @@ class Productcustomerprice extends CommonObject
$sql .= " t.tms,";
$sql .= " t.fk_product,";
$sql .= " t.fk_soc,";
+ $sql .= " t.ref_customer,";
$sql .= " t.price,";
$sql .= " t.price_ttc,";
$sql .= " t.price_min,";
@@ -286,6 +296,7 @@ class Productcustomerprice extends CommonObject
$this->tms = $this->db->jdate($obj->tms);
$this->fk_product = $obj->fk_product;
$this->fk_soc = $obj->fk_soc;
+ $this->ref_customer = $obj->ref_customer;
$this->price = $obj->price;
$this->price_ttc = $obj->price_ttc;
$this->price_min = $obj->price_min;
@@ -334,6 +345,7 @@ class Productcustomerprice extends CommonObject
$sql .= " t.tms,";
$sql .= " t.fk_product,";
$sql .= " t.fk_soc,";
+ $sql .= " t.ref_customer,";
$sql .= " t.price,";
$sql .= " t.price_ttc,";
$sql .= " t.price_min,";
@@ -393,6 +405,7 @@ class Productcustomerprice extends CommonObject
$line->tms = $this->db->jdate($obj->tms);
$line->fk_product = $obj->fk_product;
$line->fk_soc = $obj->fk_soc;
+ $line->ref_customer = $obj->ref_customer;
$line->price = $obj->price;
$line->price_ttc = $obj->price_ttc;
$line->price_min = $obj->price_min;
@@ -447,6 +460,7 @@ class Productcustomerprice extends CommonObject
$sql .= " t.datec,";
$sql .= " t.fk_product,";
$sql .= " t.fk_soc,";
+ $sql .= " t.ref_customer,";
$sql .= " t.price,";
$sql .= " t.price_ttc,";
$sql .= " t.price_min,";
@@ -502,6 +516,7 @@ class Productcustomerprice extends CommonObject
$line->tms = $this->db->jdate($obj->tms);
$line->fk_product = $obj->fk_product;
$line->fk_soc = $obj->fk_soc;
+ $line->ref_customer = $obj->ref_customer;
$line->price = $obj->price;
$line->price_ttc = $obj->price_ttc;
$line->price_min = $obj->price_min;
@@ -549,7 +564,9 @@ class Productcustomerprice extends CommonObject
if (isset($this->fk_product))
$this->fk_product = trim($this->fk_product);
if (isset($this->fk_soc))
- $this->fk_soc = trim($this->fk_soc);
+ $this->fk_soc = trim($this->fk_soc);
+ if (isset($this->ref_customer))
+ $this->ref_customer = trim($this->ref_customer);
if (isset($this->price))
$this->price = trim($this->price);
if (isset($this->price_ttc))
@@ -615,6 +632,7 @@ class Productcustomerprice extends CommonObject
$sql .= "datec,";
$sql .= "fk_product,";
$sql .= "fk_soc,";
+ $sql .= "ref_customer,";
$sql .= "price,";
$sql .= "price_ttc,";
$sql .= "price_min,";
@@ -637,6 +655,7 @@ class Productcustomerprice extends CommonObject
$sql .= " t.datec,";
$sql .= " t.fk_product,";
$sql .= " t.fk_soc,";
+ $sql .= " t.ref_customer,";
$sql .= " t.price,";
$sql .= " t.price_ttc,";
$sql .= " t.price_min,";
@@ -671,6 +690,7 @@ class Productcustomerprice extends CommonObject
$sql .= " tms=".(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
$sql .= " fk_product=".(isset($this->fk_product) ? $this->fk_product : "null").",";
$sql .= " fk_soc=".(isset($this->fk_soc) ? $this->fk_soc : "null").",";
+ $sql .= " ref_customer=".(isset($this->ref_customer) ? $this->ref_customer : "null").",";
$sql .= " price=".(isset($this->price) ? $this->price : "null").",";
$sql .= " price_ttc=".(isset($this->price_ttc) ? $this->price_ttc : "null").",";
$sql .= " price_min=".(isset($this->price_min) ? $this->price_min : "null").",";
@@ -790,6 +810,7 @@ class Productcustomerprice extends CommonObject
// If line do not exits then create it
$prodsocpricenew = new Productcustomerprice($this->db);
$prodsocpricenew->fk_soc = $obj->rowid;
+ $prodsocpricenew->ref_customer = $obj->ref_customer;
$prodsocpricenew->fk_product = $this->fk_product;
$prodsocpricenew->price = $this->price;
$prodsocpricenew->price_min = $this->price_min;
@@ -924,6 +945,7 @@ class Productcustomerprice extends CommonObject
$this->tms = '';
$this->fk_product = '';
$this->fk_soc = '';
+ $this->ref_customer = '';
$this->price = '';
$this->price_ttc = '';
$this->price_min = '';
@@ -962,6 +984,11 @@ class PriceByCustomerLine
*/
public $fk_product;
+ /**
+ * @var string Customer reference
+ */
+ public $ref_customer;
+
/**
* @var int Thirdparty ID
*/
From 6a3150028c74851ce256bb8fc8546cac1e2530e9 Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Mon, 26 Oct 2020 11:47:01 +0100
Subject: [PATCH 03/74] NEW: ref in product customer price: fix price update
SQL
---
htdocs/product/class/productcustomerprice.class.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php
index 49386e8a379..c18d09614e6 100644
--- a/htdocs/product/class/productcustomerprice.class.php
+++ b/htdocs/product/class/productcustomerprice.class.php
@@ -690,7 +690,7 @@ class Productcustomerprice extends CommonObject
$sql .= " tms=".(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
$sql .= " fk_product=".(isset($this->fk_product) ? $this->fk_product : "null").",";
$sql .= " fk_soc=".(isset($this->fk_soc) ? $this->fk_soc : "null").",";
- $sql .= " ref_customer=".(isset($this->ref_customer) ? $this->ref_customer : "null").",";
+ $sql .= " ref_customer=".(isset($this->ref_customer) ? "'" . $this->db->escape($this->ref_customer) . "'" : "null").",";
$sql .= " price=".(isset($this->price) ? $this->price : "null").",";
$sql .= " price_ttc=".(isset($this->price_ttc) ? $this->price_ttc : "null").",";
$sql .= " price_min=".(isset($this->price_min) ? $this->price_min : "null").",";
From c2518e92fbb26ce077cb33500965b6cc77528ea8 Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Mon, 26 Oct 2020 11:50:04 +0100
Subject: [PATCH 04/74] NEW: ref in product customer price: add field in views
---
htdocs/product/price.php | 9 ++++++---
htdocs/societe/price.php | 8 ++++++--
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/htdocs/product/price.php b/htdocs/product/price.php
index 8d10535ae31..2444fe6468d 100644
--- a/htdocs/product/price.php
+++ b/htdocs/product/price.php
@@ -1854,6 +1854,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES))
print '
| '.$langs->trans("VATRate").' | ';
print $form->load_tva("tva_tx", $prodcustprice->tva_tx, $mysoc, '', $staticprod->id, $prodcustprice->recuperableonly);
From bb850ad0d083e8cc76eeb997acd29dc8779cab31 Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Mon, 26 Oct 2020 13:05:07 +0100
Subject: [PATCH 06/74] NEW: ref in product customer price: add ref in PDFs +
hidden conf to choose refs to show
---
htdocs/core/lib/pdf.lib.php | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 0ff40659daa..9889e3ff220 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -1237,6 +1237,10 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0,
} else {
include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
$prodser = new Product($db);
+
+ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
+ include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+ }
}
if ($idprod)
@@ -1364,6 +1368,32 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0,
}
} else {
$ref_prodserv = $prodser->ref; // Show local ref only
+
+ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
+ $productCustomerPriceStatic = new Productcustomerprice($db);
+ $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
+
+ $nbCustomerPrices = $productCustomerPriceStatic->fetch_all('', '', 1, 0, $filter);
+
+ if ($nbCustomerPrices > 0) {
+ $productCustomerPrice = $productCustomerPriceStatic->lines[0];
+
+ if (! empty($productCustomerPrice->ref_customer)) {
+ switch($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
+ case 1:
+ $ref_prodserv = $productCustomerPrice->ref_customer;
+ break;
+
+ case 2:
+ $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
+ break;
+
+ default:
+ $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
+ }
+ }
+ }
+ }
}
if (!empty($libelleproduitservice) && !empty($ref_prodserv)) $ref_prodserv .= " - ";
From 79ba133a07d5f691fac0ef00f94af5559ac233aa Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Mon, 26 Oct 2020 13:05:26 +0100
Subject: [PATCH 07/74] NEW: ref in product customer price: fix missing
language key
---
htdocs/langs/en_US/main.lang | 1 +
1 file changed, 1 insertion(+)
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 1096b9857f1..84d399ddde2 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -646,6 +646,7 @@ SupplierPreview=Vendor preview
ShowCustomerPreview=Show customer preview
ShowSupplierPreview=Show vendor preview
RefCustomer=Ref. customer
+InternalRef=Internal ref.
Currency=Currency
InfoAdmin=Information for administrators
Undo=Undo
From 541dab57371e5b8517bc77f527262bc777b178ea Mon Sep 17 00:00:00 2001
From: stickler-ci
Date: Mon, 26 Oct 2020 13:40:05 +0000
Subject: [PATCH 08/74] Fixing style errors.
---
htdocs/core/lib/pdf.lib.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 9889e3ff220..6d0b3023964 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -1379,7 +1379,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0,
$productCustomerPrice = $productCustomerPriceStatic->lines[0];
if (! empty($productCustomerPrice->ref_customer)) {
- switch($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
+ switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
case 1:
$ref_prodserv = $productCustomerPrice->ref_customer;
break;
From ca2ed2ef74d94d7808154ee8e41cf0f4ec290891 Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Wed, 28 Oct 2020 11:04:15 +0100
Subject: [PATCH 09/74] NEW: ref in product customer price: look for products
with customer ref
---
htdocs/core/class/html.form.class.php | 10 +++++++---
htdocs/core/lib/ajax.lib.php | 3 ++-
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index bf52ff5871a..59f98e626a9 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -2137,8 +2137,8 @@ class Form
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid))
{
$sql .= ', pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
- $sql .= ' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
- $selectFields .= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx";
+ $sql .= ' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx, pcp.ref_customer as custref';
+ $selectFields .= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx, custref";
}
// Units
if (!empty($conf->global->PRODUCT_USE_UNITS)) {
@@ -2235,6 +2235,7 @@ class Form
if ($i > 0) $sql .= " AND ";
$sql .= "(p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%'";
if (!empty($conf->global->MAIN_MULTILANGS)) $sql .= " OR pl.label LIKE '".$this->db->escape($prefix.$crit)."%'";
+ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && ! empty($socid)) $sql .= " OR pcp.ref_customer LIKE '".$this->db->escape($prefix.$crit)."%'";
if (!empty($conf->global->PRODUCT_AJAX_SEARCH_ON_DESCRIPTION))
{
$sql .= " OR p.description LIKE '".$this->db->escape($prefix.$crit)."%'";
@@ -2422,6 +2423,7 @@ class Form
$outkey = $objp->rowid;
$outref = $objp->ref;
+ $outrefcust = empty($objp->custref) ? '' : $objp->custref;
$outlabel = $objp->label;
$outdesc = $objp->description;
$outbarcode = $objp->barcode;
@@ -2487,11 +2489,13 @@ class Form
}
$opt .= '>';
$opt .= $objp->ref;
+ if (! empty($objp->custref)) $opt.= ' (' . $objp->custref . ')';
if ($outbarcode) $opt .= ' ('.$outbarcode.')';
$opt .= ' - '.dol_trunc($label, $maxlengtharticle);
if ($outorigin && !empty($conf->global->PRODUCT_SHOW_ORIGIN_IN_COMBO)) $opt .= ' ('.getCountry($outorigin, 1).')';
$objRef = $objp->ref;
+ if (! empty($objp->custref)) $objRef .= ' (' . $objp->custref . ')';
if (!empty($filterkey) && $filterkey != '') $objRef = preg_replace('/('.preg_quote($filterkey, '/').')/i', '$1', $objRef, 1);
$outval .= $objRef;
if ($outbarcode) $outval .= ' ('.$outbarcode.')';
@@ -2655,7 +2659,7 @@ class Form
}
$opt .= "\n";
- $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>price2num($outprice_ht), 'price_ttc'=>price2num($outprice_ttc), 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'pbq'=>$outpbq);
+ $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>price2num($outprice_ht), 'price_ttc'=>price2num($outprice_ttc), 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'pbq'=>$outpbq, 'ref_customer'=>$outrefcust);
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
index 10fa477600a..0c7a8ecc312 100644
--- a/htdocs/core/lib/ajax.lib.php
+++ b/htdocs/core/lib/ajax.lib.php
@@ -134,7 +134,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
}
return { label: label, value: item.value, id: item.key, disabled: item.disabled,
update: update, textarea: textarea,
- pbq: item.pbq, type: item.type, qty: item.qty, discount: item.discount, pricebasetype: item.pricebasetype, price_ht: item.price_ht, price_ttc: item.price_ttc }
+ pbq: item.pbq, type: item.type, qty: item.qty, discount: item.discount, pricebasetype: item.pricebasetype, price_ht: item.price_ht, price_ttc: item.price_ttc, ref_customer: item.ref_customer }
}));
}
else console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
@@ -152,6 +152,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
$("#'.$htmlname.'").attr("data-pbqbase", ui.item.pricebasetype);
$("#'.$htmlname.'").attr("data-pbqqty", ui.item.qty);
$("#'.$htmlname.'").attr("data-pbqpercent", ui.item.discount);
+ $("#'.$htmlname.'").attr("data-ref-customer", ui.item.ref_customer);
$("#'.$htmlname.'").val(ui.item.id).trigger("change"); // Select new value
// Disable an element
From 7b739920a24aadfcf60bcec56e95a853fa812aa1 Mon Sep 17 00:00:00 2001
From: Gauthier PC portable 024
Date: Thu, 17 Dec 2020 13:18:40 +0100
Subject: [PATCH 10/74] NEW : Workstations management
---
htdocs/admin/workstation.php | 513 ++++++++
htdocs/core/modules/modWorkstation.class.php | 522 ++++++++
.../workstation/mod_workstation_advanced.php | 150 +++
.../workstation/mod_workstation_standard.php | 151 +++
.../workstation/modules_workstation.php | 150 +++
htdocs/core/tpl/commonfields_add.tpl.php | 1 +
htdocs/core/tpl/commonfields_edit.tpl.php | 1 +
.../install/mysql/migration/13.0.0-14.0.0.sql | 40 +
.../llx_workstation_workstation.key.sql | 27 +
.../tables/llx_workstation_workstation.sql | 36 +
.../llx_workstation_workstation_resource.sql | 22 +
...llx_workstation_workstation_user_group.sql | 22 +
htdocs/langs/en_US/mrp.lang | 26 +-
.../class/html.formresource.class.php | 8 +-
.../workstation/class/workstation.class.php | 1054 +++++++++++++++++
.../class/workstation.class.php.back | 1052 ++++++++++++++++
.../class/workstationresource.class.php | 82 ++
.../class/workstationusergroup.class.php | 82 ++
htdocs/workstation/lib/workstation.lib.php | 65 +
.../lib/workstation_workstation.lib.php | 85 ++
htdocs/workstation/workstation_agenda.php | 276 +++++
htdocs/workstation/workstation_card.php | 511 ++++++++
htdocs/workstation/workstation_document.php | 228 ++++
htdocs/workstation/workstation_list.php | 601 ++++++++++
htdocs/workstation/workstation_note.php | 183 +++
25 files changed, 5884 insertions(+), 4 deletions(-)
create mode 100755 htdocs/admin/workstation.php
create mode 100755 htdocs/core/modules/modWorkstation.class.php
create mode 100755 htdocs/core/modules/workstation/mod_workstation_advanced.php
create mode 100755 htdocs/core/modules/workstation/mod_workstation_standard.php
create mode 100755 htdocs/core/modules/workstation/modules_workstation.php
create mode 100644 htdocs/install/mysql/migration/13.0.0-14.0.0.sql
create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation.key.sql
create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation.sql
create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql
create mode 100755 htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql
create mode 100755 htdocs/workstation/class/workstation.class.php
create mode 100755 htdocs/workstation/class/workstation.class.php.back
create mode 100644 htdocs/workstation/class/workstationresource.class.php
create mode 100644 htdocs/workstation/class/workstationusergroup.class.php
create mode 100755 htdocs/workstation/lib/workstation.lib.php
create mode 100755 htdocs/workstation/lib/workstation_workstation.lib.php
create mode 100755 htdocs/workstation/workstation_agenda.php
create mode 100755 htdocs/workstation/workstation_card.php
create mode 100755 htdocs/workstation/workstation_document.php
create mode 100755 htdocs/workstation/workstation_list.php
create mode 100755 htdocs/workstation/workstation_note.php
diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php
new file mode 100755
index 00000000000..8f9ee369d4f
--- /dev/null
+++ b/htdocs/admin/workstation.php
@@ -0,0 +1,513 @@
+
+ * Copyright (C) 2020 SuperAdmin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file workstation/admin/setup.php
+ * \ingroup workstation
+ * \brief Workstation setup page.
+ */
+
+// Load Dolibarr environment
+require "../main.inc.php";
+
+// Libraries
+require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
+require_once DOL_DOCUMENT_ROOT . '/workstation/lib/workstation.lib.php';
+//require_once "../class/myclass.class.php";
+
+// Translations
+$langs->loadLangs(array("admin", "workstation@workstation"));
+
+// Access control
+if (!$user->admin) accessforbidden();
+
+// Parameters
+$action = GETPOST('action', 'aZ09');
+$backtopage = GETPOST('backtopage', 'alpha');
+
+$value = GETPOST('value', 'alpha');
+
+/*$arrayofparameters = array(
+ 'WORKSTATION_MYPARAM1'=>array('css'=>'minwidth200', 'enabled'=>1),
+ 'WORKSTATION_MYPARAM2'=>array('css'=>'minwidth500', 'enabled'=>1)
+);*/
+
+$error = 0;
+$setupnotempty = 0;
+
+
+/*
+ * Actions
+ */
+
+if ((float) DOL_VERSION >= 6)
+{
+ include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
+}
+
+if ($action == 'updateMask')
+{
+ $maskconstorder = GETPOST('maskconstWorkstation', 'alpha');
+ $maskorder = GETPOST('maskWorkstation', 'alpha');
+
+ if ($maskconstorder) $res = dolibarr_set_const($db, $maskconstorder, $maskorder, 'chaine', 0, '', $conf->entity);
+
+ if (!$res > 0) $error++;
+
+ if (!$error)
+ {
+ setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+ } else {
+ setEventMessages($langs->trans("Error"), null, 'errors');
+ }
+} elseif ($action == 'specimen')
+{
+ $modele = GETPOST('module', 'alpha');
+ $tmpobjectkey = GETPOST('object');
+
+ $tmpobject = new $tmpobjectkey($db);
+ $tmpobject->initAsSpecimen();
+
+ // Search template files
+ $file = ''; $classname = ''; $filefound = 0;
+ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+ foreach ($dirmodels as $reldir)
+ {
+ $file = dol_buildpath($reldir."core/modules/workstation/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0);
+ if (file_exists($file))
+ {
+ $filefound = 1;
+ $classname = "pdf_".$modele;
+ break;
+ }
+ }
+
+ if ($filefound)
+ {
+ require_once $file;
+
+ $module = new $classname($db);
+
+ if ($module->write_file($tmpobject, $langs) > 0)
+ {
+ header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf");
+ return;
+ } else {
+ setEventMessages($module->error, null, 'errors');
+ dol_syslog($module->error, LOG_ERR);
+ }
+ } else {
+ setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
+ dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
+ }
+}
+
+// Activate a model
+elseif ($action == 'set')
+{
+ $ret = addDocumentModel($value, $type, $label, $scandir);
+} elseif ($action == 'del')
+{
+ $tmpobjectkey = GETPOST('object');
+
+ $ret = delDocumentModel($value, $type);
+ if ($ret > 0)
+ {
+ $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF';
+ if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity);
+ }
+}
+
+// Set default model
+elseif ($action == 'setdoc')
+{
+ $tmpobjectkey = GETPOST('object');
+ $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF';
+ if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity))
+ {
+ // The constant that was read before the new set
+ // We therefore requires a variable to have a coherent view
+ $conf->global->$constforval = $value;
+ }
+
+ // On active le modele
+ $ret = delDocumentModel($value, $type);
+ if ($ret > 0)
+ {
+ $ret = addDocumentModel($value, $type, $label, $scandir);
+ }
+} elseif ($action == 'setmod')
+{
+ // TODO Check if numbering module chosen can be activated
+ // by calling method canBeActivated
+ $tmpobjectkey = GETPOST('object');
+ $constforval = 'WORKSTATION_'.strtoupper($tmpobjectkey)."_ADDON";
+ dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity);
+}
+
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+
+$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
+$page_name = "WorkstationSetup";
+llxHeader('', $langs->trans($page_name));
+
+// Subheader
+$linkback = ''.$langs->trans("BackToModuleList").'';
+
+print load_fiche_titre($langs->trans($page_name), $linkback, 'object_workstation@workstation');
+
+// Configuration header
+$head = workstationAdminPrepareHead();
+print dol_get_fiche_head($head, 'settings', '', -1, "workstation@workstation");
+
+// Setup page goes here
+//echo ''.$langs->trans("WorkstationSetupPage").'
';
+
+
+if ($action == 'edit')
+{
+ print '';
+ print ' ';
+} else {
+ if (!empty($arrayofparameters))
+ {
+ print '';
+ print '| '.$langs->trans("Parameter").' | '.$langs->trans("Value").' | ';
+
+ foreach ($arrayofparameters as $key => $val)
+ {
+ $setupnotempty++;
+
+ print '| ';
+ $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
+ print $form->textwithpicto($langs->trans($key), $tooltiphelp);
+ print ' | '.$conf->global->$key.' | ';
+ }
+
+ print ' ';
+
+ print '';
+ }/* else {
+ print ' '.$langs->trans("NothingToSetup");
+ }*/
+}
+
+
+$moduledir = 'workstation';
+$myTmpObjects = array();
+$myTmpObjects['workstation'] = array('includerefgeneration'=>1, 'includedocgeneration'=>0);
+
+
+foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
+ if ($myTmpObjectKey == 'MyObject') continue;
+ if ($myTmpObjectArray['includerefgeneration']) {
+ /*
+ * Orders Numbering model
+ */
+ $setupnotempty++;
+
+ print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', '');
+
+ print '';
+ print '';
+ print '| '.$langs->trans("Name").' | ';
+ print ''.$langs->trans("Description").' | ';
+ print ''.$langs->trans("Example").' | ';
+ print ''.$langs->trans("Status").' | ';
+ print ''.$langs->trans("ShortInfo").' | ';
+ 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 '| '.$module->name." | \n";
+ print $module->info();
+ print ' | ';
+
+ // Show example of numbering model
+ print '';
+ $tmp = $module->getExample();
+ if (preg_match('/^Error/', $tmp)) {
+ $langs->load("errors");
+ print ' '.$langs->trans($tmp).' ';
+ } elseif ($tmp == 'NotConfigured') print $langs->trans($tmp);
+ else print $tmp;
+ print ' | '."\n";
+
+ print '';
+ $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON';
+ if ($conf->global->$constforvar == $file)
+ {
+ print img_picto($langs->trans("Activated"), 'switch_on');
+ } else {
+ print '';
+ print img_picto($langs->trans("Disabled"), 'switch_off');
+ print '';
+ }
+ print ' | ';
+
+ $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 $form->textwithpicto('', $htmltooltip, 1, 0);
+ print ' | ';
+
+ print " \n";
+ }
+ }
+ }
+ closedir($handle);
+ }
+ }
+ }
+ print " \n";
+ }
+
+ if ($myTmpObjectArray['includedocgeneration']) {
+ /*
+ * Document templates generators
+ */
+ $setupnotempty++;
+ $type = strtolower($myTmpObjectKey);
+
+ print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', '');
+
+ // Load array def with activated templates
+ $def = array();
+ $sql = "SELECT nom";
+ $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
+ $sql .= " WHERE type = '".$db->escape($type)."'";
+ $sql .= " AND entity = ".$conf->entity;
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $i = 0;
+ $num_rows = $db->num_rows($resql);
+ while ($i < $num_rows)
+ {
+ $array = $db->fetch_array($resql);
+ array_push($def, $array[0]);
+ $i++;
+ }
+ } else {
+ dol_print_error($db);
+ }
+
+ print "\n";
+ print "\n";
+ print '| '.$langs->trans("Name").' | ';
+ print ''.$langs->trans("Description").' | ';
+ print ''.$langs->trans("Status")." | \n";
+ print ''.$langs->trans("Default")." | \n";
+ print ''.$langs->trans("ShortInfo").' | ';
+ print ''.$langs->trans("Preview").' | ';
+ 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 '| ';
+ print (empty($module->name) ? $name : $module->name);
+ print " | \n";
+ if (method_exists($module, 'info')) print $module->info($langs);
+ else print $module->description;
+ print ' | ';
+
+ // Active
+ if (in_array($name, $def))
+ {
+ print ''."\n";
+ print '';
+ print img_picto($langs->trans("Enabled"), 'switch_on');
+ print '';
+ print ' | ';
+ } else {
+ print ''."\n";
+ print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'';
+ print " | ";
+ }
+
+ // Default
+ print '';
+ $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON';
+ if ($conf->global->$constforvar == $name)
+ {
+ print img_picto($langs->trans("Default"), 'on');
+ } else {
+ print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'';
+ }
+ print ' | ';
+
+ // 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 '';
+ print $form->textwithpicto('', $htmltooltip, 1, 0);
+ print ' | ';
+
+ // Preview
+ print '';
+ if ($module->type == 'pdf')
+ {
+ print ''.img_object($langs->trans("Preview"), 'generic').'';
+ } else {
+ print img_object($langs->trans("PreviewNotAvailable"), 'generic');
+ }
+ print ' | ';
+
+ print " \n";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ print ' ';
+ }
+}
+
+/*if (empty($setupnotempty)) {
+ print ' '.$langs->trans("NothingToSetup");
+}*/
+
+// Page end
+print dol_get_fiche_end();
+
+llxFooter();
+$db->close();
diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php
new file mode 100755
index 00000000000..216d591670a
--- /dev/null
+++ b/htdocs/core/modules/modWorkstation.class.php
@@ -0,0 +1,522 @@
+
+ * Copyright (C) 2018-2019 Nicolas ZABOURI
+ * Copyright (C) 2019-2020 Frédéric France
+ * Copyright (C) 2020 SuperAdmin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \defgroup workstation Module Workstation
+ * \brief Workstation module descriptor.
+ *
+ * \file htdocs/workstation/core/modules/modWorkstation.class.php
+ * \ingroup workstation
+ * \brief Description and activation file for module Workstation
+ */
+include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
+
+/**
+ * Description and activation class for module Workstation
+ */
+class modWorkstation extends DolibarrModules
+{
+ /**
+ * Constructor. Define names, constants, directories, boxes, permissions
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $langs, $conf;
+ $this->db = $db;
+
+ // Id for module (must be unique).
+ // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
+ $this->numero = 500000; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve an id number for your module
+ // Key text used to identify module (for permissions, menus, etc...)
+ $this->rights_class = 'workstation';
+ // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
+ // It is used to group modules by family in module setup page
+ $this->family = "other";
+ // Module position in the family on 2 digits ('01', '10', '20', ...)
+ $this->module_position = '90';
+ // Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
+ //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
+ // Module label (no space allowed), used if translation string 'ModuleWorkstationName' not found (Workstation is name of module).
+ $this->name = preg_replace('/^mod/i', '', get_class($this));
+ // Module description, used if translation string 'ModuleWorkstationDesc' not found (Workstation is name of module).
+ $this->description = "WorkstationsDescription";
+ // Used only if file README.md and README-LL.md not found.
+ $this->descriptionlong = "Workstation description (Long)";
+ $this->editor_name = 'Editor name';
+ $this->editor_url = 'https://www.example.com';
+ // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
+ $this->version = '1.0';
+ // Url to the file with your last numberversion of this module
+ //$this->url_last_version = 'http://www.example.com/versionmodule.txt';
+
+ // Key used in llx_const table to save module status enabled/disabled (where WORKSTATION is value of property name of module in uppercase)
+ $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
+ // Name of image file used for this module.
+ // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
+ // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
+ $this->picto = 'mrp';
+ // Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
+ $this->module_parts = array(
+ // Set this to 1 if module has its own trigger directory (core/triggers)
+ 'triggers' => 0,
+ // Set this to 1 if module has its own login method file (core/login)
+ 'login' => 0,
+ // Set this to 1 if module has its own substitution function file (core/substitutions)
+ 'substitutions' => 0,
+ // Set this to 1 if module has its own menus handler directory (core/menus)
+ 'menus' => 0,
+ // Set this to 1 if module overwrite template dir (core/tpl)
+ 'tpl' => 0,
+ // Set this to 1 if module has its own barcode directory (core/modules/barcode)
+ 'barcode' => 0,
+ // Set this to 1 if module has its own models directory (core/modules/xxx)
+ 'models' => 1,
+ // Set this to 1 if module has its own printing directory (core/modules/printing)
+ 'printing' => 0,
+ // Set this to 1 if module has its own theme directory (theme)
+ 'theme' => 0,
+ // Set this to relative path of css file if module has its own css file
+ 'css' => array(
+ // '/workstation/css/workstation.css.php',
+ ),
+ // Set this to relative path of js file if module must load a js on all pages
+ 'js' => array(
+ // '/workstation/js/workstation.js.php',
+ ),
+ // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context to 'all'
+ 'hooks' => array(
+ // 'data' => array(
+ // 'hookcontext1',
+ // 'hookcontext2',
+ // ),
+ // 'entity' => '0',
+ ),
+ // Set this to 1 if features of module are opened to external users
+ 'moduleforexternal' => 0,
+ );
+ // Data directories to create when module is enabled.
+ // Example: this->dirs = array("/workstation/temp","/workstation/subdir");
+ $this->dirs = array("/workstation/temp");
+ // Config pages. Put here list of php page, stored into workstation/admin directory, to use to setup module.
+ $this->config_page_url = array("workstation.php");
+ // Dependencies
+ // A condition to hide module
+ $this->hidden = false;
+ // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...)
+ $this->depends = array();
+ $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
+ $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...)
+ $this->langfiles = array("mrp");
+ $this->phpmin = array(5, 5); // Minimum version of PHP required by module
+ $this->need_dolibarr_version = array(11, -3); // Minimum version of Dolibarr required by module
+ $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
+ $this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
+ //$this->automatic_activation = array('FR'=>'WorkstationWasAutomaticallyActivatedBecauseOfYourCountryChoice');
+ //$this->always_enabled = true; // If true, can't be disabled
+
+ // Constants
+ // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
+ // Example: $this->const=array(1 => array('WORKSTATION_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1),
+ // 2 => array('WORKSTATION_MYNEWCONST2', 'chaine', 'myvalue', 'This is another constant to add', 0, 'current', 1)
+ // );
+ $this->const = array();
+
+ // Some keys to add into the overwriting translation tables
+ /*$this->overwrite_translation = array(
+ 'en_US:ParentCompany'=>'Parent company or reseller',
+ 'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
+ )*/
+
+ if (!isset($conf->workstation) || !isset($conf->workstation->enabled)) {
+ $conf->workstation = new stdClass();
+ $conf->workstation->enabled = 0;
+ }
+
+ // Array to add new pages in new tabs
+ $this->tabs = array();
+ // Example:
+ // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@workstation:$user->rights->workstation->read:/workstation/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1
+ // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@workstation:$user->rights->othermodule->read:/workstation/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
+ // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname
+ //
+ // Where objecttype can be
+ // 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
+ // 'contact' to add a tab in contact view
+ // 'contract' to add a tab in contract view
+ // 'group' to add a tab in group view
+ // 'intervention' to add a tab in intervention view
+ // 'invoice' to add a tab in customer invoice view
+ // 'invoice_supplier' to add a tab in supplier invoice view
+ // 'member' to add a tab in fundation member view
+ // 'opensurveypoll' to add a tab in opensurvey poll view
+ // 'order' to add a tab in customer order view
+ // 'order_supplier' to add a tab in supplier order view
+ // 'payment' to add a tab in payment view
+ // 'payment_supplier' to add a tab in supplier payment view
+ // 'product' to add a tab in product view
+ // 'propal' to add a tab in propal view
+ // 'project' to add a tab in project view
+ // 'stock' to add a tab in stock view
+ // 'thirdparty' to add a tab in third party view
+ // 'user' to add a tab in user view
+
+ // Dictionaries
+ $this->dictionaries = array();
+ /* Example:
+ $this->dictionaries=array(
+ 'langs'=>'workstation@workstation',
+ // List of tables we want to see into dictonnary editor
+ 'tabname'=>array(MAIN_DB_PREFIX."table1", MAIN_DB_PREFIX."table2", MAIN_DB_PREFIX."table3"),
+ // Label of tables
+ 'tablib'=>array("Table1", "Table2", "Table3"),
+ // Request to select fields
+ 'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),
+ // Sort order
+ 'tabsqlsort'=>array("label ASC", "label ASC", "label ASC"),
+ // List of fields (result of select to show dictionary)
+ 'tabfield'=>array("code,label", "code,label", "code,label"),
+ // List of fields (list of fields to edit a record)
+ 'tabfieldvalue'=>array("code,label", "code,label", "code,label"),
+ // List of fields (list of fields for insert)
+ 'tabfieldinsert'=>array("code,label", "code,label", "code,label"),
+ // Name of columns with primary key (try to always name it 'rowid')
+ 'tabrowid'=>array("rowid", "rowid", "rowid"),
+ // Condition to show each dictionary
+ 'tabcond'=>array($conf->workstation->enabled, $conf->workstation->enabled, $conf->workstation->enabled)
+ );
+ */
+
+ // Boxes/Widgets
+ // Add here list of php file(s) stored in workstation/core/boxes that contains a class to show a widget.
+ $this->boxes = array(
+ // 0 => array(
+ // 'file' => 'workstationwidget1.php@workstation',
+ // 'note' => 'Widget provided by Workstation',
+ // 'enabledbydefaulton' => 'Home',
+ // ),
+ // ...
+ );
+
+ // Cronjobs (List of cron jobs entries to add when module is enabled)
+ // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
+ $this->cronjobs = array(
+ // 0 => array(
+ // 'label' => 'MyJob label',
+ // 'jobtype' => 'method',
+ // 'class' => '/workstation/class/workstation.class.php',
+ // 'objectname' => 'Workstation',
+ // 'method' => 'doScheduledJob',
+ // 'parameters' => '',
+ // 'comment' => 'Comment',
+ // 'frequency' => 2,
+ // 'unitfrequency' => 3600,
+ // 'status' => 0,
+ // 'test' => '$conf->workstation->enabled',
+ // 'priority' => 50,
+ // ),
+ );
+ // Example: $this->cronjobs=array(
+ // 0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->workstation->enabled', 'priority'=>50),
+ // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->workstation->enabled', 'priority'=>50)
+ // );
+
+ // Permissions provided by this module
+ $this->rights = array();
+ $r = 0;
+ // Add here entries to declare new permissions
+ /* BEGIN MODULEBUILDER PERMISSIONS */
+ $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
+ $this->rights[$r][1] = 'Read objects of Workstation'; // Permission label
+ $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $r++;
+ $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
+ $this->rights[$r][1] = 'Create/Update objects of Workstation'; // Permission label
+ $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $r++;
+ $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
+ $this->rights[$r][1] = 'Delete objects of Workstation'; // Permission label
+ $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $r++;
+ /* END MODULEBUILDER PERMISSIONS */
+
+ // Main menu entries to add
+ $this->menu = array();
+ $r = 0;
+ // Add here entries to declare new menus
+ /* BEGIN MODULEBUILDER TOPMENU */
+ /*$this->menu[$r++] = array(
+ 'fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'top', // This is a Top menu entry
+ 'titre'=>$langs->trans('GPAO'),
+ 'mainmenu'=>'gpao',
+ 'leftmenu'=>'',
+ 'url'=>'/workstation/workstationindex.php',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000 + $r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'1', // Use 'perms'=>'$user->rights->workstation->workstation->read' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );*/
+ /* END MODULEBUILDER TOPMENU */
+ /* BEGIN MODULEBUILDER LEFTMENU WORKSTATION
+ $this->menu[$r++]=array(
+ 'fk_menu'=>'fk_mainmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'left', // This is a Top menu entry
+ 'titre'=>'Workstation',
+ 'mainmenu'=>'workstation',
+ 'leftmenu'=>'workstation',
+ 'url'=>'/workstation/workstationindex.php',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000+$r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'$user->rights->workstation->workstation->read', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );
+ $this->menu[$r++]=array(
+ 'fk_menu'=>'fk_mainmenu=workstation,fk_leftmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'left', // This is a Left menu entry
+ 'titre'=>'List_Workstation',
+ 'mainmenu'=>'workstation',
+ 'leftmenu'=>'workstation_workstation_list',
+ 'url'=>'/workstation/workstation_list.php',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000+$r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'perms'=>'$user->rights->workstation->workstation->read', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );
+ $this->menu[$r++]=array(
+ 'fk_menu'=>'fk_mainmenu=workstation,fk_leftmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'left', // This is a Left menu entry
+ 'titre'=>'New_Workstation',
+ 'mainmenu'=>'workstation',
+ 'leftmenu'=>'workstation_workstation_new',
+ 'url'=>'/workstation/workstation_card.php?action=create',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000+$r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'perms'=>'$user->rights->workstation->workstation->write', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );
+ */
+
+ $this->menu[$r++]=array(
+ // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'fk_menu'=>'fk_mainmenu=mrp',
+ // This is a Left menu entry
+ 'type'=>'left',
+ 'titre'=>$langs->trans('Workstations'),
+ 'mainmenu'=>'mrp',
+ 'leftmenu'=>'workstation_workstation',
+ 'url'=>'',
+ // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'langs'=>'mrp',
+ 'position'=>1100+$r,
+ // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'enabled'=>'$conf->workstation->enabled',
+ // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'perms'=>'$user->rights->workstation->workstation->read',
+ 'target'=>'',
+ // 0=Menu for internal users, 1=external users, 2=both
+ 'user'=>2,
+ );
+ $this->menu[$r++]=array(
+ // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'fk_menu'=>'fk_mainmenu=mrp,fk_leftmenu=workstation_workstation',
+ // This is a Left menu entry
+ 'type'=>'left',
+ 'titre'=>$langs->trans('WorkstationCreate'),
+ 'mainmenu'=>'mrp',
+ 'leftmenu'=>'workstation_workstation_left_create',
+ 'url'=>'/workstation/workstation_card.php?action=create',
+ // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'langs'=>'mrp',
+ 'position'=>1100+$r,
+ // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'enabled'=>'$conf->workstation->enabled',
+ // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'perms'=>'$user->rights->workstation->workstation->write',
+ 'target'=>'',
+ // 0=Menu for internal users, 1=external users, 2=both
+ 'user'=>2
+ );
+ $this->menu[$r++]=array(
+ // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'fk_menu'=>'fk_mainmenu=mrp,fk_leftmenu=workstation_workstation',
+ // This is a Left menu entry
+ 'type'=>'left',
+ 'titre'=>$langs->trans('List'),
+ 'mainmenu'=>'mrp',
+ 'leftmenu'=>'workstation_workstation_left_list',
+ 'url'=>'/workstation/workstation_list.php',
+ // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'langs'=>'mrp',
+ 'position'=>1101+$r,
+ // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'enabled'=>'$conf->workstation->enabled',
+ // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'perms'=>'$user->rights->workstation->workstation->read',
+ 'target'=>'',
+ // 0=Menu for internal users, 1=external users, 2=both
+ 'user'=>2
+ );
+
+ /* END MODULEBUILDER LEFTMENU WORKSTATION */
+ // Exports profiles provided by this module
+ $r = 1;
+ /* BEGIN MODULEBUILDER EXPORT WORKSTATION */
+ /*
+ $langs->load("workstation@workstation");
+ $this->export_code[$r]=$this->rights_class.'_'.$r;
+ $this->export_label[$r]='WorkstationLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_icon[$r]='workstation@workstation';
+ // Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
+ $keyforclass = 'Workstation'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ //$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
+ //unset($this->export_fields_array[$r]['t.fieldtoremove']);
+ //$keyforclass = 'WorkstationLine'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstationline@workstation'; $keyforalias='tl';
+ //include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ $keyforselect='workstation'; $keyforaliasextra='extra'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$keyforselect='workstationline'; $keyforaliasextra='extraline'; $keyforelement='workstationline@workstation';
+ //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$this->export_dependencies_array[$r] = array('workstationline'=>array('tl.rowid','tl.ref')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
+ //$this->export_special_array[$r] = array('t.field'=>'...');
+ //$this->export_examplevalues_array[$r] = array('t.field'=>'Example');
+ //$this->export_help_array[$r] = array('t.field'=>'FieldDescHelp');
+ $this->export_sql_start[$r]='SELECT DISTINCT ';
+ $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'workstation as t';
+ //$this->export_sql_end[$r] =' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_line as tl ON tl.fk_workstation = t.rowid';
+ $this->export_sql_end[$r] .=' WHERE 1 = 1';
+ $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('workstation').')';
+ $r++; */
+ /* END MODULEBUILDER EXPORT WORKSTATION */
+
+ // Imports profiles provided by this module
+ $r = 1;
+ /* BEGIN MODULEBUILDER IMPORT WORKSTATION */
+ /*
+ $langs->load("workstation@workstation");
+ $this->export_code[$r]=$this->rights_class.'_'.$r;
+ $this->export_label[$r]='WorkstationLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_icon[$r]='workstation@workstation';
+ $keyforclass = 'Workstation'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ $keyforselect='workstation'; $keyforaliasextra='extra'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
+ $this->export_sql_start[$r]='SELECT DISTINCT ';
+ $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'workstation as t';
+ $this->export_sql_end[$r] .=' WHERE 1 = 1';
+ $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('workstation').')';
+ $r++; */
+ /* END MODULEBUILDER IMPORT WORKSTATION */
+ }
+
+ /**
+ * Function called when module is enabled.
+ * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
+ * It also creates data directories
+ *
+ * @param string $options Options when enabling module ('', 'noboxes')
+ * @return int 1 if OK, 0 if KO
+ */
+ public function init($options = '')
+ {
+ global $conf, $langs;
+
+ $result = $this->_load_tables('/workstation/sql/');
+ if ($result < 0) return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default')
+
+ // Create extrafields during init
+ //include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+ //$extrafields = new ExtraFields($this->db);
+ //$result1=$extrafields->addExtraField('workstation_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result2=$extrafields->addExtraField('workstation_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result3=$extrafields->addExtraField('workstation_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result4=$extrafields->addExtraField('workstation_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result5=$extrafields->addExtraField('workstation_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+
+ // Permissions
+ $this->remove($options);
+
+ $sql = array();
+
+ // Document templates
+ $moduledir = 'workstation';
+ $myTmpObjects = array();
+ $myTmpObjects['Workstation'] = array('includerefgeneration'=>0, 'includedocgeneration'=>0);
+
+ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
+ if ($myTmpObjectKey == 'Workstation') continue;
+ if ($myTmpObjectArray['includerefgeneration']) {
+ $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/workstation/template_workstations.odt';
+ $dirodt = DOL_DATA_ROOT.'/doctemplates/workstation';
+ $dest = $dirodt.'/template_workstations.odt';
+
+ if (file_exists($src) && !file_exists($dest))
+ {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+ dol_mkdir($dirodt);
+ $result = dol_copy($src, $dest, 0, 0);
+ if ($result < 0)
+ {
+ $langs->load("errors");
+ $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
+ return 0;
+ }
+ }
+
+ $sql = array_merge($sql, array(
+ "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'standard_".strtolower($myTmpObjectKey)."' AND type = '".strtolower($myTmpObjectKey)."' AND entity = ".$conf->entity,
+ "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('standard_".strtolower($myTmpObjectKey)."','".strtolower($myTmpObjectKey)."',".$conf->entity.")",
+ "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'generic_".strtolower($myTmpObjectKey)."_odt' AND type = '".strtolower($myTmpObjectKey)."' AND entity = ".$conf->entity,
+ "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('generic_".strtolower($myTmpObjectKey)."_odt', '".strtolower($myTmpObjectKey)."', ".$conf->entity.")"
+ ));
+ }
+ }
+
+ return $this->_init($sql, $options);
+ }
+
+ /**
+ * Function called when module is disabled.
+ * Remove from database constants, boxes and permissions from Dolibarr database.
+ * Data directories are not deleted
+ *
+ * @param string $options Options when enabling module ('', 'noboxes')
+ * @return int 1 if OK, 0 if KO
+ */
+ public function remove($options = '')
+ {
+ $sql = array();
+ return $this->_remove($sql, $options);
+ }
+}
diff --git a/htdocs/core/modules/workstation/mod_workstation_advanced.php b/htdocs/core/modules/workstation/mod_workstation_advanced.php
new file mode 100755
index 00000000000..d9133b4063c
--- /dev/null
+++ b/htdocs/core/modules/workstation/mod_workstation_advanced.php
@@ -0,0 +1,150 @@
+
+ * Copyright (C) 2004-2007 Laurent Destailleur
+ * Copyright (C) 2005-2009 Regis Houssin
+ * Copyright (C) 2008 Raphael Bertrand (Resultic)
+ * Copyright (C) 2019 Frédéric France
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see https://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/workstation/mod_workstation_advanced.php
+ * \ingroup workstation
+ * \brief File containing class for advanced numbering model of Workstation
+ */
+
+require_once DOL_DOCUMENT_ROOT . '/core/modules/workstation/modules_workstation.php';
+
+
+/**
+ * Class to manage customer Bom numbering rules advanced
+ */
+class mod_workstation_advanced extends ModeleNumRefWorkstation
+{
+ /**
+ * Dolibarr version of the loaded document
+ * @var string
+ */
+ public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
+
+ /**
+ * @var string Error message
+ */
+ public $error = '';
+
+ /**
+ * @var string name
+ */
+ public $name = 'advanced';
+
+
+ /**
+ * Returns the description of the numbering model
+ *
+ * @return string Texte descripif
+ */
+ public function info()
+ {
+ global $conf, $langs, $db;
+
+ $langs->load("bills");
+
+ $form = new Form($db);
+
+ $texte = $langs->trans('GenericNumRefModelDesc')." \n";
+ $texte .= '';
+
+ return $texte;
+ }
+
+ /**
+ * Return an example of numbering
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ global $conf, $db, $langs, $mysoc;
+
+ $object = new Workstation($db);
+ $object->initAsSpecimen();
+
+ /*$old_code_client = $mysoc->code_client;
+ $old_code_type = $mysoc->typent_code;
+ $mysoc->code_client = 'CCCCCCCCCC';
+ $mysoc->typent_code = 'TTTTTTTTTT';*/
+
+ $numExample = $this->getNextValue($object);
+
+ /*$mysoc->code_client = $old_code_client;
+ $mysoc->typent_code = $old_code_type;*/
+
+ if (!$numExample)
+ {
+ $numExample = $langs->trans('NotConfigured');
+ }
+ return $numExample;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ public function getNextValue($object)
+ {
+ global $db, $conf;
+
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+
+ // We get cursor rule
+ $mask = $conf->global->WORKSTATION_WORKSTATION_ADVANCED_MASK;
+
+ if (!$mask)
+ {
+ $this->error = 'NotConfigured';
+ return 0;
+ }
+
+ $date = $object->date;
+
+ $numFinal = get_next_value($db, $mask, 'workstation_workstation', 'ref', '', null, $date);
+
+ return $numFinal;
+ }
+}
diff --git a/htdocs/core/modules/workstation/mod_workstation_standard.php b/htdocs/core/modules/workstation/mod_workstation_standard.php
new file mode 100755
index 00000000000..87e94233c88
--- /dev/null
+++ b/htdocs/core/modules/workstation/mod_workstation_standard.php
@@ -0,0 +1,151 @@
+
+ * Copyright (C) 2005-2009 Regis Houssin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see https://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/workstation/mod_workstation_standard.php
+ * \ingroup workstation
+ * \brief File of class to manage Workstation numbering rules standard
+ */
+require_once DOL_DOCUMENT_ROOT . '/core/modules/workstation/modules_workstation.php';
+
+/**
+ * Class to manage customer order numbering rules standard
+ */
+class mod_workstation_standard extends ModeleNumRefWorkstation
+{
+ /**
+ * Dolibarr version of the loaded document
+ * @var string
+ */
+ public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
+
+ public $prefix = 'WORKSTATION';
+
+ /**
+ * @var string Error code (or message)
+ */
+ public $error = '';
+
+ /**
+ * @var string name
+ */
+ public $name = 'standard';
+
+
+ /**
+ * Return description of numbering module
+ *
+ * @return string Text with description
+ */
+ public function info()
+ {
+ global $langs;
+ return $langs->trans("SimpleNumRefModelDesc", $this->prefix);
+ }
+
+
+ /**
+ * Return an example of numbering
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ return $this->prefix."0501-0001";
+ }
+
+
+ /**
+ * Checks if the numbers already in the database do not
+ * cause conflicts that would prevent this numbering working.
+ *
+ * @param Object $object Object we need next value for
+ * @return boolean false if conflict, true if ok
+ */
+ public function canBeActivated($object)
+ {
+ global $conf, $langs, $db;
+
+ $coyymm = ''; $max = '';
+
+ $posindice = strlen($this->prefix) + 6;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql .= " FROM ".MAIN_DB_PREFIX."workstation_workstation";
+ $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
+ if ($object->ismultientitymanaged == 1) {
+ $sql .= " AND entity = ".$conf->entity;
+ } elseif ($object->ismultientitymanaged == 2) {
+ // TODO
+ }
+
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $row = $db->fetch_row($resql);
+ if ($row) { $coyymm = substr($row[0], 0, 6); $max = $row[0]; }
+ }
+ if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm))
+ {
+ $langs->load("errors");
+ $this->error = $langs->trans('ErrorNumRefModel', $max);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ public function getNextValue($object)
+ {
+ global $db, $conf;
+
+ // First we get the max value
+ $posindice = strlen($this->prefix) + 6;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql .= " FROM ".MAIN_DB_PREFIX."workstation_workstation";
+ $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
+ //$sql .= " AND entity = ".$conf->entity;
+
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $obj = $db->fetch_object($resql);
+ if ($obj) $max = intval($obj->max);
+ else $max = 0;
+ } else {
+ dol_syslog("mod_workstation_standard::getNextValue", LOG_DEBUG);
+ return -1;
+ }
+
+ //$date=time();
+ $date = dol_now();
+ $yymm = strftime("%y%m", $date);
+
+ if ($max >= (pow(10, 4) - 1)) $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is
+ else $num = sprintf("%04s", $max + 1);
+
+ dol_syslog("mod_workstation_standard::getNextValue return ".$this->prefix.$yymm."-".$num);
+ return $this->prefix.$yymm."-".$num;
+ }
+}
diff --git a/htdocs/core/modules/workstation/modules_workstation.php b/htdocs/core/modules/workstation/modules_workstation.php
new file mode 100755
index 00000000000..bfd0f6c95ea
--- /dev/null
+++ b/htdocs/core/modules/workstation/modules_workstation.php
@@ -0,0 +1,150 @@
+
+ * Copyright (C) 2004-2011 Laurent Destailleur
+ * Copyright (C) 2004 Eric Seigne
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2006 Andre Cianfarani
+ * Copyright (C) 2012 Juanjo Menent
+ * Copyright (C) 2014 Marcos García
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see https://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/workstation/modules_workstation.php
+ * \ingroup workstation
+ * \brief File that contains parent class for workstations document models and parent class for workstations numbering models
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
+require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // required for use by classes that inherit
+
+
+/**
+ * Parent class for documents models
+ */
+abstract class ModelePDFWorkstation extends CommonDocGenerator
+{
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Return list of active generation modules
+ *
+ * @param DoliDB $db Database handler
+ * @param integer $maxfilenamelength Max length of value to show
+ * @return array List of templates
+ */
+ public static function liste_modeles($db, $maxfilenamelength = 0)
+ {
+ // phpcs:enable
+ global $conf;
+
+ $type = 'workstation';
+ $list = array();
+
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+ $list = getListOfModels($db, $type, $maxfilenamelength);
+
+ return $list;
+ }
+}
+
+
+
+/**
+ * Parent class to manage numbering of Workstation
+ */
+abstract class ModeleNumRefWorkstation
+{
+ /**
+ * @var string Error code (or message)
+ */
+ public $error = '';
+
+ /**
+ * Return if a module can be used or not
+ *
+ * @return boolean true if module can be used
+ */
+ public function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Returns the default description of the numbering template
+ *
+ * @return string Texte descripif
+ */
+ public function info()
+ {
+ global $langs;
+ $langs->load("workstation@workstation");
+ return $langs->trans("NoDescription");
+ }
+
+ /**
+ * Returns an example of numbering
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ global $langs;
+ $langs->load("workstation@workstation");
+ return $langs->trans("NoExample");
+ }
+
+ /**
+ * Checks if the numbers already in the database do not
+ * cause conflicts that would prevent this numbering working.
+ *
+ * @param Object $object Object we need next value for
+ * @return boolean false if conflict, true if ok
+ */
+ public function canBeActivated($object)
+ {
+ return true;
+ }
+
+ /**
+ * Returns next assigned value
+ *
+ * @param Object $object Object we need next value for
+ * @return string Valeur
+ */
+ public function getNextValue($object)
+ {
+ global $langs;
+ return $langs->trans("NotAvailable");
+ }
+
+ /**
+ * Returns version of numbering module
+ *
+ * @return string Valeur
+ */
+ public function getVersion()
+ {
+ global $langs;
+ $langs->load("admin");
+
+ if ($this->version == 'development') return $langs->trans("VersionDevelopment");
+ if ($this->version == 'experimental') return $langs->trans("VersionExperimental");
+ if ($this->version == 'dolibarr') return DOL_VERSION;
+ if ($this->version) return $this->version;
+ return $langs->trans("NotAvailable");
+ }
+}
diff --git a/htdocs/core/tpl/commonfields_add.tpl.php b/htdocs/core/tpl/commonfields_add.tpl.php
index c7069b3d2aa..a0b0ce7a6e2 100644
--- a/htdocs/core/tpl/commonfields_add.tpl.php
+++ b/htdocs/core/tpl/commonfields_add.tpl.php
@@ -55,6 +55,7 @@ foreach ($object->fields as $key => $val)
print '';
if (!empty($val['picto'])) { print img_picto('', $val['picto']); }
if (in_array($val['type'], array('int', 'integer'))) $value = GETPOST($key, 'int');
+ elseif ($val['type'] == 'double') $value = price2num(GETPOST($key, 'alphanohtml'));
elseif ($val['type'] == 'text' || $val['type'] == 'html') $value = GETPOST($key, 'restricthtml');
else $value = GETPOST($key, 'alpha');
if ($val['noteditable']) print $object->showOutputField($val, $key, $value, '', '', '', 0);
diff --git a/htdocs/core/tpl/commonfields_edit.tpl.php b/htdocs/core/tpl/commonfields_edit.tpl.php
index 946d8c0b504..76a9fafe417 100644
--- a/htdocs/core/tpl/commonfields_edit.tpl.php
+++ b/htdocs/core/tpl/commonfields_edit.tpl.php
@@ -53,6 +53,7 @@ foreach ($object->fields as $key => $val)
print ' | ';
if (!empty($val['picto'])) { print img_picto('', $val['picto']); }
if (in_array($val['type'], array('int', 'integer'))) $value = GETPOSTISSET($key) ?GETPOST($key, 'int') : $object->$key;
+ elseif ($val['type'] == 'double') $value = GETPOSTISSET($key) ? price2num(GETPOST($key, 'alphanohtml')) : $object->$key;
elseif (preg_match('/^(text|html)/', $val['type'])) {
$tmparray = explode(':', $val['type']);
if (!empty($tmparray[1])) {
diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql
new file mode 100644
index 00000000000..a75de31a905
--- /dev/null
+++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql
@@ -0,0 +1,40 @@
+CREATE TABLE llx_workstation_workstation(
+ -- BEGIN MODULEBUILDER FIELDS
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ ref varchar(128) DEFAULT '(PROV)' NOT NULL,
+ label varchar(255),
+ type varchar(7),
+ note_public text,
+ entity int DEFAULT 1,
+ note_private text,
+ date_creation datetime NOT NULL,
+ tms timestamp,
+ fk_user_creat integer NOT NULL,
+ fk_user_modif integer,
+ import_key varchar(14),
+ status smallint NOT NULL,
+ nb_operators_required integer,
+ thm_operator_estimated double,
+ thm_machine_estimated double
+ -- END MODULEBUILDER FIELDS
+) ENGINE=innodb;
+
+ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_rowid (rowid);
+ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_ref (ref);
+ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid);
+ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_status (status);
+
+CREATE TABLE llx_workstation_workstation_resource(
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ tms timestamp,
+ fk_resource integer,
+ fk_workstation integer
+) ENGINE=innodb;
+
+CREATE TABLE llx_workstation_workstation_usergroup(
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ tms timestamp,
+ fk_usergroup integer,
+ fk_workstation integer
+) ENGINE=innodb;
+
diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql
new file mode 100755
index 00000000000..2e013ee0128
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql
@@ -0,0 +1,27 @@
+-- Copyright (C) ---Put here your own copyright and developer email---
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see https://www.gnu.org/licenses/.
+
+
+-- BEGIN MODULEBUILDER INDEXES
+ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_rowid (rowid);
+ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_ref (ref);
+ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid);
+ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_status (status);
+-- END MODULEBUILDER INDEXES
+
+--ALTER TABLE llx_workstation_workstation ADD UNIQUE INDEX uk_workstation_workstation_fieldxy(fieldx, fieldy);
+
+--ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_field FOREIGN KEY (fk_field) REFERENCES llx_workstation_myotherobject(rowid);
+
diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.sql
new file mode 100755
index 00000000000..5c141ed59df
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_workstation_workstation.sql
@@ -0,0 +1,36 @@
+-- Copyright (C) ---Put here your own copyright and developer email---
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see https://www.gnu.org/licenses/.
+
+
+CREATE TABLE llx_workstation_workstation(
+ -- BEGIN MODULEBUILDER FIELDS
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ ref varchar(128) DEFAULT '(PROV)' NOT NULL,
+ label varchar(255),
+ type varchar(7),
+ note_public text,
+ entity int DEFAULT 1,
+ note_private text,
+ date_creation datetime NOT NULL,
+ tms timestamp,
+ fk_user_creat integer NOT NULL,
+ fk_user_modif integer,
+ import_key varchar(14),
+ status smallint NOT NULL,
+ nb_operators_required integer,
+ thm_operator_estimated double,
+ thm_machine_estimated double
+ -- END MODULEBUILDER FIELDS
+) ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql
new file mode 100755
index 00000000000..1ab019f4385
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql
@@ -0,0 +1,22 @@
+-- Copyright (C) ---Put here your own copyright and developer email---
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see https://www.gnu.org/licenses/.
+
+
+CREATE TABLE llx_workstation_workstation_resource(
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ tms timestamp,
+ fk_resource integer,
+ fk_workstation integer
+) ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql
new file mode 100755
index 00000000000..9bffb4f30c9
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql
@@ -0,0 +1,22 @@
+-- Copyright (C) ---Put here your own copyright and developer email---
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see https://www.gnu.org/licenses/.
+
+
+CREATE TABLE llx_workstation_workstation_usergroup(
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ tms timestamp,
+ fk_usergroup integer,
+ fk_workstation integer
+) ENGINE=innodb;
diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang
index 902f167d819..ec999a473a4 100644
--- a/htdocs/langs/en_US/mrp.lang
+++ b/htdocs/langs/en_US/mrp.lang
@@ -77,4 +77,28 @@ UnitCost=Unit cost
TotalCost=Total cost
BOMTotalCost=The cost to produce this BOM based on cost of each quantity and product to consume (use Cost price if defined, else Average Weighted Price if defined, else the Best purchase price)
GoOnTabProductionToProduceFirst=You must first have started the production to close a Manufacturing Order (See tab '%s'). But you can Cancel it.
-ErrorAVirtualProductCantBeUsedIntoABomOrMo=A kit can't be used into a BOM or a MO
\ No newline at end of file
+ErrorAVirtualProductCantBeUsedIntoABomOrMo=A kit can't be used into a BOM or a MO
+Workstation=Workstation
+Workstations=Workstations
+WorkstationsDescription=Workstations management
+WorkstationSetup = Workstations setup
+WorkstationSetupPage = Workstations setup page
+WorkstationAbout = About Workstation
+WorkstationAboutPage = Workstations about page
+WorkstationList=Workstation list
+WorkstationCreate=Add new workstation
+ConfirmEnableWorkstation=Are you sure you want to enable workstation %s ?
+EnableAWorkstation=Enable a workstation
+ConfirmDisableWorkstation=Are you sure you want to disable workstation %s ?
+DisableAWorkstation=Disable a workstation
+DeleteWorkstation=Supprimer
+NbOperatorsRequired=Number of operators required
+THMOperatorEstimated=Estimated operator THM
+THMMachineEstimated=Estimated machine THM
+WorkstationType=Workstation type
+Human=Human
+Machine=Machine
+HumanMachine=Human / Machine
+WorkstationArea=Workstation area
+Machines=Machines
+THMEstimatedHelp=This rate makes it possible to define a forecast cost of the item
diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php
index 0b6239b01e4..46085c126e0 100644
--- a/htdocs/resource/class/html.formresource.class.php
+++ b/htdocs/resource/class/html.formresource.class.php
@@ -77,7 +77,7 @@ class FormResource
* @param string $morecss More css
* @return string HTML string with
*/
- public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '')
+ public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '', $multiple=false)
{
// phpcs:enable
global $conf, $user, $langs;
@@ -89,6 +89,8 @@ class FormResource
$resources_used = $resourcestat->fetch_all('ASC', 't.rowid', $limit, 0, $filter);
+ if (!is_array($selected)) $selected = array($selected);
+
if ($outputmode != 2)
{
$out = ' | |