From 49f7f8576251bbcbc331224405b79e40dde111f0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 00:00:51 +0200 Subject: [PATCH 01/25] Fix example --- htdocs/societe/class/api_thirdparties.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 39773b7b637..253a35e710c 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -124,8 +124,8 @@ class Thirdparties extends DolibarrApi * Set to 2 to show only prospects * Set to 3 to show only those are not customer neither prospect * Set to 4 to show only suppliers - * @param int $category Use this param to filter list by category - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.nom:like:'TheCompany%') and (t.date_creation:<:'20160101')" + * @param int $category Use this param to filter list by category + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "((t.nom:like:'TheCompany%') or (t.name_alias:like:'TheCompany%')) and (t.datec:<:'20160101')" * @return array Array of thirdparty objects */ public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '') From 4da5aeedf42fac063afcc82fedb73ffd0c90ca96 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 08:42:33 +0200 Subject: [PATCH 02/25] Fix bad test --- test/phpunit/ActionCommTest.php | 2 +- test/phpunit/AdherentTest.php | 6 +++--- test/phpunit/BuildDocTest.php | 14 +++++++------- test/phpunit/CommandeFournisseurTest.php | 2 +- test/phpunit/CommandeTest.php | 2 +- test/phpunit/DateLibTzFranceTest.php | 2 +- test/phpunit/EntrepotTest.php | 2 +- test/phpunit/FactureTest.php | 4 ++-- test/phpunit/MouvementStockTest.php | 2 +- test/phpunit/PaypalTest.php | 2 +- test/phpunit/PdfDocTest.php | 2 +- test/phpunit/ProductTest.php | 2 +- test/phpunit/RestAPIUserTest.php | 2 +- test/phpunit/SocieteTest.php | 6 +++--- test/phpunit/StripeTest.php | 2 +- test/phpunit/SupplierProposalTest.php | 2 +- test/phpunit/UserTest.php | 2 +- 17 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/phpunit/ActionCommTest.php b/test/phpunit/ActionCommTest.php index cb908416535..b739b387a74 100644 --- a/test/phpunit/ActionCommTest.php +++ b/test/phpunit/ActionCommTest.php @@ -84,7 +84,7 @@ class ActionCommTest extends PHPUnit\Framework\TestCase $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. if (empty($conf->agenda->enabled)) { - print __METHOD__." module agenda must be enabled.\n"; die(); + print __METHOD__." module agenda must be enabled.\n"; die(1); } print __METHOD__."\n"; diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 63b55dd37aa..0e4956e3a12 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -87,13 +87,13 @@ class AdherentTest extends PHPUnit\Framework\TestCase if (! empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print "\n".__METHOD__." Company must be setup to have name-firstname in order 'Firstname Lastname'\n"; - die(); + die(1); } if (! empty($conf->global->MAIN_MODULE_LDAP)) { - print "\n".__METHOD__." module LDAP must be disabled.\n"; die(); + print "\n".__METHOD__." module LDAP must be disabled.\n"; die(1); } if (! empty($conf->global->MAIN_MODULE_MAILMANSPIP)) { - print "\n".__METHOD__." module MailmanSpip must be disabled.\n"; die(); + print "\n".__METHOD__." module MailmanSpip must be disabled.\n"; die(1); } print __METHOD__."\n"; diff --git a/test/phpunit/BuildDocTest.php b/test/phpunit/BuildDocTest.php index 455f2ce513a..18a737ec50b 100644 --- a/test/phpunit/BuildDocTest.php +++ b/test/phpunit/BuildDocTest.php @@ -113,25 +113,25 @@ class BuildDocTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (! $conf->facture->enabled) { - print __METHOD__." invoice module not enabled\n"; die(); + print __METHOD__." invoice module not enabled\n"; die(1); } if (! $conf->commande->enabled) { - print __METHOD__." order module not enabled\n"; die(); + print __METHOD__." order module not enabled\n"; die(1); } if (! $conf->propal->enabled) { - print __METHOD__." propal module not enabled\n"; die(); + print __METHOD__." propal module not enabled\n"; die(1); } if (! $conf->projet->enabled) { - print __METHOD__." project module not enabled\n"; die(); + print __METHOD__." project module not enabled\n"; die(1); } if (! $conf->expedition->enabled) { - print __METHOD__." shipment module not enabled\n"; die(); + print __METHOD__." shipment module not enabled\n"; die(1); } if (! $conf->ficheinter->enabled) { - print __METHOD__." intervention module not enabled\n"; die(); + print __METHOD__." intervention module not enabled\n"; die(1); } if (! $conf->expensereport->enabled) { - print __METHOD__." expensereport module not enabled\n"; die(); + print __METHOD__." expensereport module not enabled\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/CommandeFournisseurTest.php b/test/phpunit/CommandeFournisseurTest.php index b050005bcf1..bf5922460a2 100644 --- a/test/phpunit/CommandeFournisseurTest.php +++ b/test/phpunit/CommandeFournisseurTest.php @@ -147,7 +147,7 @@ class CommandeFournisseurTest extends PHPUnit\Framework\TestCase $product=new ProductFournisseur($db); $product->fetch(0, 'PIDRESS'); if ($product->id <= 0) { - print "\n".__METHOD__." A product with ref PIDRESS must exists into database"; die(); + print "\n".__METHOD__." A product with ref PIDRESS must exists into database"; die(1); } $quantity=10; diff --git a/test/phpunit/CommandeTest.php b/test/phpunit/CommandeTest.php index 4ab81d63524..064c205c0e9 100644 --- a/test/phpunit/CommandeTest.php +++ b/test/phpunit/CommandeTest.php @@ -84,7 +84,7 @@ class CommandeTest extends PHPUnit\Framework\TestCase $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. if (empty($conf->commande->enabled)) { - print __METHOD__." module customer order must be enabled.\n"; die(); + print __METHOD__." module customer order must be enabled.\n"; die(1); } print __METHOD__."\n"; diff --git a/test/phpunit/DateLibTzFranceTest.php b/test/phpunit/DateLibTzFranceTest.php index 63eadc1a98f..4b63450c332 100644 --- a/test/phpunit/DateLibTzFranceTest.php +++ b/test/phpunit/DateLibTzFranceTest.php @@ -83,7 +83,7 @@ class DateLibTzFranceTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (getServerTimeZoneString() != 'Europe/Paris' && getServerTimeZoneString() != 'Europe/Berlin') { - print "\n".__METHOD__." This PHPUnit test can be launched manually only onto a server with PHP timezone set to TZ=Europe/Paris, not a TZ=".getServerTimeZoneString().".\n"; die(); + print "\n".__METHOD__." This PHPUnit test can be launched manually only onto a server with PHP timezone set to TZ=Europe/Paris, not a TZ=".getServerTimeZoneString().".\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/EntrepotTest.php b/test/phpunit/EntrepotTest.php index 6be9b5ba349..691b3039744 100644 --- a/test/phpunit/EntrepotTest.php +++ b/test/phpunit/EntrepotTest.php @@ -83,7 +83,7 @@ class EntrepotTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (empty($conf->stock->enabled)) { - print __METHOD__." Module Stock must be enabled.\n"; die(); + print __METHOD__." Module Stock must be enabled.\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php index ddb895d1b96..efa7d43a269 100644 --- a/test/phpunit/FactureTest.php +++ b/test/phpunit/FactureTest.php @@ -84,10 +84,10 @@ class FactureTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (empty($conf->facture->enabled)) { - print __METHOD__." module customer invoice must be enabled.\n"; die(); + print __METHOD__." module customer invoice must be enabled.\n"; die(1); } if (! empty($conf->ecotaxdeee->enabled)) { - print __METHOD__." ecotaxdeee module must not be enabled.\n"; die(); + print __METHOD__." ecotaxdeee module must not be enabled.\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/MouvementStockTest.php b/test/phpunit/MouvementStockTest.php index b68a8c90d0a..749f94ab20f 100644 --- a/test/phpunit/MouvementStockTest.php +++ b/test/phpunit/MouvementStockTest.php @@ -115,7 +115,7 @@ class MouvementStockTest extends PHPUnit\Framework\TestCase $db=$this->savdb; if (empty($conf->productbatch->enabled)) { - print "\n".__METHOD__." module Lot/Serial must be enabled.\n"; die(); + print "\n".__METHOD__." module Lot/Serial must be enabled.\n"; die(1); } print __METHOD__."\n"; diff --git a/test/phpunit/PaypalTest.php b/test/phpunit/PaypalTest.php index 3177e5555ed..61027d02710 100644 --- a/test/phpunit/PaypalTest.php +++ b/test/phpunit/PaypalTest.php @@ -84,7 +84,7 @@ class PaypalTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (empty($conf->paypal->enabled)) { - print __METHOD__." Module Paypal must be enabled.\n"; die(); + print __METHOD__." Module Paypal must be enabled.\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/PdfDocTest.php b/test/phpunit/PdfDocTest.php index 4c07f970c24..039bbe69288 100644 --- a/test/phpunit/PdfDocTest.php +++ b/test/phpunit/PdfDocTest.php @@ -144,7 +144,7 @@ class PdfDocTest extends PHPUnit\Framework\TestCase $localproduct->fetch(0, 'PIDRESS'); $product_id=$localproduct->id; if ($product_id <= 0) { - print "\n".__METHOD__." A product with ref PIDRESS must exists into database"; die(); + print "\n".__METHOD__." A product with ref PIDRESS must exists into database"; die(1); } $localobject=new Facture($this->savdb); diff --git a/test/phpunit/ProductTest.php b/test/phpunit/ProductTest.php index a7267251ed0..7eb6de57c02 100644 --- a/test/phpunit/ProductTest.php +++ b/test/phpunit/ProductTest.php @@ -83,7 +83,7 @@ class ProductTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (empty($conf->produit->enabled)) { - print __METHOD__." Module Product must be enabled.\n"; die(); + print __METHOD__." Module Product must be enabled.\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/RestAPIUserTest.php b/test/phpunit/RestAPIUserTest.php index a534c5f5910..c908b631df8 100644 --- a/test/phpunit/RestAPIUserTest.php +++ b/test/phpunit/RestAPIUserTest.php @@ -74,7 +74,7 @@ class RestAPIUserTest extends PHPUnit\Framework\TestCase $this->savdb=$db; if (empty($conf->api->enabled)) { - print __METHOD__." module api must be enabled.\n"; die(); + print __METHOD__." module api must be enabled.\n"; die(1); } print __METHOD__." db->type=".$db->type." user->id=".$user->id; diff --git a/test/phpunit/SocieteTest.php b/test/phpunit/SocieteTest.php index 12f24290413..73363140acd 100755 --- a/test/phpunit/SocieteTest.php +++ b/test/phpunit/SocieteTest.php @@ -84,15 +84,15 @@ class SocieteTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if ($conf->global->SOCIETE_CODECLIENT_ADDON != 'mod_codeclient_monkey') { - print "\n".__METHOD__." third party ref checker must be setup to 'mod_codeclient_monkey' not to '".$conf->global->SOCIETE_CODECLIENT_ADDON."'.\n"; die(); + print "\n".__METHOD__." third party ref checker must be setup to 'mod_codeclient_monkey' not to '".$conf->global->SOCIETE_CODECLIENT_ADDON."'.\n"; die(1); } if (! empty($conf->global->MAIN_DISABLEPROFIDRULES)) { - print "\n".__METHOD__." constant MAIN_DISABLEPROFIDRULES must be empty (if a module set it, disable module).\n"; die(); + print "\n".__METHOD__." constant MAIN_DISABLEPROFIDRULES must be empty (if a module set it, disable module).\n"; die(1); } if ($langs->defaultlang != 'en_US') { - print "\n".__METHOD__." default language of company must be set to autodetect.\n"; die(); + print "\n".__METHOD__." default language of company must be set to autodetect.\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/StripeTest.php b/test/phpunit/StripeTest.php index 9425cc47aa0..bb769e83e80 100644 --- a/test/phpunit/StripeTest.php +++ b/test/phpunit/StripeTest.php @@ -84,7 +84,7 @@ class StripeTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (empty($conf->stripe->enabled)) { - print __METHOD__." Module Stripe must be enabled.\n"; die(); + print __METHOD__." Module Stripe must be enabled.\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. diff --git a/test/phpunit/SupplierProposalTest.php b/test/phpunit/SupplierProposalTest.php index bc9263f410c..ebcf30c29e6 100644 --- a/test/phpunit/SupplierProposalTest.php +++ b/test/phpunit/SupplierProposalTest.php @@ -87,7 +87,7 @@ class SupplierProposalTest extends PHPUnit\Framework\TestCase $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. if (empty($conf->global->MAIN_MODULE_SUPPLIERPROPOSAL)) { - print "\n".__METHOD__." module Supplier proposal must be enabled.\n"; die(); + print "\n".__METHOD__." module Supplier proposal must be enabled.\n"; die(1); } print __METHOD__."\n"; diff --git a/test/phpunit/UserTest.php b/test/phpunit/UserTest.php index ca889fdbc96..5a09e4c9864 100644 --- a/test/phpunit/UserTest.php +++ b/test/phpunit/UserTest.php @@ -83,7 +83,7 @@ class UserTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; if (! empty($conf->global->MAIN_MODULE_LDAP)) { - print "\n".__METHOD__." module LDAP must be disabled.\n"; die(); + print "\n".__METHOD__." module LDAP must be disabled.\n"; die(1); } $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. From 3ea6cd1c66a75d3fc38c870cfa759578414d4fec Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 08:53:29 +0200 Subject: [PATCH 03/25] Fix missing columns --- htdocs/install/mysql/migration/13.0.0-14.0.0.sql | 2 ++ htdocs/install/mysql/tables/llx_product.sql | 2 ++ htdocs/product/inventory/inventory.php | 6 +++--- test/phpunit/PdfDocTest.php | 7 +++++-- 4 files changed, 12 insertions(+), 5 deletions(-) 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 index 92e2c3cf757..37719c015c5 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -403,6 +403,8 @@ UPDATE llx_propal SET date_signature = date_cloture WHERE date_signature IS NULL ALTER TABLE llx_product ADD COLUMN batch_mask VARCHAR(32) NULL; +ALTER TABLE llx_product ADD COLUMN lifetime INTEGER NULL; +ALTER TABLE llx_product ADD COLUMN qc_frequency INTEGER NULL; insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (210, 'conferenceorbooth', 'internal', 'MANAGER', 'Conference or Booth manager', 1); insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (211, 'conferenceorbooth', 'external', 'SPEAKER', 'Conference Speaker', 1); diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index da8c2ff693c..73b4473a5a4 100644 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -94,6 +94,8 @@ create table llx_product fk_default_warehouse integer DEFAULT NULL, canvas varchar(32) DEFAULT NULL, finished tinyint DEFAULT NULL, -- see dictionnary c_product_nature + lifetime integer DEFAULT NULL, + qc_frequency integer DEFAULT NULL, hidden tinyint DEFAULT 0, -- Not used. Deprecated. import_key varchar(14), -- Import key model_pdf varchar(255), -- model save dodument used diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index ecad54a4a73..331dcb997c7 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -609,7 +609,7 @@ if ($object->id > 0) { print ''; } - // Request to show lines of inventory (prefilled during creation) + // Request to show lines of inventory (prefilled after start/validate step) $sql = 'SELECT id.rowid, id.datec as date_creation, id.tms as date_modification, id.fk_inventory, id.fk_warehouse,'; $sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated'; $sql .= ' FROM '.MAIN_DB_PREFIX.'inventorydet as id'; @@ -641,8 +641,8 @@ if ($object->id > 0) { $product_static = $cacheOfProducts[$obj->fk_product]; } else { $product_static = new Product($db); - $product_static->fetch($obj->fk_product); - + $result = $product_static->fetch($obj->fk_product, '', '', '', 1, 1, 1); +var_dump($result); $option = 'nobatch'; $option .= ',novirtual'; $product_static->load_stock($option); // Load stock_reel + stock_warehouse. This can also call load_virtual_stock() diff --git a/test/phpunit/PdfDocTest.php b/test/phpunit/PdfDocTest.php index 039bbe69288..e744aef3c2f 100644 --- a/test/phpunit/PdfDocTest.php +++ b/test/phpunit/PdfDocTest.php @@ -141,8 +141,11 @@ class PdfDocTest extends PHPUnit\Framework\TestCase $db=$this->savdb; $localproduct=new Product($this->savdb); - $localproduct->fetch(0, 'PIDRESS'); - $product_id=$localproduct->id; + $result = $localproduct->fetch(0, 'PIDRESS'); + if ($result < 0) { + print "\n".__METHOD__." Failed to make the fetch of product PIDRESS. ".$localproduct->error; die(1); + } + $product_id = $localproduct->id; if ($product_id <= 0) { print "\n".__METHOD__." A product with ref PIDRESS must exists into database"; die(1); } From fac32ee9136e1ba0fbf00d00f79a16bf8f7a53f5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 08:54:36 +0200 Subject: [PATCH 04/25] Better performance --- htdocs/product/inventory/inventory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 331dcb997c7..b2cf491d901 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -642,7 +642,7 @@ if ($object->id > 0) { } else { $product_static = new Product($db); $result = $product_static->fetch($obj->fk_product, '', '', '', 1, 1, 1); -var_dump($result); + $option = 'nobatch'; $option .= ',novirtual'; $product_static->load_stock($option); // Load stock_reel + stock_warehouse. This can also call load_virtual_stock() From dd00feae006e9c80354a89309fcc507af6d03f82 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 08:57:06 +0200 Subject: [PATCH 05/25] Clean code --- .../accountancy/bookkeeping/thirdparty_lettering_customer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php index 0064e8c4715..8669cae7c2f 100644 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php @@ -281,7 +281,7 @@ if ($resql) { $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal); print ''.$journaltoshow.''; - if (empty($obj->lettering_code)) { + if (empty($obj->lettering_code) && empty($obj->date_validated)) { print ''; print ''; print img_edit(); From b8254186ce7d5742c3898250bc43915306ecf2ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 09:07:36 +0200 Subject: [PATCH 06/25] Clean code --- htdocs/core/class/html.formother.class.php | 46 ++++++++++++++++++++++ htdocs/product/inventory/inventory.php | 32 ++------------- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 4fb0a44b06b..fa825bcb84d 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -56,6 +56,52 @@ class FormOther $this->db = $db; } + /** + * Return HTML code for scanner tool + * + * @param string $jstoexecuteonadd Name of javascript function to call + * @return string HTML component + */ + public function getHTMLScannerForm($jstoexecuteonadd = 'barcodscannerjs') + { + global $langs; + + $out = ''; + + $out .= '
'; + $out .= ''."\n"; + $out .= '
'; + $out .= '
Barcode scanner tool...

'; + + $out .= ' Autodetect if we scan a product barcode or a lot/serial barcode
'; + $out .= ' Scan a product barcode
'; + $out .= ' Scan a product lot or serial number
'; + + $out .= $langs->trans("QtyToAddAfterBarcodeScan").'
'; + $out .= ''; + + /*print '
'.$langs->trans("or").'
'; + + print '
'; + + print '     Qty
'; + */ + $out .= '
'; + $out .= '
'; + $out .= ''; + $out .= ''; + $out .= '
'; + + $out .= ''.$langs->trans("FeatureNotYetAvailable").''; + + // TODO Add call of javascript $jstoexecuteonadd so each scan will add qty into the inventory page + an ajax save. + + $out .= '
'; + $out .= '
'; + $out .= '
'; + + return $out; + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index b2cf491d901..6af61126fe6 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -524,35 +524,9 @@ if ($object->id > 0) { // Popup for mass barcode scanning if ($action == 'updatebyscaning') { - print '
'; - print ''."\n"; - print '
'; - print '
Barcode scanner tool...

'; - - print ' Autodetect if we scan a product barcode or a lot/serial barcode
'; - print ' Scan a product barcode
'; - print ' Scan a product lot or serial number
'; - - print $langs->trans("QtyToAddAfterBarcodeScan").'
'; - print ''; - - /*print '
'.$langs->trans("or").'
'; - - print '
'; - - print '     Qty
'; - */ - print '
'; - print '
'; - print '
'; - - print ''.$langs->trans("FeatureNotYetAvailable").''; - - // TODO Add javascript so each scan will add qty into the inventory page + an ajax save. - - print '
'; - print '
'; - print '
'; + include DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + $formother = new FormOther($db); + print $formother->getHTMLScannerForm(); } From f334f2a255d347c1aeb1e32f8cf3a7f2a88b3831 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 09:22:49 +0200 Subject: [PATCH 07/25] Fix inventory --- htdocs/product/inventory/inventory.php | 32 ++++++++++++++++++-------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 6af61126fe6..970676c34b6 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -103,7 +103,7 @@ if ($action == 'cancel_record' && $permissiontoadd) { $object->setCanceled($user); } -if ($action == 'update' && $user->rights->stock->mouvement->creer) { +if ($action == 'update' && !empty($user->rights->stock->mouvement->creer)) { $stockmovment = new MouvementStock($db); $stockmovment->origin = $object; @@ -160,7 +160,7 @@ if ($action == 'update' && $user->rights->stock->mouvement->creer) { } } -if (($action == 'record' || $action =='updateinventorylines') && $permissiontoadd) { +if ($action =='updateinventorylines' && $permissiontoadd) { $sql = 'SELECT id.rowid, id.datec as date_creation, id.tms as date_modification, id.fk_inventory, id.fk_warehouse,'; $sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated'; $sql .= ' FROM '.MAIN_DB_PREFIX.'inventorydet as id'; @@ -301,16 +301,19 @@ llxHeader('', $langs->trans('Inventory'), $help_url); // Disable button Generate movement if data were not saved print ''; @@ -466,7 +469,7 @@ if ($object->id > 0) { // Save if ($object->status == $object::STATUS_VALIDATED) { if ($permissiontoadd) { - print '
'.$langs->trans("MakeMovementsAndClose").''."\n"; + print ''.$langs->trans("MakeMovementsAndClose").''."\n"; } else { print ''.$langs->trans('MakeMovementsAndClose').''."\n"; } @@ -598,6 +601,7 @@ if ($object->id > 0) { $num = $db->num_rows($resql); $i = 0; + $totalfound = 0; $totalarray = array(); while ($i < $num) { $obj = $db->fetch_object($resql); @@ -647,6 +651,7 @@ if ($object->id > 0) { print ''; if ($object->status == $object::STATUS_VALIDATED) { $qty_view = GETPOST("id_".$obj->rowid) ? GETPOST("id_".$obj->rowid) : $obj->qty_view; + $totalfound += price2num($qty_view, 'MS'); print ''; print ''; print ''; @@ -654,6 +659,7 @@ if ($object->id > 0) { print ''; } else { print $obj->qty_view; + $totalfound += $obj->qty_view; print ''; } print ''; @@ -674,6 +680,14 @@ if ($object->id > 0) { print ''; + // Call method to disable the button if no qty entered yet for inventory + if ($object->status != $object::STATUS_VALIDATED || $totalfound == 0) { + print ''; + } print ''; } From cfded75d114da064cc90abf5d23c2daa58759e36 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 09:27:04 +0200 Subject: [PATCH 08/25] Debug v14 --- htdocs/core/class/html.formother.class.php | 5 ++--- htdocs/product/inventory/inventory.php | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index fa825bcb84d..ba3ff77d394 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -57,7 +57,8 @@ class FormOther } /** - * Return HTML code for scanner tool + * Return HTML code for scanner tool. + * This must be called into an existing
* * @param string $jstoexecuteonadd Name of javascript function to call * @return string HTML component @@ -68,7 +69,6 @@ class FormOther $out = ''; - $out .= ''; $out .= ''."\n"; $out .= '
'; $out .= '
Barcode scanner tool...

'; @@ -98,7 +98,6 @@ class FormOther $out .= ''; $out .= '
'; - $out .= '
'; return $out; } diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 970676c34b6..2abc830eb7c 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -99,6 +99,10 @@ $now = dol_now(); * Actions */ +if ($cancel) { + $action = ''; +} + if ($action == 'cancel_record' && $permissiontoadd) { $object->setCanceled($user); } From ce8c60613237b0c35c137875a5820b5daf32a108 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 11:04:22 +0200 Subject: [PATCH 09/25] Clean APIs --- htdocs/api/class/api.class.php | 25 +++++++-- htdocs/product/class/api_products.class.php | 60 +++++++++++++++++---- htdocs/product/class/product.class.php | 12 +---- htdocs/user/card.php | 12 +++-- 4 files changed, 80 insertions(+), 29 deletions(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 7a9dd908a59..0a84de7b7c1 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -124,6 +124,16 @@ class DolibarrApi unset($object->ref_previous); unset($object->ref_next); unset($object->ref_int); + unset($object->imgWidth); + unset($object->imgHeight); + unset($object->barcode_type_code); + unset($object->barcode_type_label); + + unset($object->mode_reglement); // We use mode_reglement_id now + unset($object->cond_reglement); // We use cond_reglement_id now + unset($object->note); // We use note_public or note_private now + unset($object->contact); // We use contact_id now + unset($object->thirdparty); // We use thirdparty_id or fk_soc or socid now unset($object->projet); // Should be fk_project unset($object->project); // Should be fk_project @@ -137,6 +147,12 @@ class DolibarrApi unset($object->timespent_fk_user); unset($object->timespent_note); unset($object->fk_delivery_address); + unset($object->modelpdf); + unset($object->sendtoid); + unset($object->name_bis); + unset($object->newref); + unset($object->alreadypaid); + unset($object->openid); unset($object->statuts); unset($object->statuts_short); @@ -169,16 +185,17 @@ class DolibarrApi unset($object->region); unset($object->region_code); + unset($object->country); + unset($object->state); + unset($object->state_code); + unset($object->departement); + unset($object->departement_code); unset($object->libelle_statut); unset($object->libelle_paiement); unset($object->prefix_comm); - unset($object->sendtoid); - unset($object->name_bis); - unset($object->newref); - if (!isset($object->table_element) || $object->table_element != 'ticket') { unset($object->comments); } diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index fc89787deda..b4e860a1069 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -73,15 +73,16 @@ class Products extends DolibarrApi * @param int $includestockdata Load also information about stock (slower) * @param bool $includesubproducts Load information about subproducts * @param bool $includeparentid Load also ID of parent product (if product is a variant of a parent product) + * @param bool $includetrans Load also the translations of product label and description * @return array|mixed Data without useless information * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ - public function get($id, $includestockdata = 0, $includesubproducts = false, $includeparentid = false) + public function get($id, $includestockdata = 0, $includesubproducts = false, $includeparentid = false, $includetrans = false) { - return $this->_fetch($id, '', '', '', $includestockdata, $includesubproducts, $includeparentid); + return $this->_fetch($id, '', '', '', $includestockdata, $includesubproducts, $includeparentid, false, $includetrans); } /** @@ -93,6 +94,7 @@ class Products extends DolibarrApi * @param int $includestockdata Load also information about stock (slower) * @param bool $includesubproducts Load information about subproducts * @param bool $includeparentid Load also ID of parent product (if product is a variant of a parent product) + * @param bool $includetrans Load also the translations of product label and description * * @return array|mixed Data without useless information * @@ -102,9 +104,9 @@ class Products extends DolibarrApi * @throws RestException 403 * @throws RestException 404 */ - public function getByRef($ref, $includestockdata = 0, $includesubproducts = false, $includeparentid = false) + public function getByRef($ref, $includestockdata = 0, $includesubproducts = false, $includeparentid = false, $includetrans = false) { - return $this->_fetch('', $ref, '', '', $includestockdata, $includesubproducts, $includeparentid); + return $this->_fetch('', $ref, '', '', $includestockdata, $includesubproducts, $includeparentid, false, $includetrans); } /** @@ -116,6 +118,7 @@ class Products extends DolibarrApi * @param int $includestockdata Load also information about stock (slower) * @param bool $includesubproducts Load information about subproducts * @param bool $includeparentid Load also ID of parent product (if product is a variant of a parent product) + * @param bool $includetrans Load also the translations of product label and description * * @return array|mixed Data without useless information * @@ -125,9 +128,9 @@ class Products extends DolibarrApi * @throws RestException 403 * @throws RestException 404 */ - public function getByRefExt($ref_ext, $includestockdata = 0, $includesubproducts = false, $includeparentid = false) + public function getByRefExt($ref_ext, $includestockdata = 0, $includesubproducts = false, $includeparentid = false, $includetrans = false) { - return $this->_fetch('', '', $ref_ext, '', $includestockdata, $includesubproducts, $includeparentid); + return $this->_fetch('', '', $ref_ext, '', $includestockdata, $includesubproducts, $includeparentid, false, $includetrans); } /** @@ -139,6 +142,7 @@ class Products extends DolibarrApi * @param int $includestockdata Load also information about stock (slower) * @param bool $includesubproducts Load information about subproducts * @param bool $includeparentid Load also ID of parent product (if product is a variant of a parent product) + * @param bool $includetrans Load also the translations of product label and description * * @return array|mixed Data without useless information * @@ -148,9 +152,9 @@ class Products extends DolibarrApi * @throws RestException 403 * @throws RestException 404 */ - public function getByBarcode($barcode, $includestockdata = 0, $includesubproducts = false, $includeparentid = false) + public function getByBarcode($barcode, $includestockdata = 0, $includesubproducts = false, $includeparentid = false, $includetrans = false) { - return $this->_fetch('', '', '', $barcode, $includestockdata, $includesubproducts, $includeparentid); + return $this->_fetch('', '', '', $barcode, $includestockdata, $includesubproducts, $includeparentid, false, $includetrans); } /** @@ -1895,6 +1899,8 @@ class Products extends DolibarrApi // phpcs:enable $object = parent::_cleanObjectDatas($object); + unset($object->statut); + unset($object->regeximgext); unset($object->price_by_qty); unset($object->prices_by_qty_id); @@ -1906,8 +1912,39 @@ class Products extends DolibarrApi unset($object->firstname); unset($object->lastname); unset($object->civility_id); + unset($object->contact); + unset($object->contact_id); + unset($object->thirdparty); + unset($object->user); + unset($object->origin); + unset($object->origin_id); + unset($object->fourn_pu); + unset($object->fourn_price_base_type); + unset($object->fourn_socid); + unset($object->ref_fourn); + unset($object->ref_supplier); + unset($object->product_fourn_id); + unset($object->fk_project); + unset($object->mode_reglement_id); + unset($object->cond_reglement_id); + unset($object->demand_reason_id); + unset($object->transport_mode_id); + unset($object->cond_reglement); + unset($object->shipping_method_id); + unset($object->model_pdf); + unset($object->note); + + unset($object->nbphoto); unset($object->recuperableonly); + unset($object->multiprices_recuperableonly); + unset($object->tva_npr); + unset($object->lines); + unset($object->fk_bank); + unset($object->fk_account); + + unset($object->supplierprices); // Mut use another API to get them + return $object; } @@ -1942,14 +1979,15 @@ class Products extends DolibarrApi * @param int $includestockdata Load also information about stock (slower) * @param bool $includesubproducts Load information about subproducts (if product is a virtual product) * @param bool $includeparentid Load also ID of parent product (if product is a variant of a parent product) - * @param bool $includeifobjectisused Check if product object is used and set is_object_used with result. + * @param bool $includeifobjectisused Check if product object is used and set property 'is_object_used' with result. + * @param bool $includetrans Load also the translations of product label and description * @return array|mixed Data without useless information * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ - private function _fetch($id, $ref = '', $ref_ext = '', $barcode = '', $includestockdata = 0, $includesubproducts = false, $includeparentid = false, $includeifobjectisused = false) + private function _fetch($id, $ref = '', $ref_ext = '', $barcode = '', $includestockdata = 0, $includesubproducts = false, $includeparentid = false, $includeifobjectisused = false, $includetrans = false) { if (empty($id) && empty($ref) && empty($ref_ext) && empty($barcode)) { throw new RestException(400, 'bad value for parameter id, ref, ref_ext or barcode'); @@ -1961,7 +1999,7 @@ class Products extends DolibarrApi throw new RestException(403); } - $result = $this->product->fetch($id, $ref, $ref_ext, $barcode); + $result = $this->product->fetch($id, $ref, $ref_ext, $barcode, 0, 0, ($includetrans ? 0 : 1)); if (!$result) { throw new RestException(404, 'Product not found'); } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index b359d7629b7..22e28001743 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -330,13 +330,6 @@ class Product extends CommonObject */ public $barcode_type_code; - /** - * Additional barcodes (Some products have different barcodes according to the country of origin of manufacture) - * - * @var array - */ - public $barcodes_extra = array(); - public $stats_propale = array(); public $stats_commande = array(); public $stats_contrat = array(); @@ -2237,7 +2230,7 @@ class Product extends CommonObject if ($separatedStock) { $sql .= " AND sp.fk_entrepot IN ( SELECT rowid - FROM ".MAIN_DB_PREFIX."entrepot WHERE entity IN (" . $this->db->sanitize($visibleWarehousesEntities) ."))"; + FROM ".MAIN_DB_PREFIX."entrepot WHERE entity IN (".$this->db->sanitize($visibleWarehousesEntities)."))"; } @@ -2336,11 +2329,10 @@ class Product extends CommonObject $this->db->free($resql); - // Retrieve all extrafield // fetch optionals attributes and labels $this->fetch_optionals(); - // multilangs + // Multilangs if (!empty($conf->global->MAIN_MULTILANGS) && empty($ignore_lang_load)) { $this->getMultiLangs(); } diff --git a/htdocs/user/card.php b/htdocs/user/card.php index b1a9a229827..8b31f8b544b 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -240,10 +240,12 @@ if (empty($reshook)) { //$object->twitter = GETPOST("twitter", 'alphanohtml'); //$object->facebook = GETPOST("facebook", 'alphanohtml'); //$object->linkedin = GETPOST("linkedin", 'alphanohtml'); - $object->socialnetworks = array(); if (!empty($conf->socialnetworks->enabled)) { + $object->socialnetworks = array(); foreach ($socialnetworks as $key => $value) { - $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml'); + if (GETPOST($key, 'alphanohtml')) { + $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml'); + } } } @@ -400,10 +402,12 @@ if (empty($reshook)) { //$object->twitter = GETPOST("twitter", 'alphanohtml'); //$object->facebook = GETPOST("facebook", 'alphanohtml'); //$object->linkedin = GETPOST("linkedin", 'alphanohtml'); - $object->socialnetworks = array(); if (!empty($conf->socialnetworks->enabled)) { + $object->socialnetworks = array(); foreach ($socialnetworks as $key => $value) { - $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml'); + if (GETPOST($key, 'alphanohtml')) { + $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml'); + } } } $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alphanohtml')); From a665ff5bdacc55e52434d830e5d37d8c57abf81d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 11:51:39 +0200 Subject: [PATCH 10/25] Copy-Paste works also for hidden fields --- htdocs/core/lib/functions.lib.php | 22 ++++++++++++------- htdocs/theme/eldy/global.inc.php | 10 +++++++-- htdocs/theme/md/style.css.php | 17 ++++++++++++++- htdocs/user/card.php | 36 +++++++++++++++++-------------- 4 files changed, 58 insertions(+), 27 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ba953282d2d..970ec73e373 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3505,7 +3505,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'margin', 'map-marker-alt', 'member', 'meeting', 'money-bill-alt', 'movement', 'mrp', 'note', 'next', 'off', 'on', 'order', 'paiment', 'paragraph', 'play', 'pdf', 'phone', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'stock', 'resize', 'service', 'stats', 'trip', - 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'tools', 'unlink', 'uparrow', 'user', 'vcard', 'wrench', + 'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'tools', 'unlink', 'uparrow', 'user', 'vcard', 'wrench', 'github', 'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp', 'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', 'commercial', 'companies', 'generic', 'home', 'hrm', 'members', 'products', 'invoicing', @@ -3556,7 +3556,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'reception'=>'dolly', 'recruitmentjobposition'=>'id-card-alt', 'recruitmentcandidature'=>'id-badge', 'resize'=>'crop', 'supplier_order'=>'dol-order_supplier', 'supplier_proposal'=>'file-signature', 'refresh'=>'redo', 'resource'=>'laptop-house', - 'salary'=>'wallet', 'shipment'=>'dolly', 'stock'=>'box-open', 'stats' => 'chart-bar', 'split'=>'code-branch', 'stripe'=>'stripe-s', + 'security'=>'key', 'salary'=>'wallet', 'shipment'=>'dolly', 'stock'=>'box-open', 'stats' => 'chart-bar', 'split'=>'code-branch', 'stripe'=>'stripe-s', 'supplier'=>'building', 'supplier_invoice'=>'file-invoice-dollar', 'technic'=>'cogs', 'ticket'=>'ticket-alt', 'timespent'=>'clock', 'title_setup'=>'tools', 'title_accountancy'=>'money-check-alt', 'title_bank'=>'university', 'title_hrm'=>'umbrella-beach', 'title_agenda'=>'calendar-alt', @@ -3656,7 +3656,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'other'=>'#ddd', 'partnership'=>'#6c6aa8', 'playdisabled'=>'#ccc', 'printer'=>'#444', 'projectpub'=>'#986c6a', 'reception'=>'#a69944', 'resize'=>'#444', 'rss'=>'#cba', //'shipment'=>'#a69944', - 'stats'=>'#444', 'switch_off'=>'#999', 'technic'=>'#999', 'timespent'=>'#555', + 'security'=>'#999', 'stats'=>'#444', 'switch_off'=>'#999', 'technic'=>'#999', 'timespent'=>'#555', 'uncheck'=>'#800', 'uparrow'=>'#555', 'user-cog'=>'#999', 'country'=>'#aaa', 'globe-americas'=>'#aaa', 'website'=>'#304', 'workstation'=>'#a69944' ); @@ -10232,14 +10232,20 @@ function readfileLowMemory($fullpath_original_file_osencoded, $method = -1) } /** - * Create a button to copy $valuetoprint in the clipboard + * Create a button to copy $valuetocopy in the clipboard * - * @param string $valuetoprint The value to print - * @param int $showonlyonhover Show the copypaste button only on hover + * @param string $valuetocopy The value to print + * @param int $showonlyonhover Show the copy-paste button only on hover + * @param string $texttoshow Replace the value to show with this text * @return string The string to print for the button */ -function showValueWithClipboardCPButton($valuetoprint, $showonlyonhover = 1) +function showValueWithClipboardCPButton($valuetocopy, $showonlyonhover = 1, $texttoshow = '') { - $result = ''.$valuetoprint.''; + if ($texttoshow) { + $result = ''.$valuetocopy.''.$texttoshow.''; + } else { + $result = ''.$valuetocopy.''; + } + return $result; } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index e9a646d751f..912cf21a1de 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -4674,7 +4674,7 @@ table.dp { /* ============================================================================== */ -/* Afficher/cacher */ +/* Show/Hide */ /* ============================================================================== */ div.visible { @@ -6763,9 +6763,15 @@ div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before /* ============================================================================== */ -/* For copypaste feature */ +/* For copy-paste feature */ /* ============================================================================== */ +span.clipboardCPValue.hidewithsize { + width: 0 !important; + display: inline-block; + color: transparent; +} + .clipboardCPShowOnHover .clipboardCPButton { display: none; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 0b09b141258..8152e56e945 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4583,7 +4583,7 @@ table.dp { /* ============================================================================== */ -/* Afficher/cacher */ +/* Show/Hide */ /* ============================================================================== */ div.visible { @@ -6606,6 +6606,21 @@ div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before } +/* ============================================================================== */ +/* For copy-paste feature */ +/* ============================================================================== */ + +span.clipboardCPValue.hidewithsize { + width: 0 !important; + display: inline-block; + color: transparent; +} + +.clipboardCPShowOnHover .clipboardCPButton { + display: none; +} + + /* ============================================================================== */ /* CSS style used for small screen */ /* ============================================================================== */ diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 8b31f8b544b..332c98f56da 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1573,7 +1573,7 @@ if ($action == 'create' || $action == 'adduserldap') { // Color user if (!empty($conf->agenda->enabled)) { - print ''.$langs->trans("ColorUser").''; + print ''.$langs->trans("ColorUser").''; print ''; print $formother->showColor($object->color, ''); print ''; @@ -1582,7 +1582,7 @@ if ($action == 'create' || $action == 'adduserldap') { // Categories if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { - print ''.$langs->trans("Categories").''; + print ''.$langs->trans("Categories").''; print ''; print $form->showCategories($object->id, Categorie::TYPE_USER, 1); print ''; @@ -1591,7 +1591,7 @@ if ($action == 'create' || $action == 'adduserldap') { // Default language if (!empty($conf->global->MAIN_MULTILANGS)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - print ''.$langs->trans("DefaultLang").''; + print ''.$langs->trans("DefaultLang").''; //$s=picto_from_langcode($object->default_lang); //print ($s?$s.' ':''); $langs->load("languages"); @@ -1606,14 +1606,6 @@ if ($action == 'create' || $action == 'adduserldap') { print "\n"; } - print ''.$langs->trans("LastConnexion").''; - print ''.dol_print_date($object->datelastlogin, "dayhour").''; - print "\n"; - - print ''.$langs->trans("PreviousConnexion").''; - print ''.dol_print_date($object->datepreviouslogin, "dayhour").''; - print "\n"; - // Multicompany if (!empty($conf->multicompany->enabled) && is_object($mc)) { // This is now done with hook formObjectOptions. Keep this code for backward compatibility with old multicompany module @@ -1698,13 +1690,13 @@ if ($action == 'create' || $action == 'adduserldap') { print "\n"; - + // Credentials print '
'; - print ''; + print '
'; print ''; - print ''; + print ''; print ''; // Date login validity @@ -1779,13 +1771,25 @@ if ($action == 'create' || $action == 'adduserldap') { print ''; print ''; } + + print ''; + print ''; + print "\n"; + print '
'; - print $langs->trans("Credentials"); + print img_picto('', 'security', 'class="paddingleft pictofixedwidth"').$langs->trans("Credentials"); print '
'.$langs->trans("ApiKey").''; if (!empty($object->api_key)) { - print ''.preg_replace('/./', '*', $object->api_key).''; + print ''; + print showValueWithClipboardCPButton($object->api_key, 1, $langs->trans("Hidden")); + print ''; } if ($user->admin || $user->id == $object->id) { // TODO Add a feature to reveal the hash } print '
'.$langs->trans("LastConnexion").''; + if ($object->datepreviouslogin) { + print dol_print_date($object->datepreviouslogin, "dayhour").' ('.$langs->trans("Previous").'), '; + } + print dol_print_date($object->datelastlogin, "dayhour").' ('.$langs->trans("Current").')'; + print '
'; print ''; From a5ad604fe23e59ff99d107a5d756ed6f275b9be1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 11:52:57 +0200 Subject: [PATCH 11/25] changelog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a618b8a14fe..bb44e0fa0be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,7 @@ NEW: Add a security center page with all information and advices related to the NEW: Add a performance center page with all information and advices related to the performance of your instance NEW: A lot of fix into english text after a small proofreading campaign (still not perfect, but really better) NEW: All main menu entries are using the picto of the module +NEW: Add a copy to clipboard button on some fields NEW: Add an example of scheduled job to send email reminder for unpayed invoices NEW: Accountancy - Add FEC import NEW: Accountancy - Add a confirmation form with options on export @@ -135,7 +136,6 @@ NEW: Add data-eec=1 for EEC countries on select for js interaction NEW: Add experimental repair script to switch to dynamic row format and utf8mb4 encoding NEW: add form confirm hook on company card NEW: Add function showValueWithClipboardCPButton() to add a copy/paste -NEW: Add function showValueWithCopyAndPasteButton() to add a copy/paste NEW: Add hook addSectionECMAuto method to add custom diretory into ECM auto files NEW: Add native compression in rest apis NEW: Product Variants API, add variant stock to response by parameter From 866c9d012fa08a66e39d004b9988e0cc96c40b7a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 14:19:12 +0200 Subject: [PATCH 12/25] Fix fetch for customer and vendor relative discount --- htdocs/societe/class/societe.class.php | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index defcc71a3e5..946ceeb42f3 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -480,6 +480,7 @@ class Societe extends CommonObject public $remise_percent; public $remise_supplier_percent; + public $mode_reglement_supplier_id; public $cond_reglement_supplier_id; public $transport_mode_supplier_id; @@ -1636,14 +1637,14 @@ class Societe extends CommonObject $sql .= ', s.fk_typent as typent_id'; $sql .= ', s.fk_effectif as effectif_id'; $sql .= ', s.fk_forme_juridique as forme_juridique_code'; - $sql .= ', s.webservices_url, s.webservices_key'; + $sql .= ', s.webservices_url, s.webservices_key, s.model_pdf'; if (empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { $sql .= ', s.accountancy_code_buy, s.accountancy_code_sell'; } else { $sql .= ', spe.accountancy_code_buy, spe.accountancy_code_sell'; } $sql .= ', s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.parent, s.barcode'; - $sql .= ', s.fk_departement as state_id, s.fk_pays as country_id, s.fk_stcomm, s.remise_supplier, s.mode_reglement, s.cond_reglement, s.transport_mode'; + $sql .= ', s.fk_departement as state_id, s.fk_pays as country_id, s.fk_stcomm, s.mode_reglement, s.cond_reglement, s.transport_mode'; $sql .= ', s.fk_account, s.tva_assuj'; $sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.transport_mode_supplier'; $sql .= ', s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo, s.logo_squarred'; @@ -1659,7 +1660,11 @@ class Societe extends CommonObject $sql .= ', st.libelle as stcomm, st.picto as stcomm_picto'; $sql .= ', te.code as typent_code'; $sql .= ', i.libelle as label_incoterms'; - $sql .= ', sr.remise_client, model_pdf'; + if (empty($conf->multicompany->enabled)) { + $sql .= ', s.remise_client, s.remise_supplier'; + } else { + $sql .= ', sr.remise_client, sr2.remise_supplier'; + } $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); @@ -1672,8 +1677,12 @@ class Societe extends CommonObject $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_regions as r ON d.fk_region = r.code_region '; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as te ON s.fk_typent = te.id'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON s.fk_incoterms = i.rowid'; - $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_remise as sr ON sr.rowid = (SELECT MAX(rowid) FROM '.MAIN_DB_PREFIX.'societe_remise WHERE fk_soc = s.rowid AND entity IN ('.getEntity('discount').'))'; - + // With default setup, llx_societe_remise is a history table in default setup and current value is in llx_societe. + // We use it for real value when multicompany is on. A better place would be into llx_societe_perentity. + if (!empty($conf->multicompany->enabled)) { + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_remise as sr ON sr.rowid = (SELECT MAX(rowid) FROM '.MAIN_DB_PREFIX.'societe_remise WHERE fk_soc = s.rowid AND entity IN ('.getEntity('discount').'))'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_remise_supplier as sr2 ON sr2.rowid = (SELECT MAX(rowid) FROM '.MAIN_DB_PREFIX.'societe_remise_supplier WHERE fk_soc = s.rowid AND entity IN ('.getEntity('discount').'))'; + } $sql .= ' WHERE s.entity IN ('.getEntity($this->element).')'; if ($rowid) { $sql .= ' AND s.rowid = '.((int) $rowid); @@ -1809,6 +1818,7 @@ class Societe extends CommonObject $this->remise_percent = $obj->remise_client ? price2num($obj->remise_client) : 0; // 0.000000 must be 0 $this->remise_supplier_percent = $obj->remise_supplier; + $this->mode_reglement_id = $obj->mode_reglement; $this->cond_reglement_id = $obj->cond_reglement; $this->transport_mode_id = $obj->transport_mode; From 75bd4405915dadb8eb0aa8314b7590570dbcf2ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 18:29:02 +0200 Subject: [PATCH 13/25] Trans --- htdocs/langs/en_US/stocks.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 5960f900cca..ddb94c70279 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -249,7 +249,7 @@ SelectAStockMovementFileToImport=select a stock movement file to import InfoTemplateImport=Uploaded file needs to have this format (* are mandatory fields):
Source Warehouse* | Target Warehouse* | Product* | Quantity* | Lot/serial number
CSV character separator must be "%s" LabelOfInventoryMovemement=Inventory %s ReOpen=Reopen -ConfirmFinish=Do you confirm the closing of the inventory ? This will generate all stock movements to update your stock. +ConfirmFinish=Do you confirm the closing of the inventory ? This will generate all stock movements to update your stock to the real qty you entered into the inventory. ObjectNotFound=%s not found MakeMovementsAndClose=Generate movements and close AutofillWithExpected=Fill real quantity with expected quantity \ No newline at end of file From aa2d85276ec285cfa03a344b68166800d4d0ccc1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 18:38:22 +0200 Subject: [PATCH 14/25] Debug v14 --- htdocs/core/class/html.formother.class.php | 4 ++-- htdocs/install/fileconf.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index ba3ff77d394..46858191c7b 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -88,8 +88,8 @@ class FormOther */ $out .= '
'; $out .= '
'; - $out .= ''; - $out .= ''; + $out .= ''; + $out .= ''; $out .= '
'; $out .= ''.$langs->trans("FeatureNotYetAvailable").''; diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php index 3f2e714640a..42c8d3459fe 100644 --- a/htdocs/install/fileconf.php +++ b/htdocs/install/fileconf.php @@ -33,7 +33,7 @@ global $langs; $err = 0; -$setuplang = GETPOST("selectlang", '', 3) ? GETPOST("selectlang", '', 3) : (GETPOST('lang', 'alpha', 1) ? GETPOST('lang', 'alpha', 1) : 'auto'); +$setuplang = GETPOST("selectlang", 'alpha', 3) ? GETPOST("selectlang", 'alpha', 3) : (GETPOST('lang', 'alpha', 1) ? GETPOST('lang', 'alpha', 1) : 'auto'); $langs->setDefaultLang($setuplang); $langs->loadLangs(array("install", "errors")); From f504cbcec4865106017066ea0c7038f84d5ca1c1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 19:18:51 +0200 Subject: [PATCH 15/25] Fix log --- htdocs/core/class/utils.class.php | 2 +- htdocs/langs/en_US/errors.lang | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 9534970a856..d2987e8fc63 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -354,7 +354,7 @@ class Utils $execmethod = 1; } - dol_syslog("Utils::dumpDatabase execmethod=".$execmethod." command:".$fullcommandcrypted, LOG_DEBUG); + dol_syslog("Utils::dumpDatabase execmethod=".$execmethod." command:".$fullcommandcrypted, LOG_INFO); // TODO Replace with executeCLI function if ($execmethod == 1) { diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index a1155b0f57c..f2d9106107b 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -117,7 +117,7 @@ ErrorCantReadFile=Failed to read file '%s' ErrorCantReadDir=Failed to read directory '%s' ErrorBadLoginPassword=Bad value for login or password ErrorLoginDisabled=Your account has been disabled -ErrorFailedToRunExternalCommand=Failed to run external command. Check it is available and runnable by your PHP server. If PHP Safe Mode is enabled, check that command is inside a directory defined by parameter safe_mode_exec_dir. +ErrorFailedToRunExternalCommand=Failed to run external command. Check it is available and runnable by your PHP server user. Check also the command is not protected on shell level by a security layer like apparmor. ErrorFailedToChangePassword=Failed to change password ErrorLoginDoesNotExists=User with login %s could not be found. ErrorLoginHasNoEmail=This user has no email address. Process aborted. From 9eda9c1e21e61363461dc23c967e855f86dacc3e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 19:55:16 +0200 Subject: [PATCH 16/25] Enhance setup --- htdocs/admin/system/security.php | 33 +++++++++++++++++++++++++++++++- htdocs/langs/en_US/admin.lang | 4 +++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index d8dd21719fd..36f08309e02 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -40,6 +40,8 @@ if (GETPOST('action', 'aZ09') == 'donothing') { exit; } +$execmethod = empty($conf->global->MAIN_EXEC_USE_POPEN) ? 1 : $conf->global->MAIN_EXEC_USE_POPEN; + /* * View @@ -74,7 +76,13 @@ print "PHP allow_url_include = ".(ini_get('allow_url_include') print "PHP disable_functions = "; $arrayoffunctionsdisabled = explode(',', ini_get('disable_functions')); $arrayoffunctionstodisable = explode(',', 'pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals'); -$arrayoffunctionstodisable2 = explode(',', 'exec,passthru,shell_exec,system,proc_open,popen'); +if ($execmethod == 1) { + $arrayoffunctionstodisable2 = explode(',', 'passthru,shell_exec,system,proc_open,popen'); + $functiontokeep = 'exec'; +} else { + $arrayoffunctionstodisable2 = explode(',', 'exec,passthru,shell_exec,system,proc_open'); + $functiontokeep = 'popen'; +} $i = 0; foreach ($arrayoffunctionsdisabled as $functionkey) { if ($i > 0) { @@ -115,6 +123,13 @@ if ($todisabletext) { print '
'; } +print $langs->trans("PHPFunctionsRequiredForCLI").': '; +if (in_array($functiontokeep, $arrayoffunctionsdisabled)) { + print img_picto($langs->trans("PHPFunctionsRequiredForCLI"), 'warning'); +} +print ''.$functiontokeep.''; +print '
'; + print '
'; // XDebug @@ -245,6 +260,22 @@ print 'MAIN_SECURITY_ANTI_SSRF_SERVER_IP = '.(empty($conf->glob print '
'; +print 'MAIN_EXEC_USE_POPEN = '; +if (empty($conf->global->MAIN_EXEC_USE_POPEN)) { + print ''.$langs->trans("Undefined").'   '; +} else { + print $conf->global->MAIN_EXEC_USE_POPEN.'   '; +} +if ($execmethod == 1) { + print ' --> "exec" PHP method will be used for shell commands.'; +} +if ($execmethod == 2) { + print ' --> "popen" PHP method will be used for shell commands.'; +} +print "
"; +print '
'; + + print ''.$langs->trans("AntivirusEnabledOnUpload").': '; print empty($conf->global->MAIN_ANTIVIRUS_COMMAND) ? '' : img_picto('', 'tick').' '; print yn($conf->global->MAIN_ANTIVIRUS_COMMAND ? 1 : 0); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 9f4bcfcfbd4..467fba89199 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2127,7 +2127,8 @@ ConfFileIsReadableOrWritableByAnyUsers=The conf file is readable or writable by MailToSendEventOrganization=Event Organization AGENDA_EVENT_DEFAULT_STATUS=Default event status when creating a event from the form YouShouldDisablePHPFunctions=You should disable PHP functions -IfCLINotRequiredYouShouldDisablePHPFunctions=Except if you need to run system commands (for the module Scheduled job, or to run the external command line Anti-virus for example), you shoud disable PHP functions +IfCLINotRequiredYouShouldDisablePHPFunctions=Except if you need to run system commands in custom code, you shoud disable PHP functions +PHPFunctionsRequiredForCLI=For shell purpose (like scheduled job backup or running an anitivurs program), you must keep PHP functions NoWritableFilesFoundIntoRootDir=No writable files or directories of the common programs were found into your root directory (Good) RecommendedValueIs=Recommended: %s NotRecommended=Not recommanded @@ -2137,3 +2138,4 @@ CheckForModuleUpdateHelp=This action will connect to editors of external modules ModuleUpdateAvailable=An update is available NoExternalModuleWithUpdate=No updates found for external modules SwaggerDescriptionFile=Swagger API description file (for use with redoc for example) +YouEnableDeprecatedWSAPIsUseRESTAPIsInstead=You enabled deprecated WS API. You should use REST API instead. \ No newline at end of file From 19a203bd401599fca0523803dd7a9e4e44698dd6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 22:09:06 +0200 Subject: [PATCH 17/25] Fix amount of memberships --- .../adherents/class/adherent_type.class.php | 2 +- htdocs/adherents/stats/index.php | 4 +-- htdocs/adherents/type.php | 29 ++++++++++--------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 2ffc1e2c9fd..0104f8f36e8 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -366,7 +366,7 @@ class AdherentType extends CommonObject $sql .= "libelle = '".$this->db->escape($this->label)."',"; $sql .= "morphy = '".$this->db->escape($this->morphy)."',"; $sql .= "subscription = '".$this->db->escape($this->subscription)."',"; - $sql .= "amount = '".$this->db->escape($this->amount)."',"; + $sql .= "amount = ".((empty($this->amount) && $this->amount == '') ? 'null' : ((float) $this->amount)).","; $sql .= "duration = '".$this->db->escape($this->duration_value.$this->duration_unit)."',"; $sql .= "note = '".$this->db->escape($this->note)."',"; $sql .= "vote = ".(integer) $this->db->escape($this->vote).","; diff --git a/htdocs/adherents/stats/index.php b/htdocs/adherents/stats/index.php index 11c0025dcc5..e820d0a0d23 100644 --- a/htdocs/adherents/stats/index.php +++ b/htdocs/adherents/stats/index.php @@ -198,8 +198,8 @@ foreach ($data as $val) { //print ''; print ''; print ''.$val['nb'].''; - print ''.price(price2num($val['total'], 'MT'), 1).''; - print ''.price(price2num($val['avg'], 'MT'), 1).''; + print ''.price(price2num($val['total'], 'MT'), 1).''; + print ''.price(price2num($val['avg'], 'MT'), 1).''; print ''; $oldyear = $year; } diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 6c4f63725e1..033592a9afc 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -71,7 +71,7 @@ $label = GETPOST("label", "alpha"); $morphy = GETPOST("morphy", "alpha"); $status = GETPOST("status", "int"); $subscription = GETPOST("subscription", "int"); -$amount = price2num(GETPOST('amount', 'alpha'), 'MT'); +$amount = GETPOST('amount', 'alpha'); $duration_value = GETPOST('duration_value', 'int'); $duration_unit = GETPOST('duration_unit', 'alpha'); $vote = GETPOST("vote", "int"); @@ -119,7 +119,7 @@ if ($action == 'add' && $user->rights->adherent->configurer) { $object->morphy = trim($morphy); $object->status = (int) $status; $object->subscription = (int) $subscription; - $object->amount = $amount; + $object->amount = ($amount == '' ? '' : price2num($amount, 'MT')); $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->note = trim($comment); @@ -166,12 +166,11 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->fetch($rowid); $object->oldcopy = clone $object; - $object->label= trim($label); $object->morphy = trim($morphy); $object->status = (int) $status; $object->subscription = (int) $subscription; - $object->amount = $amount; + $object->amount = ($amount == '' ? '' : price2num($amount, 'MT'));; $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->note = trim($comment); @@ -306,7 +305,7 @@ if (!$rowid && $action != 'create' && $action != 'edit') { } print ''; print ''.yn($objp->subscription).''; - print ''.price($objp->amount).''; + print ''.(is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount)).''; print ''.yn($objp->vote).''; print ''.$membertype->getLibStatut(5).''; if ($user->rights->adherent->configurer) { @@ -446,7 +445,7 @@ if ($rowid > 0) { print ''; print ''.$langs->trans("Amount").''; - print price($object->amount); + print ((is_null($object->amount) || $object->amount === '') ? '' : price($object->amount)); print ''; print ''.$langs->trans("VoteAllowed").''; @@ -594,24 +593,24 @@ if ($rowid > 0) { $titre .= " (".$membertype->label.")"; } - $param = "&rowid=".$object->id; + $param = "&rowid=".urlencode($object->id); if (!empty($status)) { - $param .= "&status=".$status; + $param .= "&status=".urlencode($status); } if (!empty($search_lastname)) { - $param .= "&search_lastname=".$search_lastname; + $param .= "&search_lastname=".urlencode($search_lastname); } if (!empty($search_firstname)) { - $param .= "&search_firstname=".$search_firstname; + $param .= "&search_firstname=".urlencode($search_firstname); } if (!empty($search_login)) { - $param .= "&search_login=".$search_login; + $param .= "&search_login=".urlencode($search_login); } if (!empty($search_email)) { - $param .= "&search_email=".$search_email; + $param .= "&search_email=".urlencode($search_email); } if (!empty($filter)) { - $param .= "&filter=".$filter; + $param .= "&filter=".urlencode($filter); } if ($sall) { @@ -797,7 +796,9 @@ if ($rowid > 0) { print ''; print ''.$langs->trans("Amount").''; - print ''; + print ''; print ''; print ''.$langs->trans("VoteAllowed").''; From ba6e675273cc72259dbfa2a76e7a9dc83ffd1727 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 22:21:20 +0200 Subject: [PATCH 18/25] css --- htdocs/compta/bank/various_payment/list.php | 13 ++++++------- htdocs/salaries/stats/index.php | 8 ++++---- htdocs/theme/md/style.css.php | 5 ++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/htdocs/compta/bank/various_payment/list.php b/htdocs/compta/bank/various_payment/list.php index 5e6d199db0a..f78e004f571 100644 --- a/htdocs/compta/bank/various_payment/list.php +++ b/htdocs/compta/bank/various_payment/list.php @@ -338,14 +338,13 @@ if ($result) { if ($search_accountancy_subledger > 0) { $param .= '&search_accountancy_subledger='.urlencode($search_accountancy_subledger); } - if ($optioncss != '') { - $param .= '&optioncss='.urlencode($optioncss); + $param .= '&optioncss='.urlencode($optioncss); } $url = DOL_URL_ROOT.'/compta/bank/various_payment/card.php?action=create'; if (!empty($socid)) { - $url .= '&socid='.$socid; + $url .= '&socid='.urlencode($socid); } $newcardbutton = dolGetButtonTitle($langs->trans('MenuNewVariousPayment'), '', 'fa fa-plus-circle', $url, '', $user->rights->banque->modifier); @@ -423,7 +422,7 @@ if ($result) { // Payment type if ($arrayfields['type']['checked']) { - print ''; + print ''; $form->select_types_paiements($typeid, 'typeid', '', 0, 1, 1, 16, 1, 'maxwidth100'); print ''; } @@ -498,7 +497,7 @@ if ($result) { print_liste_field_titre($arrayfields['ref']['label'], $_SERVER["PHP_SELF"], 'v.rowid', '', $param, '', $sortfield, $sortorder); } if ($arrayfields['label']['checked']) { - print_liste_field_titre($arrayfields['label']['label'], $_SERVER["PHP_SELF"], 'v.label', '', $param, '', $sortfield, $sortorder, 'left '); + print_liste_field_titre($arrayfields['label']['label'], $_SERVER["PHP_SELF"], 'v.label', '', $param, '', $sortfield, $sortorder); } if ($arrayfields['datep']['checked']) { print_liste_field_titre($arrayfields['datep']['label'], $_SERVER["PHP_SELF"], 'v.datep,v.rowid', '', $param, '', $sortfield, $sortorder, 'center '); @@ -507,7 +506,7 @@ if ($result) { print_liste_field_titre($arrayfields['datev']['label'], $_SERVER["PHP_SELF"], 'v.datev,v.rowid', '', $param, '', $sortfield, $sortorder, 'center '); } if ($arrayfields['type']['checked']) { - print_liste_field_titre($arrayfields['type']['label'], $_SERVER["PHP_SELF"], 'type', '', $param, '', $sortfield, $sortorder, 'left '); + print_liste_field_titre($arrayfields['type']['label'], $_SERVER["PHP_SELF"], 'type', '', $param, '', $sortfield, $sortorder, 'center '); } if ($arrayfields['project']['checked']) { print_liste_field_titre($arrayfields['project']['label'], $_SERVER["PHP_SELF"], 'fk_project', '', $param, '', $sortfield, $sortorder); @@ -590,7 +589,7 @@ if ($result) { // Type if ($arrayfields['type']['checked']) { - print ''; + print ''; if ($obj->payment_code) { print $langs->trans("PaymentTypeShort".$obj->payment_code); print ' '; diff --git a/htdocs/salaries/stats/index.php b/htdocs/salaries/stats/index.php index 1fe914d38c2..1a7f2de6d39 100644 --- a/htdocs/salaries/stats/index.php +++ b/htdocs/salaries/stats/index.php @@ -238,16 +238,16 @@ foreach ($data as $val) { print ''; print ''.$oldyear.''; print '0'; - print '0'; - print '0'; + print '0'; + print '0'; print ''; } print ''; print ''.$year.''; print ''.$val['nb'].''; - print ''.price(price2num($val['total'], 'MT'), 1).''; - print ''.price(price2num($val['avg'], 'MT'), 1).''; + print ''.price(price2num($val['total'], 'MT'), 1).''; + print ''.price(price2num($val['avg'], 'MT'), 1).''; print ''; $oldyear = $year; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 8152e56e945..06e05a542ee 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -369,7 +369,7 @@ select.vmenusearchselectcombo { background-color: unset; } -textarea:focus, button:focus { +textarea:focus { /* v6 box-shadow: 0 0 4px #8091BF; */ border: 1px solid #aaa !important; } @@ -738,6 +738,9 @@ div.floatright .largenumber { font-size: 1.4em; } +button:focus { + outline: none; +} th .button { -webkit-box-shadow: none !important; From 5e0f2f9781dab1facea07442917a73bf8b4745f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 22:35:21 +0200 Subject: [PATCH 19/25] Debug v14. Fix regression. --- .../install/mysql/migration/13.0.0-14.0.0.sql | 4 ++ .../install/mysql/tables/llx_product_lot.sql | 3 ++ .../product/stock/class/productlot.class.php | 38 +++++++++---------- htdocs/theme/md/style.css.php | 2 +- 4 files changed, 25 insertions(+), 22 deletions(-) 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 index 37719c015c5..da2cd34fa00 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -64,6 +64,10 @@ ALTER TABLE llx_export_model MODIFY COLUMN type varchar(64); -- For v14 +ALTER TABLE llx_product_lot ADD COLUMN eol_date datetime NULL; +ALTER TABLE llx_product_lot ADD COLUMN manufacturing_date datetime NULL; +ALTER TABLE llx_product_lot ADD COLUMN scrapping_date datetime NULL; + create table llx_accounting_groups_account ( rowid integer AUTO_INCREMENT PRIMARY KEY, diff --git a/htdocs/install/mysql/tables/llx_product_lot.sql b/htdocs/install/mysql/tables/llx_product_lot.sql index 86cca7d0f04..f8d02f19ccb 100644 --- a/htdocs/install/mysql/tables/llx_product_lot.sql +++ b/htdocs/install/mysql/tables/llx_product_lot.sql @@ -24,6 +24,9 @@ CREATE TABLE llx_product_lot ( batch varchar(128) DEFAULT NULL, -- Lot or serial number eatby date DEFAULT NULL, -- Eatby date sellby date DEFAULT NULL, -- Sellby date + eol_date datetime NULL, + manufacturing_date datetime NULL, + scrapping_date datetime NULL, datec datetime, tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_user_creat integer, diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index f05a4ae3d39..2a3b3cf2e20 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -91,11 +91,11 @@ class Productlot extends CommonObject 'batch' => array('type'=>'varchar(30)', 'label'=>'Batch', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'comment'=>'Batch', 'searchall'=>1), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>20), 'sellby' => array('type'=>'date', 'label'=>'SellByDate', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_SELLBY)?1:0', 'visible'=>5, 'position'=>60), - 'eol_date' => array('type'=>'date', 'label'=>'EndOfLife', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_TRACEABILITY)?1:0', 'visible'=>5, 'position'=>70), - 'manufacturing_date' => array('type'=>'date', 'label'=>'ManufacturingDate', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_TRACEABILITY)?1:0', 'visible'=>5, 'position'=>80), - 'scrapping_date' => array('type'=>'date', 'label'=>'DestructionDate', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_TRACEABILITY)?1:0', 'visible'=>5, 'position'=>90), - 'commissionning_date' => array('type'=>'date', 'label'=>'FirstUseDate', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_TRACEABILITY)?1:0', 'visible'=>5, 'position'=>100), - 'qc_frequency' => array('type'=>'varchar(6)', 'label'=>'QCFrequency', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_TRACEABILITY)?1:0', 'visible'=>5, 'position'=>110), + 'eol_date' => array('type'=>'date', 'label'=>'EndOfLife', 'enabled'=>'empty($conf->global->PRODUCT_ENABLE_TRACEABILITY)?0:1', 'visible'=>5, 'position'=>70), + 'manufacturing_date' => array('type'=>'date', 'label'=>'ManufacturingDate', 'enabled'=>'empty($conf->global->PRODUCT_ENABLE_TRACEABILITY)?0:1', 'visible'=>5, 'position'=>80), + 'scrapping_date' => array('type'=>'date', 'label'=>'DestructionDate', 'enabled'=>'empty($conf->global->PRODUCT_ENABLE_TRACEABILITY)?0:1', 'visible'=>5, 'position'=>90), + //'commissionning_date' => array('type'=>'date', 'label'=>'FirstUseDate', 'enabled'=>'empty($conf->global->PRODUCT_ENABLE_TRACEABILITY)?0:1', 'visible'=>5, 'position'=>100), + //'qc_frequency' => array('type'=>'varchar(6)', 'label'=>'QCFrequency', 'enabled'=>'empty($conf->global->PRODUCT_ENABLE_QUALITYCONTROL)?1:0', 'visible'=>5, 'position'=>110), 'eatby' => array('type'=>'date', 'label'=>'EatByDate', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_EATBY)?1:0', 'visible'=>5, 'position'=>62), 'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>500), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501), @@ -120,8 +120,8 @@ class Productlot extends CommonObject public $eol_date = ''; public $manufacturing_date = ''; public $scrapping_date = ''; - public $commissionning_date = ''; - public $qc_frequency = ''; + //public $commissionning_date = ''; + //public $qc_frequency = ''; public $datec = ''; public $tms = ''; @@ -184,8 +184,6 @@ class Productlot extends CommonObject $this->import_key = trim($this->import_key); } - - // Check parameters // Put here code to add control on parameters values @@ -199,8 +197,8 @@ class Productlot extends CommonObject $sql .= 'eol_date,'; $sql .= 'manufacturing_date,'; $sql .= 'scrapping_date,'; - $sql .= 'commissionning_date,'; - $sql .= 'qc_frequency,'; + //$sql .= 'commissionning_date,'; + //$sql .= 'qc_frequency,'; $sql .= 'datec,'; $sql .= 'fk_user_creat,'; $sql .= 'fk_user_modif,'; @@ -214,9 +212,8 @@ class Productlot extends CommonObject $sql .= ' '.(!isset($this->eol_date) || dol_strlen($this->eol_date) == 0 ? 'NULL' : "'".$this->db->idate($this->eol_date)."'").','; $sql .= ' '.(!isset($this->manufacturing_date) || dol_strlen($this->manufacturing_date) == 0 ? 'NULL' : "'".$this->db->idate($this->manufacturing_date)."'").','; $sql .= ' '.(!isset($this->scrapping_date) || dol_strlen($this->scrapping_date) == 0 ? 'NULL' : "'".$this->db->idate($this->scrapping_date)."'").','; - $sql .= ' '.(!isset($this->commissionning_date) || dol_strlen($this->commissionning_date) == 0 ? 'NULL' : "'".$this->db->idate($this->commissionning_date)."'").','; - $sql .= ' '.(!isset($this->qc_frequency) ? 'NULL' : $this->qc_frequency).','; - + //$sql .= ' '.(!isset($this->commissionning_date) || dol_strlen($this->commissionning_date) == 0 ? 'NULL' : "'".$this->db->idate($this->commissionning_date)."'").','; + //$sql .= ' '.(!isset($this->qc_frequency) ? 'NULL' : $this->qc_frequency).','; $sql .= ' '."'".$this->db->idate(dol_now())."'".','; $sql .= ' '.(!isset($this->fk_user_creat) ? 'NULL' : $this->fk_user_creat).','; $sql .= ' '.(!isset($this->fk_user_modif) ? 'NULL' : $this->fk_user_modif).','; @@ -292,8 +289,8 @@ class Productlot extends CommonObject $sql .= " t.eol_date,"; $sql .= " t.manufacturing_date,"; $sql .= " t.scrapping_date,"; - $sql .= " t.commissionning_date,"; - $sql .= " t.qc_frequency,"; + //$sql .= " t.commissionning_date,"; + //$sql .= " t.qc_frequency,"; $sql .= " t.datec,"; $sql .= " t.tms,"; $sql .= " t.fk_user_creat,"; @@ -322,11 +319,10 @@ class Productlot extends CommonObject $this->eatby = $this->db->jdate($obj->eatby); $this->sellby = $this->db->jdate($obj->sellby); $this->eol_date = $this->db->jdate($obj->eol_date); - $this->manufacturing_date = $this->db->jdate($obj->manufacturing_date); $this->scrapping_date = $this->db->jdate($obj->scrapping_date); - $this->commissionning_date = $this->db->jdate($obj->commissionning_date); - $this->qc_frequency = $obj->qc_frequency; + //$this->commissionning_date = $this->db->jdate($obj->commissionning_date); + //$this->qc_frequency = $obj->qc_frequency; $this->datec = $this->db->jdate($obj->datec); $this->tms = $this->db->jdate($obj->tms); @@ -407,8 +403,8 @@ class Productlot extends CommonObject $sql .= ' eol_date = '.(!isset($this->eol_date) || dol_strlen($this->eol_date) != 0 ? "'".$this->db->idate($this->eol_date)."'" : 'null').','; $sql .= ' manufacturing_date = '.(!isset($this->manufacturing_date) || dol_strlen($this->manufacturing_date) != 0 ? "'".$this->db->idate($this->manufacturing_date)."'" : 'null').','; $sql .= ' scrapping_date = '.(!isset($this->destruction_date) || dol_strlen($this->destruction_date) != 0 ? "'".$this->db->idate($this->destruction_date)."'" : 'null').','; - $sql .= ' commissionning_date = '.(!isset($this->first_use_date) || dol_strlen($this->first_use_date) != 0 ? "'".$this->db->idate($this->first_use_date)."'" : 'null').','; - $sql .= ' qc_frequency = '.(!isset($this->qc_frequency) || dol_strlen($this->qc_frequency) != 0 ? "'".$this->db->escape($this->qc_frequency)."'" : 'null').','; + //$sql .= ' commissionning_date = '.(!isset($this->first_use_date) || dol_strlen($this->first_use_date) != 0 ? "'".$this->db->idate($this->first_use_date)."'" : 'null').','; + //$sql .= ' qc_frequency = '.(!isset($this->qc_frequency) || dol_strlen($this->qc_frequency) != 0 ? "'".$this->db->escape($this->qc_frequency)."'" : 'null').','; $sql .= ' datec = '.(!isset($this->datec) || dol_strlen($this->datec) != 0 ? "'".$this->db->idate($this->datec)."'" : 'null').','; $sql .= ' tms = '.(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : "'".$this->db->idate(dol_now())."'").','; $sql .= ' fk_user_creat = '.(isset($this->fk_user_creat) ? $this->fk_user_creat : "null").','; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 06e05a542ee..5735837d665 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3836,7 +3836,7 @@ tr.liste_titre_sel th, th.liste_titre_sel, tr.liste_titre_sel td, td.liste_titre font-family: ; font-weight: normal; border-bottom: 1px solid #FDFFFF; - text-decoration: underline; + /* text-decoration: underline; */ } input.liste_titre { background: transparent; From 488f242e25bd7b87c05724b85704b96f710189c6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 22:42:10 +0200 Subject: [PATCH 20/25] css --- htdocs/product/list.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 073643fe235..eb3fc71d53a 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -586,7 +586,8 @@ if ($resql) { $paramsCat .= "&search_category_product_list[]=".urlencode($searchCategoryProduct); } - llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, 'classforhorizontalscrolloftabs'); + //llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, 'classforhorizontalscrolloftabs'); + llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, ''); // Displays product removal confirmation if (GETPOST('delprod')) { From 097f493315a798ef5ca210955bfe1ce0122bd542 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 22:43:47 +0200 Subject: [PATCH 21/25] css --- htdocs/theme/md/style.css.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 5735837d665..5d6bcf13a59 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -793,10 +793,19 @@ textarea.centpercent { color: #777; } +.flip { + transform: scaleX(-1) translate(2px, 0); +} +.rotate90 { + transform: rotate(90deg) translate(0, 2px); +} .center { text-align: center; margin: 0px auto; } +.alignstart { + text-align: start; +} .left { text-align: ; } From e47118108906ab9b6049a2dfda2d9167ae56ba9f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 22:52:50 +0200 Subject: [PATCH 22/25] css --- htdocs/theme/md/style.css.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 5d6bcf13a59..25df9b941ef 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4290,10 +4290,10 @@ div.divphotoref > a > .photowithmargin { /* Margin right for photo not inside a .photowithborder { border: 1px solid #f0f0f0; } -.photointoolitp { +.photointooltip { margin-top: 8px; margin-bottom: 6px; - text-align: center; + text-align: center !important; } .photodelete { margin-top: 6px !important; From 5917a9f73eca3681d0ea48258afc229ee899bc53 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 May 2021 23:08:52 +0200 Subject: [PATCH 23/25] Fix phpcs --- dev/setup/codesniffer/README | 5 +++++ htdocs/theme/md/style.css.php | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/dev/setup/codesniffer/README b/dev/setup/codesniffer/README index 087fb318f6f..2fdc66b9d1f 100644 --- a/dev/setup/codesniffer/README +++ b/dev/setup/codesniffer/README @@ -10,6 +10,11 @@ To run phpcs: > cd dolibarrgitrepo > phpcs --standard=dev/setup/codesniffer/ruleset.xml --extensions=php --parallel=8 . +To fix with phpcbf: +> cd dolibarrgitrepo +> phpcbf --standard=dev/setup/codesniffer/ruleset.xml --extensions=php --parallel=8 . + + Note with Eclipse: You must setup the PTI plugin of Eclipse into PHPCodeSniffer menu with: * tab value to 4 * path of code sniffer standard to dev/codesniffer diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 25df9b941ef..70a2ce1303e 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -6623,9 +6623,9 @@ div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before /* ============================================================================== */ span.clipboardCPValue.hidewithsize { - width: 0 !important; - display: inline-block; - color: transparent; + width: 0 !important; + display: inline-block; + color: transparent; } .clipboardCPShowOnHover .clipboardCPButton { From d1f36ec20cf530d0f93ae10cea2275669dcc0f6a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 13 May 2021 15:45:47 +0200 Subject: [PATCH 24/25] Fix phpcs --- htdocs/theme/eldy/global.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 912cf21a1de..3518518a5ef 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -6767,9 +6767,9 @@ div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before /* ============================================================================== */ span.clipboardCPValue.hidewithsize { - width: 0 !important; - display: inline-block; - color: transparent; + width: 0 !important; + display: inline-block; + color: transparent; } .clipboardCPShowOnHover .clipboardCPButton { From a9ddf2a5ad51be91b2769fdbcf6595fa8db5457b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 13 May 2021 19:07:47 +0200 Subject: [PATCH 25/25] Fix phpcs --- htdocs/product/class/product.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 22e28001743..16c72297e10 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -190,6 +190,10 @@ class Product extends CommonObject public $localtax1_type; public $localtax2_type; + public $lifetime; + + public $qc_frequency; + /** * Stock real *