From f620b165d3b87d4c7f25c495375cd2e613ce11cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Fri, 15 Nov 2019 22:17:53 +0100 Subject: [PATCH 01/84] API New get / add / remove product childs --- htdocs/product/class/api_products.class.php | 136 ++++++++++++++++++-- 1 file changed, 127 insertions(+), 9 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index f9a4a12b0df..c2f61604cd9 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -66,15 +66,16 @@ class Products extends DolibarrApi * * @param int $id ID of product * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesousproduits Load information about virtual product components * @return array|mixed Data without useless information * * @throws 401 * @throws 403 * @throws 404 */ - public function get($id, $includestockdata = 0) + public function get($id, $includestockdata = 0, $includesousproduits = false) { - return $this->_fetch($id, '', '', '', $includestockdata); + return $this->_fetch($id, '', '', '', $includestockdata, $includesousproduits); } /** @@ -84,6 +85,7 @@ class Products extends DolibarrApi * * @param string $ref Ref of element * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesousproduits Load information about virtual product components * * @return array|mixed Data without useless information * @@ -93,9 +95,9 @@ class Products extends DolibarrApi * @throws 403 * @throws 404 */ - public function getByRef($ref, $includestockdata = 0) + public function getByRef($ref, $includestockdata = 0, $includesousproduits = false) { - return $this->_fetch('', $ref, '', '', $includestockdata); + return $this->_fetch('', $ref, '', '', $includestockdata, $includesousproduits); } /** @@ -105,6 +107,7 @@ class Products extends DolibarrApi * * @param string $ref_ext Ref_ext of element * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesousproduits Load information about virtual product components * * @return array|mixed Data without useless information * @@ -114,9 +117,9 @@ class Products extends DolibarrApi * @throws 403 * @throws 404 */ - public function getByRefExt($ref_ext, $includestockdata = 0) + public function getByRefExt($ref_ext, $includestockdata = 0, $includesousproduits = false) { - return $this->_fetch('', '', $ref_ext, '', $includestockdata); + return $this->_fetch('', '', $ref_ext, '', $includestockdata, $includesousproduits); } /** @@ -126,6 +129,7 @@ class Products extends DolibarrApi * * @param string $barcode Barcode of element * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesousproduits Load information about virtual product components * * @return array|mixed Data without useless information * @@ -135,9 +139,9 @@ class Products extends DolibarrApi * @throws 403 * @throws 404 */ - public function getByBarcode($barcode, $includestockdata = 0) + public function getByBarcode($barcode, $includestockdata = 0, $includesousproduits = false) { - return $this->_fetch('', '', '', $barcode, $includestockdata); + return $this->_fetch('', '', '', $barcode, $includestockdata, $includesousproduits); } /** @@ -369,6 +373,105 @@ class Products extends DolibarrApi return $this->product->delete(DolibarrApiAccess::$user); } + + /** + * Get the list of children of the product. + * + * @param int $id Id of parent product/service + * @return array + * + * @throws RestException + * @throws 401 + * @throws 404 + * + * @url GET {id}/childs + */ + public function getChilds($id) + { + if(! DolibarrApiAccess::$user->rights->produit->lire) { + throw new RestException(401); + } + + if(! DolibarrApi::_checkAccessToResource('product', $id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $childsArbo = $this->product->getChildsArbo($id, 1); + + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; + $childs = []; + foreach ($childsArbo as $values) { + $childs[] = array_combine($keys, $values); + } + + return $childs; + } + + /** + * Add product child. + * + * Link a product/service to a parent product/service + * + * @param int $id Id of parent product/service + * @param int $id_fils Id of child product/service + * @param int $qty Quantity + * @param int $incdec 1=Increase/decrease stock of child when parent stock increase/decrease + * @return int + * + * @throws RestException + * @throws 401 + * @throws 404 + * + * @url POST {id}/childs/add + */ + public function addChild($id, $child_id, $qty, $incdec = 1) + { + if(! DolibarrApiAccess::$user->rights->produit->creer) { + throw new RestException(401); + } + + if(! DolibarrApi::_checkAccessToResource('product', $id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->product->add_sousproduit($id, $child_id, $qty, $incdec); + if ($result <= 0) { + throw new RestException(500, "Error adding product child"); + } + return $result; + } + + /** + * Remove product child. + * + * Unlink a product/service from a parent product/service + * + * @param int $id Id of parent product/service + * @param int $child_id Id of child product/service + * @return int + * + * @throws RestException + * @throws 401 + * @throws 404 + * + * @url DELETE {id}/childs/remove + */ + public function delChild($id, $child_id) + { + if(! DolibarrApiAccess::$user->rights->produit->creer) { + throw new RestException(401); + } + + if(! DolibarrApi::_checkAccessToResource('product', $id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->product->del_sousproduit($id, $child_id); + if ($result <= 0) { + throw new RestException(500, "Error while removing product child"); + } + return $result; + } /** @@ -753,13 +856,14 @@ class Products extends DolibarrApi * @param string $ref_ext Ref ext of element * @param string $barcode Barcode of element * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesousproduits Load information about virtual product components * @return array|mixed Data without useless information * * @throws 401 * @throws 403 * @throws 404 */ - private function _fetch($id, $ref = '', $ref_ext = '', $barcode = '', $includestockdata = 0) + private function _fetch($id, $ref = '', $ref_ext = '', $barcode = '', $includestockdata = 0, $includesousproduits = 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'); @@ -783,6 +887,20 @@ class Products extends DolibarrApi if ($includestockdata) { $this->product->load_stock(); } + + + + if ($includesousproduits) { + $childsArbo = $this->product->getChildsArbo($id, 1); + + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; + $childs = []; + foreach ($childsArbo as $values) { + $childs[] = array_combine($keys, $values); + } + + $this->product->sousprods = $childs; + } return $this->_cleanObjectDatas($this->product); } From aa7353d3cf25020b627fc7434a2defe5e9e6a67c Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 15 Nov 2019 21:18:40 +0000 Subject: [PATCH 02/84] Fixing style errors. --- htdocs/product/class/api_products.class.php | 36 ++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index c2f61604cd9..1ec1479f24c 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -373,7 +373,7 @@ class Products extends DolibarrApi return $this->product->delete(DolibarrApiAccess::$user); } - + /** * Get the list of children of the product. * @@ -391,22 +391,22 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if(! DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $childsArbo = $this->product->getChildsArbo($id, 1); - + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; $childs = []; foreach ($childsArbo as $values) { $childs[] = array_combine($keys, $values); } - + return $childs; } - + /** * Add product child. * @@ -421,26 +421,26 @@ class Products extends DolibarrApi * @throws RestException * @throws 401 * @throws 404 - * + * * @url POST {id}/childs/add */ public function addChild($id, $child_id, $qty, $incdec = 1) - { + { if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if(! DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->product->add_sousproduit($id, $child_id, $qty, $incdec); if ($result <= 0) { throw new RestException(500, "Error adding product child"); } return $result; } - + /** * Remove product child. * @@ -461,11 +461,11 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if(! DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->product->del_sousproduit($id, $child_id); if ($result <= 0) { throw new RestException(500, "Error while removing product child"); @@ -887,18 +887,18 @@ class Products extends DolibarrApi if ($includestockdata) { $this->product->load_stock(); } - - - + + + if ($includesousproduits) { $childsArbo = $this->product->getChildsArbo($id, 1); - + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; $childs = []; foreach ($childsArbo as $values) { $childs[] = array_combine($keys, $values); } - + $this->product->sousprods = $childs; } From 04f58f5d32e7b9b4e82c7db4949478b2a4021731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 16 Nov 2019 11:17:56 +0100 Subject: [PATCH 03/84] $includesubproducts and path consistency --- htdocs/product/class/api_products.class.php | 64 ++++++++++----------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 1ec1479f24c..ccfe8f1acf9 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -64,18 +64,18 @@ class Products extends DolibarrApi * * Return an array with product information. * - * @param int $id ID of product - * @param int $includestockdata Load also information about stock (slower) - * @param bool $includesousproduits Load information about virtual product components + * @param int $id ID of product + * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesubproducts Load information about subproducts * @return array|mixed Data without useless information * * @throws 401 * @throws 403 * @throws 404 */ - public function get($id, $includestockdata = 0, $includesousproduits = false) + public function get($id, $includestockdata = 0, $includesubproducts = false) { - return $this->_fetch($id, '', '', '', $includestockdata, $includesousproduits); + return $this->_fetch($id, '', '', '', $includestockdata, $includesubproducts); } /** @@ -83,21 +83,21 @@ class Products extends DolibarrApi * * Return an array with product information. * - * @param string $ref Ref of element - * @param int $includestockdata Load also information about stock (slower) - * @param bool $includesousproduits Load information about virtual product components + * @param string $ref Ref of element + * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesubproducts Load information about subproducts * * @return array|mixed Data without useless information * - * @url GET byRef/{ref} + * @url GET ref/{ref} * * @throws 401 * @throws 403 * @throws 404 */ - public function getByRef($ref, $includestockdata = 0, $includesousproduits = false) + public function getByRef($ref, $includestockdata = 0, $includesubproducts = false) { - return $this->_fetch('', $ref, '', '', $includestockdata, $includesousproduits); + return $this->_fetch('', $ref, '', '', $includestockdata, $includesubproducts); } /** @@ -105,21 +105,21 @@ class Products extends DolibarrApi * * Return an array with product information. * - * @param string $ref_ext Ref_ext of element - * @param int $includestockdata Load also information about stock (slower) - * @param bool $includesousproduits Load information about virtual product components + * @param string $ref_ext Ref_ext of element + * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesubproducts Load information about subproducts * * @return array|mixed Data without useless information * - * @url GET byRefExt/{ref_ext} + * @url GET ref_ext/{ref_ext} * * @throws 401 * @throws 403 * @throws 404 */ - public function getByRefExt($ref_ext, $includestockdata = 0, $includesousproduits = false) + public function getByRefExt($ref_ext, $includestockdata = 0, $includesubproducts = false) { - return $this->_fetch('', '', $ref_ext, '', $includestockdata, $includesousproduits); + return $this->_fetch('', '', $ref_ext, '', $includestockdata, $includesubproducts); } /** @@ -127,21 +127,21 @@ class Products extends DolibarrApi * * Return an array with product information. * - * @param string $barcode Barcode of element - * @param int $includestockdata Load also information about stock (slower) - * @param bool $includesousproduits Load information about virtual product components + * @param string $barcode Barcode of element + * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesubproducts Load information about subproducts * * @return array|mixed Data without useless information * - * @url GET byBarcode/{barcode} + * @url GET barcode/{barcode} * * @throws 401 * @throws 403 * @throws 404 */ - public function getByBarcode($barcode, $includestockdata = 0, $includesousproduits = false) + public function getByBarcode($barcode, $includestockdata = 0, $includesubproducts = false) { - return $this->_fetch('', '', '', $barcode, $includestockdata, $includesousproduits); + return $this->_fetch('', '', '', $barcode, $includestockdata, $includesubproducts); } /** @@ -851,19 +851,19 @@ class Products extends DolibarrApi * * Return an array with product information. * - * @param int $id ID of product - * @param string $ref Ref of element - * @param string $ref_ext Ref ext of element - * @param string $barcode Barcode of element - * @param int $includestockdata Load also information about stock (slower) - * @param bool $includesousproduits Load information about virtual product components - * @return array|mixed Data without useless information + * @param int $id ID of product + * @param string $ref Ref of element + * @param string $ref_ext Ref ext of element + * @param string $barcode Barcode of element + * @param int $includestockdata Load also information about stock (slower) + * @param bool $includesubproducts Load information about subproducts + * @return array|mixed Data without useless information * * @throws 401 * @throws 403 * @throws 404 */ - private function _fetch($id, $ref = '', $ref_ext = '', $barcode = '', $includestockdata = 0, $includesousproduits = false) + private function _fetch($id, $ref = '', $ref_ext = '', $barcode = '', $includestockdata = 0, $includesubproducts = 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'); @@ -890,7 +890,7 @@ class Products extends DolibarrApi - if ($includesousproduits) { + if ($includesubproducts) { $childsArbo = $this->product->getChildsArbo($id, 1); $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; From 33d4c4b73cd09a064612438f9b3a1c07dad4379c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 16 Nov 2019 11:23:50 +0100 Subject: [PATCH 04/84] Doc for $child_id --- htdocs/product/class/api_products.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index ccfe8f1acf9..06cf17ea66b 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -412,10 +412,10 @@ class Products extends DolibarrApi * * Link a product/service to a parent product/service * - * @param int $id Id of parent product/service - * @param int $id_fils Id of child product/service - * @param int $qty Quantity - * @param int $incdec 1=Increase/decrease stock of child when parent stock increase/decrease + * @param int $id Id of parent product/service + * @param int $child_id Id of child product/service + * @param int $qty Quantity + * @param int $incdec 1=Increase/decrease stock of child when parent stock increase/decrease * @return int * * @throws RestException From 256e256f62c00a8b0cdaff829a045f704833a960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 16 Nov 2019 12:30:47 +0100 Subject: [PATCH 05/84] Paths and vars: subproducts instead of childs --- htdocs/product/class/api_products.class.php | 34 ++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 06cf17ea66b..58d53583645 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -375,7 +375,7 @@ class Products extends DolibarrApi } /** - * Get the list of children of the product. + * Get the list of subproducts of the product. * * @param int $id Id of parent product/service * @return array @@ -384,9 +384,9 @@ class Products extends DolibarrApi * @throws 401 * @throws 404 * - * @url GET {id}/childs + * @url GET {id}/subproducts */ - public function getChilds($id) + public function getSubproducts($id) { if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); @@ -408,23 +408,23 @@ class Products extends DolibarrApi } /** - * Add product child. + * Add subproduct. * * Link a product/service to a parent product/service * - * @param int $id Id of parent product/service - * @param int $child_id Id of child product/service - * @param int $qty Quantity - * @param int $incdec 1=Increase/decrease stock of child when parent stock increase/decrease + * @param int $id Id of parent product/service + * @param int $subproduct_id Id of child product/service + * @param int $qty Quantity + * @param int $incdec 1=Increase/decrease stock of child when parent stock increase/decrease * @return int * * @throws RestException * @throws 401 * @throws 404 * - * @url POST {id}/childs/add + * @url POST {id}/subproducts/add */ - public function addChild($id, $child_id, $qty, $incdec = 1) + public function addSubproducts($id, $subproduct_id, $qty, $incdec = 1) { if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); @@ -434,7 +434,7 @@ class Products extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $result = $this->product->add_sousproduit($id, $child_id, $qty, $incdec); + $result = $this->product->add_sousproduit($id, $subproduct_id, $qty, $incdec); if ($result <= 0) { throw new RestException(500, "Error adding product child"); } @@ -442,21 +442,21 @@ class Products extends DolibarrApi } /** - * Remove product child. + * Remove subproduct. * * Unlink a product/service from a parent product/service * - * @param int $id Id of parent product/service - * @param int $child_id Id of child product/service + * @param int $id Id of parent product/service + * @param int $subproduct_id Id of child product/service * @return int * * @throws RestException * @throws 401 * @throws 404 * - * @url DELETE {id}/childs/remove + * @url DELETE {id}/subproducts/remove */ - public function delChild($id, $child_id) + public function delSubproducts($id, $subproduct_id) { if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); @@ -466,7 +466,7 @@ class Products extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $result = $this->product->del_sousproduit($id, $child_id); + $result = $this->product->del_sousproduit($id, $subproduct_id); if ($result <= 0) { throw new RestException(500, "Error while removing product child"); } From 8c057f1975d07aaa1b1c14dd506196bd07932361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sun, 17 Nov 2019 01:20:15 +0100 Subject: [PATCH 06/84] API New Product variants --- htdocs/product/class/api_products.class.php | 546 ++++++++++++++++++++ 1 file changed, 546 insertions(+) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 58d53583645..e3fb4d6079c 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -21,6 +21,10 @@ use Luracast\Restler\RestException; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; +require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; +require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'; +require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php'; +require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination2ValuePair.class.php'; /** * API class for products @@ -798,6 +802,548 @@ class Products extends DolibarrApi return $this->_cleanObjectDatas($this->productsupplier); } + + /** + * Get attributes. + * + * @return array + * + * @throws RestException + * + * @url GET attributes + */ + public function getAttributes() + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $prodattr = new ProductAttribute($this->db); + return $prodattr->fetchAll(); + } + + /** + * Get attribute by ID. + * + * @param int $id ID of Attribute + * @return array + * + * @throws RestException + * @throws 401 + * @throws 404 + * + * @url GET attributes/{id} + */ + public function getAttributeById($id) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $prodattr = new ProductAttribute($this->db); + $result = $prodattr->fetch((int) $id); + + if($result < 0) { + throw new RestException(404, "Attribute not found"); + } + + return $prodattr; + } + + /** + * Add attributes. + * + * @param string $ref Reference of Attribute + * @param string $label Label of Attribute + * @return int + * + * @throws RestException + * @throws 401 + * + * @url POST attributes + */ + public function addAttributes($ref, $label) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $prodattr = new ProductAttribute($this->db); + $prodattr->label = $label; + $prodattr->ref = $ref; + + $resid = $prodattr->create(DolibarrApiAccess::$user); + if ($resid <= 0) { + throw new RestException(500, "Error creating new attribute"); + } + return $resid; + } + + /** + * Update attributes by id. + * + * @param int $id ID of Attribute + * @param string $ref Reference of Attribute + * @param string $label Label of Attribute + * @return int + * + * @throws RestException + * @throws 401 + * @throws 404 + * + * @url PUT attributes/{id} + */ + public function putAttributes($id, $ref, $label) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $prodattr = new ProductAttribute($this->db); + + $result = $prodattr->fetch((int) $id); + if ($result == 0) { + throw new RestException(404, 'Attribute not found'); + } elseif ($result < 0) { + throw new RestException(500, "Error fetching attribute"); + } + + + $prodattr->label = $label; + $prodattr->ref = $ref; + + if ($prodattr->update(DolibarrApiAccess::$user) > 0) { + return 1; + } + throw new RestException(500, "Error updating attribute"); + } + + /** + * Delete attributes by id. + * + * @param int $id ID of Attribute + * @return int + * + * @throws RestException + * @throws 401 + * + * @url DELETE attributes/{id} + */ + public function deleteAttributes($id) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $prodattr = new ProductAttribute($this->db); + $prodattr->id = (int) $id; + $result = $prodattr->delete(); + + if ($result > 0) { + return 1; + } + throw new RestException(500, "Error deleting attribute"); + } + + /** + * Delete attributes by ref. + * + * @param string $ref Reference of Attribute + * @return int + * + * @throws RestException + * @throws 401 + * + * @url DELETE attributes/ref/{ref} + */ + public function deleteAttributesByRef($ref) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '". trim($ref) ."'"; + + if ($this->db->query($sql)) { + return 1; + } + throw new RestException(500, "Error deleting attribute"); + } + + /** + * Get all values for an attribute id. + * + * @param int $id ID of an Attribute + * @return array + * + * @throws RestException + * @throws 401 + * + * @url GET attributes/{id}/values + */ + public function getAttributeValues($id) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $objectval = new ProductAttributeValue($this->db); + return $objectval->fetchAllByProductAttribute((int) $id); + } + + /** + * Get all values for an attribute ref. + * + * @param string $ref Ref of an Attribute + * @return array + * + * @throws RestException + * @throws 401 + * + * @url GET attributes/ref/{ref}/values + */ + public function getAttributeValuesByRef($ref) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $return = array(); + + $sql = 'SELECT '; + $sql .= 'v.fk_product_attribute, v.rowid, v.ref, v.value FROM '.MAIN_DB_PREFIX.'product_attribute_value v '; + $sql .= "WHERE v.fk_product_attribute = ( SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '". strtoupper(trim($ref)) ."' LIMIT 1)"; + + $query = $this->db->query($sql); + + while ($result = $this->db->fetch_object($query)) { + $tmp = new ProductAttributeValue($this->db); + $tmp->fk_product_attribute = $result->fk_product_attribute; + $tmp->id = $result->rowid; + $tmp->ref = $result->ref; + $tmp->value = $result->value; + + $return[] = $tmp; + } + + return $return; + } + + /** + * Add attribute value. + * + * @param int $id ID of Attribute + * @param string $ref Reference of Attribute value + * @param string $value Value of Attribute value + * @return int + * + * @throws RestException + * @throws 401 + * + * @url POST attributes/{id}/values + */ + public function addAttributeValue($id, $ref, $value) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + if (empty($ref) || empty($value)) { + throw new RestException(401); + } + + $objectval = new ProductAttributeValue($this->db); + $objectval->fk_product_attribute = $id; + $objectval->ref = $ref; + $objectval->value = $value; + + if ($objectval->create(DolibarrApiAccess::$user) > 0) { + return $objectval->id; + } + throw new RestException(500, "Error creating new attribute value"); + } + + /** + * Delete attribute value by id. + * + * @param int $id ID of Attribute value + * @return int + * + * @throws RestException + * @throws 401 + * + * @url DELETE attributes/values/{id} + */ + public function deleteAttributeValueById($id) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $objectval = new ProductAttributeValue($this->db); + $objectval->id = (int) $id; + + if ($objectval->delete() > 0) { + return 1; + } + throw new RestException(500, "Error deleting attribute value"); + } + + /** + * Delete attribute value by ref. + * + * @param string $ref Ref of Attribute value + * @return int + * + * @throws RestException + * @throws 401 + * + * @url DELETE attributes/values/ref/{ref} + */ + public function deleteAttributeValueByRef($ref) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '". trim($ref) ."'"; + + if ($this->db->query($sql)) { + return 1; + } + + throw new RestException(500, "Error deleting attribute value"); + } + + /** + * Get product variants. + * + * @param int $id ID of Product + * @return array + * + * @throws RestException + * @throws 401 + * + * @url GET {id}/variants + */ + public function getVariants($id) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $prodcomb = new ProductCombination($this->db); + return $prodcomb->fetchAllByFkProductParent((int) $id); + } + + /** + * Get product variants by Product ref. + * + * @param string $ref Ref of Product + * @return array + * + * @throws RestException + * @throws 401 + * + * @url GET ref/{ref}/variants + */ + public function getVariantsByProdRef($ref) + { + if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + throw new RestException(401); + } + + $result = $this->product->fetch('', $ref); + if(! $result ) { + throw new RestException(404, 'Product not found'); + } + + $prodcomb = new ProductCombination($this->db); + return $prodcomb->fetchAllByFkProductParent((int) $this->product->id); + } + + /** + * Add variant. + * + * "features" is a list of attributes pairs id_attribute=>id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) + * + * @param int $id ID of Product + * @param float $weight_impact Weight impact of variant + * @param float $price_impact Price impact of variant + * @param bool $price_impact_is_percent Price impact in percent (true or false) + * @param array $features List of attributes pairs id_attribute->id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) + * @return int + * + * @throws RestException + * @throws 401 + * @throws 404 + * + * @url POST {id}/variants + */ + public function addVariant($id, $weight_impact, $price_impact, $price_impact_is_percent, $features) + { + if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { + throw new RestException(401); + } + + if (empty($id) || empty($weight_impact) || empty($price_impact) || empty($features) || !is_array($features)) { + throw new RestException(401); + } + + $prodattr = new ProductAttribute($this->db); + $prodattr_val = new ProductAttributeValue($this->db); + foreach ($features as $id_attr => $id_value) { + if ($prodattr->fetch((int) $id_attr) < 0) { + throw new RestException(401); + } + if ($prodattr_val->fetch((int) $id_value) < 0) { + throw new RestException(401); + } + } + + $result = $this->product->fetch((int) $id); + if(! $result ) { + throw new RestException(404, 'Product not found'); + } + + $prodcomb = new ProductCombination($this->db); + if (! $prodcomb->fetchByProductCombination2ValuePairs($id, $features)) + { + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact); + if ($result > 0) + { + return $result; + } else { + throw new RestException(500, "Error creating new product variant"); + } + } else { + return $prodcomb->id; + } + } + + /** + * Add variant by product ref. + * + * "features" is a list of attributes pairs id_attribute=>id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) + * + * @param string $ref Ref of Product + * @param float $weight_impact Weight impact of variant + * @param float $price_impact Price impact of variant + * @param bool $price_impact_is_percent Price impact in percent (true or false) + * @param array $features List of attributes pairs id_attribute->id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) + * @return int + * + * @throws RestException + * @throws 401 + * @throws 404 + * + * @url POST ref/{ref}/variants + */ + public function addVariantByProductRef($ref, $weight_impact, $price_impact, $price_impact_is_percent, $features) + { + if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { + throw new RestException(401); + } + + if (empty($ref) || empty($weight_impact) || empty($price_impact) || empty($features) || !is_array($features)) { + throw new RestException(401); + } + + $prodattr = new ProductAttribute($this->db); + $prodattr_val = new ProductAttributeValue($this->db); + foreach ($features as $id_attr => $id_value) { + if ($prodattr->fetch((int) $id_attr) < 0) { + throw new RestException(404); + } + if ($prodattr_val->fetch((int) $id_value) < 0) { + throw new RestException(404); + } + } + + $result = $this->product->fetch('', trim($ref)); + if(! $result ) { + throw new RestException(404, 'Product not found'); + } + + $prodcomb = new ProductCombination($this->db); + if (! $prodcomb->fetchByProductCombination2ValuePairs($this->product->id, $features)) + { + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact); + if ($result > 0) + { + return $result; + } else { + throw new RestException(500, "Error creating new product variant"); + } + } else { + return $prodcomb->id; + } + } + + /** + * Put product variants. + * + * @param int $id ID of Variant + * @param array $request_data Datas + * @return int + * + * @throws RestException + * @throws 401 + * + * @url PUT variants/{id} + */ + public function putVariant($id, $request_data = null) + { + if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { + throw new RestException(401); + } + + $prodcomb = new ProductCombination($this->db); + $prodcomb->fetch((int) $id); + + $old_prodcomb = dol_clone($prodcomb, 0); + + foreach($request_data as $field => $value) { + if ($field == 'rowid') { continue; + } + $prodcomb->$field = $value; + } + + $result = $prodcomb->update(DolibarrApiAccess::$user); + if ($result > 0) + { + return 1; + } + throw new RestException(500, "Error editing variant"); + } + + /** + * Delete product variants. + * + * @param int $id ID of Variant + * @return int + * + * @throws RestException + * @throws 401 + * + * @url DELETE variants/{id} + */ + public function deleteVariant($id) + { + if(! (DolibarrApiAccess::$user->rights->produit->supprimer || DolibarrApiAccess::$user->rights->service->supprimer)) { + throw new RestException(401); + } + + $prodcomb = new ProductCombination($this->db); + $prodcomb->id = (int) $id; + $result = $prodcomb->delete(DolibarrApiAccess::$user); + return $result; + if ($result > 0) + { + return 1; + } + throw new RestException(500, "Error deleting variant"); + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** From a17e183da906fddfc0f1a663f8365bcf2482e892 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sun, 17 Nov 2019 00:18:43 +0000 Subject: [PATCH 07/84] Fixing style errors. --- htdocs/product/class/api_products.class.php | 132 ++++++++++---------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index e3fb4d6079c..fd564b17278 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -802,7 +802,7 @@ class Products extends DolibarrApi return $this->_cleanObjectDatas($this->productsupplier); } - + /** * Get attributes. * @@ -813,15 +813,15 @@ class Products extends DolibarrApi * @url GET attributes */ public function getAttributes() - { + { if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); return $prodattr->fetchAll(); } - + /** * Get attribute by ID. * @@ -839,17 +839,17 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $result = $prodattr->fetch((int) $id); - + if($result < 0) { throw new RestException(404, "Attribute not found"); } - + return $prodattr; } - + /** * Add attributes. * @@ -867,18 +867,18 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr->label = $label; $prodattr->ref = $ref; - + $resid = $prodattr->create(DolibarrApiAccess::$user); if ($resid <= 0) { throw new RestException(500, "Error creating new attribute"); } return $resid; } - + /** * Update attributes by id. * @@ -898,26 +898,26 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); - + $result = $prodattr->fetch((int) $id); if ($result == 0) { throw new RestException(404, 'Attribute not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute"); } - - + + $prodattr->label = $label; $prodattr->ref = $ref; - + if ($prodattr->update(DolibarrApiAccess::$user) > 0) { return 1; } throw new RestException(500, "Error updating attribute"); } - + /** * Delete attributes by id. * @@ -934,17 +934,17 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr->id = (int) $id; $result = $prodattr->delete(); - + if ($result > 0) { return 1; } throw new RestException(500, "Error deleting attribute"); } - + /** * Delete attributes by ref. * @@ -961,15 +961,15 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '". trim($ref) ."'"; - + if ($this->db->query($sql)) { return 1; } throw new RestException(500, "Error deleting attribute"); } - + /** * Get all values for an attribute id. * @@ -986,11 +986,11 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); return $objectval->fetchAllByProductAttribute((int) $id); } - + /** * Get all values for an attribute ref. * @@ -1007,28 +1007,28 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $return = array(); - + $sql = 'SELECT '; $sql .= 'v.fk_product_attribute, v.rowid, v.ref, v.value FROM '.MAIN_DB_PREFIX.'product_attribute_value v '; $sql .= "WHERE v.fk_product_attribute = ( SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '". strtoupper(trim($ref)) ."' LIMIT 1)"; $query = $this->db->query($sql); - + while ($result = $this->db->fetch_object($query)) { $tmp = new ProductAttributeValue($this->db); $tmp->fk_product_attribute = $result->fk_product_attribute; $tmp->id = $result->rowid; $tmp->ref = $result->ref; $tmp->value = $result->value; - + $return[] = $tmp; } - + return $return; } - + /** * Add attribute value. * @@ -1047,22 +1047,22 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + if (empty($ref) || empty($value)) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $objectval->fk_product_attribute = $id; $objectval->ref = $ref; $objectval->value = $value; - + if ($objectval->create(DolibarrApiAccess::$user) > 0) { return $objectval->id; } throw new RestException(500, "Error creating new attribute value"); } - + /** * Delete attribute value by id. * @@ -1079,16 +1079,16 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $objectval->id = (int) $id; - + if ($objectval->delete() > 0) { return 1; } throw new RestException(500, "Error deleting attribute value"); } - + /** * Delete attribute value by ref. * @@ -1105,16 +1105,16 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '". trim($ref) ."'"; - + if ($this->db->query($sql)) { return 1; } - + throw new RestException(500, "Error deleting attribute value"); } - + /** * Get product variants. * @@ -1131,11 +1131,11 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); return $prodcomb->fetchAllByFkProductParent((int) $id); } - + /** * Get product variants by Product ref. * @@ -1152,19 +1152,19 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { throw new RestException(401); } - + $result = $this->product->fetch('', $ref); if(! $result ) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); return $prodcomb->fetchAllByFkProductParent((int) $this->product->id); } - + /** * Add variant. - * + * * "features" is a list of attributes pairs id_attribute=>id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) * * @param int $id ID of Product @@ -1185,11 +1185,11 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { throw new RestException(401); } - + if (empty($id) || empty($weight_impact) || empty($price_impact) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); foreach ($features as $id_attr => $id_value) { @@ -1200,12 +1200,12 @@ class Products extends DolibarrApi throw new RestException(401); } } - + $result = $this->product->fetch((int) $id); if(! $result ) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); if (! $prodcomb->fetchByProductCombination2ValuePairs($id, $features)) { @@ -1220,10 +1220,10 @@ class Products extends DolibarrApi return $prodcomb->id; } } - + /** * Add variant by product ref. - * + * * "features" is a list of attributes pairs id_attribute=>id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) * * @param string $ref Ref of Product @@ -1244,11 +1244,11 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { throw new RestException(401); } - + if (empty($ref) || empty($weight_impact) || empty($price_impact) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); foreach ($features as $id_attr => $id_value) { @@ -1259,16 +1259,16 @@ class Products extends DolibarrApi throw new RestException(404); } } - + $result = $this->product->fetch('', trim($ref)); if(! $result ) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); if (! $prodcomb->fetchByProductCombination2ValuePairs($this->product->id, $features)) { - $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact); + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact); if ($result > 0) { return $result; @@ -1279,7 +1279,7 @@ class Products extends DolibarrApi return $prodcomb->id; } } - + /** * Put product variants. * @@ -1297,18 +1297,18 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $prodcomb->fetch((int) $id); - + $old_prodcomb = dol_clone($prodcomb, 0); - + foreach($request_data as $field => $value) { if ($field == 'rowid') { continue; } $prodcomb->$field = $value; } - + $result = $prodcomb->update(DolibarrApiAccess::$user); if ($result > 0) { @@ -1316,7 +1316,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error editing variant"); } - + /** * Delete product variants. * @@ -1333,7 +1333,7 @@ class Products extends DolibarrApi if(! (DolibarrApiAccess::$user->rights->produit->supprimer || DolibarrApiAccess::$user->rights->service->supprimer)) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $prodcomb->id = (int) $id; $result = $prodcomb->delete(DolibarrApiAccess::$user); From 40e4af234de3fc0568bd9c9abd6b615f1b9b1d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sun, 17 Nov 2019 01:24:07 +0100 Subject: [PATCH 08/84] Inject $user instead of global var --- htdocs/variants/class/ProductCombination.class.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 4dfd40a8f53..1c09aae62df 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -495,6 +495,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; * [...] * ) * + * @param User $user Object user * @param Product $product Parent product * @param array $combinations Attribute and value combinations. * @param array $variations Price and weight variations @@ -503,9 +504,9 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; * @param bool|float $forced_weightvar If the weight variation is forced * @return int <0 KO, >0 OK */ - public function createProductCombination(Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false) + public function createProductCombination(User $user, Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false) { - global $db, $user, $conf; + global $db, $conf; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'; @@ -660,11 +661,12 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; /** * Copies all product combinations from the origin product to the destination product * + * @param User $user Object user * @param int $origProductId Origin product id * @param Product $destProduct Destination product * @return int >0 OK <0 KO */ - public function copyAll($origProductId, Product $destProduct) + public function copyAll(User $user, $origProductId, Product $destProduct) { require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination2ValuePair.class.php'; @@ -686,6 +688,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; } if ($this->createProductCombination( + $user, $destProduct, $variations, array(), From a7f42b3fdfeba4783575e303d370877d665e949f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sun, 17 Nov 2019 01:25:44 +0100 Subject: [PATCH 09/84] Inject $user for createProductCombination --- htdocs/variants/combinations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 714ee07ed3f..f8a8b9cc9e5 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -141,7 +141,7 @@ if ($_POST) { if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) { - $result = $prodcomb->createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact); + $result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); @@ -268,7 +268,7 @@ if ($action === 'confirm_deletecombination') { if ($prodstatic->fetch('', $dest_product) > 0) { //To prevent from copying to the same product if ($prodstatic->ref != $object->ref) { - if ($prodcomb->copyAll($object->id, $prodstatic) > 0) { + if ($prodcomb->copyAll($user, $object->id, $prodstatic) > 0) { header('Location: '.dol_buildpath('/variants/combinations.php?id='.$prodstatic->id, 2)); exit(); } else { From 398f0e00f75bca7958db73ece512da9b28e7f381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sun, 17 Nov 2019 01:27:23 +0100 Subject: [PATCH 10/84] inject $user for createProductCombination --- htdocs/variants/generator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/variants/generator.php b/htdocs/variants/generator.php index 27f811fdafe..137186bd5b8 100644 --- a/htdocs/variants/generator.php +++ b/htdocs/variants/generator.php @@ -110,7 +110,7 @@ if ($_POST) $cartesianarray = cartesianArray($adapted_values); foreach ($cartesianarray as $currcomb) { - $res = $combination->createProductCombination($product, $currcomb, $sanitized_values, $price_var_percent); + $res = $combination->createProductCombination($user, $product, $currcomb, $sanitized_values, $price_var_percent); if ($res < 0) { $error++; setEventMessages($combination->error, $combination->errors, 'errors'); From 8fbf853b9421d0788469d72f9de18caeecfc0ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Tue, 19 Nov 2019 14:40:50 +0100 Subject: [PATCH 11/84] Display attributes infos when get product variants --- htdocs/product/class/api_products.class.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index fd564b17278..1d71246cab7 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1133,7 +1133,14 @@ class Products extends DolibarrApi } $prodcomb = new ProductCombination($this->db); - return $prodcomb->fetchAllByFkProductParent((int) $id); + $combinations = $prodcomb->fetchAllByFkProductParent((int) $id); + + foreach ($combinations as $key => $combination) { + $prodc2vp = new ProductCombination2ValuePair($this->db); + $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); + } + + return $combinations; } /** @@ -1159,7 +1166,14 @@ class Products extends DolibarrApi } $prodcomb = new ProductCombination($this->db); - return $prodcomb->fetchAllByFkProductParent((int) $this->product->id); + $combinations = $prodcomb->fetchAllByFkProductParent((int) $this->product->id); + + foreach ($combinations as $key => $combination) { + $prodc2vp = new ProductCombination2ValuePair($this->db); + $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); + } + + return $combinations; } /** From c33506b4cc567d8e1134746227c161868769905c Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 19 Nov 2019 13:41:30 +0000 Subject: [PATCH 12/84] Fixing style errors. --- htdocs/product/class/api_products.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 1d71246cab7..c9e95cb5fe0 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1134,12 +1134,12 @@ class Products extends DolibarrApi $prodcomb = new ProductCombination($this->db); $combinations = $prodcomb->fetchAllByFkProductParent((int) $id); - + foreach ($combinations as $key => $combination) { $prodc2vp = new ProductCombination2ValuePair($this->db); $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); } - + return $combinations; } @@ -1167,12 +1167,12 @@ class Products extends DolibarrApi $prodcomb = new ProductCombination($this->db); $combinations = $prodcomb->fetchAllByFkProductParent((int) $this->product->id); - + foreach ($combinations as $key => $combination) { $prodc2vp = new ProductCombination2ValuePair($this->db); $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); } - + return $combinations; } From 8f5c8c63dfb7fbce04356d7c73c688d5f66e585a Mon Sep 17 00:00:00 2001 From: John Botella Date: Tue, 19 Nov 2019 16:35:31 +0100 Subject: [PATCH 13/84] Fix dom and showOptionals call --- htdocs/expedition/card.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index be5ed4c757a..a33055d4b10 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2443,10 +2443,10 @@ elseif ($id || $ref) // Display lines extrafields if (is_array($extralabelslines) && count($extralabelslines)>0) { $colspan= empty($conf->productbatch->enabled) ? 5 : 6; - $line = new ExpeditionLigne($db); - $line->fetch_optionals($lines[$i]->id); - print ''; - if ($action == 'editline' && $lines[$i]->id == $line_id) + $line = $lines[$i]; + $line->fetch_optionals($line->id); + + if ($action == 'editline' && $line->id == $line_id) { print $line->showOptionals($extrafieldsline, 'edit', array('style'=>$bc[$var], 'colspan'=>$colspan), $indiceAsked); } @@ -2454,7 +2454,6 @@ elseif ($id || $ref) { print $line->showOptionals($extrafieldsline, 'view', array('style'=>$bc[$var], 'colspan'=>$colspan), $indiceAsked); } - print ''; } } } From d7e8c710912886e8b6106b6d410475bf568a022a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2019 12:45:15 +0100 Subject: [PATCH 14/84] Look and feel v11 --- htdocs/comm/mailing/list.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php index b38a796d3c7..cbd0c244bb3 100644 --- a/htdocs/comm/mailing/list.php +++ b/htdocs/comm/mailing/list.php @@ -271,6 +271,12 @@ if ($result) print "\n"; $i++; } + if (empty($num)) { + $colspan = 6; + if (!$filteremail) $colspan++; + print ''.$langs->trans("NoRecordFound").''; + } + print ''; print ''; print ''; From db0d352af3d485187f7b5a9ee20f03106b88f1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Hahn?= Date: Wed, 20 Nov 2019 12:53:23 +0100 Subject: [PATCH 15/84] Use virtual stock when this has been configured When "Use virtual stock by default, instead of physical stock, for replenishment feature" has been set in configuration, this should really be used. Otherwise only physically missing items will be shown in replenishment. --- htdocs/product/stock/replenish.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 0de9fa76786..99a4b4c286e 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -89,7 +89,7 @@ if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) { $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. } -$usevirtualstock=0; +$usevirtualstock = !empty($conf->global->STOCK_USE_VIRTUAL_STOCK); if ($mode == 'virtual') $usevirtualstock=1; $parameters=array(); From f73bd0e0a6fba4087e50e1f1548870b0068805ea Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Wed, 20 Nov 2019 13:07:26 +0100 Subject: [PATCH 16/84] FIX display job of contact list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit can see différent contact with same name but different job --- htdocs/comm/action/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 4e5abac75d3..c057dc2dee3 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1290,7 +1290,7 @@ if ($id > 0) // related contact print ''.$langs->trans("ActionOnContact").''; print '
'; - print $form->selectcontacts($object->socid, array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 0, 'quatrevingtpercent', false, 0, 0, array(), 'multiple', 'contactid'); + print $form->selectcontacts($object->socid, array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 1, 'quatrevingtpercent', false, 0, 0, array(), 'multiple', 'contactid'); print '
'; print ''; print ''; From f9092b1b8e997a9ff7fbdb8642c3447b8fb79ff8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2019 13:22:40 +0100 Subject: [PATCH 17/84] Fix responsive --- htdocs/compta/bank/bankentries_list.php | 17 ++++++++--------- htdocs/compta/bank/various_payment/card.php | 14 +++++++------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index bfbafc93bd5..eeb662c6168 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -698,10 +698,7 @@ if ($resql) print ' '; print ''.$langs->trans("Type").''; print ''.$langs->trans("Numero").''; - //if (! $search_account > 0) - //{ - print ''.$langs->trans("BankAccount").''; - //} + print ''.$langs->trans("BankAccount").''; print ''.$langs->trans("Debit").''; print ''.$langs->trans("Credit").''; /*if (! empty($conf->accounting->enabled)) @@ -824,19 +821,21 @@ if ($resql) $moreforfilter = ''; $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('DateOperationShort').' : '; - $moreforfilter .= '
'.$langs->trans('From').' '; + $moreforfilter .= $langs->trans('DateOperationShort').' :'; + $moreforfilter .= ($conf->browser->layout == 'phone' ? '
' : ' '); + $moreforfilter .= '
'.$langs->trans('From').' '; $moreforfilter .= $form->selectDate($search_dt_start, 'search_start_dt', 0, 0, 1, "search_form", 1, 0).'
'; //$moreforfilter .= ' - '; - $moreforfilter .= '
'.$langs->trans('to').' '.$form->selectDate($search_dt_end, 'search_end_dt', 0, 0, 1, "search_form", 1, 0).'
'; + $moreforfilter .= '
'.$langs->trans('to').' '.$form->selectDate($search_dt_end, 'search_end_dt', 0, 0, 1, "search_form", 1, 0).'
'; $moreforfilter .= '
'; $moreforfilter .= '
'; $moreforfilter .= $langs->trans('DateValueShort').' : '; - $moreforfilter .= '
'.$langs->trans('From').' '; + $moreforfilter .= ($conf->browser->layout == 'phone' ? '
' : ' '); + $moreforfilter .= '
'.$langs->trans('From').' '; $moreforfilter .= $form->selectDate($search_dv_start, 'search_start_dv', 0, 0, 1, "search_form", 1, 0).'
'; //$moreforfilter .= ' - '; - $moreforfilter .= '
'.$langs->trans('to').' '.$form->selectDate($search_dv_end, 'search_end_dv', 0, 0, 1, "search_form", 1, 0).'
'; + $moreforfilter .= '
'.$langs->trans('to').' '.$form->selectDate($search_dv_end, 'search_end_dv', 0, 0, 1, "search_form", 1, 0).'
'; $moreforfilter .= '
'; if (!empty($conf->categorie->enabled)) diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index ab93b2f0f97..72226f18cd6 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -283,7 +283,7 @@ if ($action == 'create') // Label print ''; print $form->editfieldkey('Label', 'label', '', $object, 0, 'string', '', 1).''; - print ''; + print ''; print ''; // Sens @@ -296,7 +296,7 @@ if ($action == 'create') // Amount print ''; print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1).''; - print ''; + print ''; print ''; // Bank @@ -321,7 +321,7 @@ if ($action == 'create') print ''; - print ''."\n"; + print ''."\n"; } // Project @@ -358,13 +358,13 @@ if ($action == 'create') // TODO Remove the fieldrequired and allow instead to edit a various payment to enter accounting code print ''.$langs->trans("AccountAccounting").''; print ''; - print $formaccounting->select_account($accountancy_code, 'accountancy_code', 1, null, 1, 1, ''); + print $formaccounting->select_account($accountancy_code, 'accountancy_code', 1, null, 1, 1); print ''; } else // For external software { print ''.$langs->trans("AccountAccounting").''; - print ''; + print ''; print ''; } @@ -379,14 +379,14 @@ if ($action == 'create') } else { - print ''; + print ''; } print ''; } else // For external software { print ''.$langs->trans("SubledgerAccount").''; - print ''; + print ''; print ''; } From 849449517f4c69664fc9486465064f2e265663ec Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2019 13:31:38 +0100 Subject: [PATCH 18/84] Fix responsive --- htdocs/contact/card.php | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 1c2053df794..ea6ef4d0530 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -622,9 +622,14 @@ else // Name print ''; - print 'lastname).'" autofocus="autofocus">'; - print ''; - print 'firstname).'">'; + print 'lastname).'" autofocus="autofocus">'; + print ''; + + print ''; + print ''; + print 'firstname).'">'; + print ''; // Company if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) @@ -715,19 +720,24 @@ else // Phone / Fax print ''.img_picto('', 'object_phoning').' '.$form->editfieldkey('PhonePro', 'phone_pro', '', $object, 0).''; print ''; + if ($conf->browser->layout == 'phone') print ''; print ''.img_picto('', 'object_phoning').' '.$form->editfieldkey('PhonePerso', 'phone_perso', '', $object, 0).''; print ''; print ''.img_picto('', 'object_phoning_mobile').' '.$form->editfieldkey('PhoneMobile', 'phone_mobile', '', $object, 0).''; print ''; + if ($conf->browser->layout == 'phone') print ''; print ''.img_picto('', 'object_phoning_fax').' '.$form->editfieldkey('Fax', 'fax', '', $object, 0).''; - print ''; + print ''; + print ''; if (($objsoc->typent_code == 'TE_PRIVATE' || !empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->email)) == 0) $object->email = $objsoc->email; // Predefined with third party // Email print ''.img_picto('', 'object_email').' '.$form->editfieldkey('EMail', 'email', '', $object, 0, 'string', '').''; print ''; + print ''; + if (!empty($conf->mailing->enabled)) { $noemail = ''; @@ -743,12 +753,10 @@ else } } + print ''; print ''; print ''.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ?GETPOST("no_email", 'alpha') : $noemail), 1).''; - } - else - { - print ' '; + print ''; } print ''; @@ -842,7 +850,7 @@ else print ''; // Date To Birth - print ''; - print ''; + print ''; } else { - print ''; + print ''; } + print ''; print ''; print "
'; + print '
'; $form = new Form($db); if ($object->birthday) { @@ -854,15 +862,16 @@ else } print ': '; + print ': '; if ($object->birthday_alert) { - print '
"; From 70882a749a63ddafdb6ac133c622df4a33473d43 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2019 14:40:52 +0100 Subject: [PATCH 19/84] Fix responsive for md theme --- htdocs/societe/card.php | 17 +- htdocs/theme/eldy/global.inc.php | 38 ++-- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 292 +++++++++++++++++++++++------ htdocs/theme/md/theme_vars.inc.php | 2 +- 5 files changed, 271 insertions(+), 80 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 0793282cd86..464f94d71cb 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1220,6 +1220,8 @@ else print $formcompany->selectProspectCustomerType($selected); print ''; + if ($conf->browser->layout == 'phone') print ''; + print ''.$form->editfieldkey('CustomerCode', 'customer_code', '', $object, 0).''; print ''; + + + if ($conf->browser->layout == 'phone') print ''; + print ''; + if ($conf->browser->layout == 'phone') print ''; + print ''; @@ -1313,6 +1321,7 @@ else // Phone / Fax print ''; print ''; + if ($conf->browser->layout == 'phone') print ''; print ''; print ''; @@ -1374,7 +1383,7 @@ else // } // Prof ids - $i = 1; $j = 0; + $i = 1; $j = 0; $NBCOLS = ($conf->browser->layout == 'phone' ? 1 : 2); while ($i <= 6) { $idprof = $langs->transcountry('ProfId'.$i, $object->country_code); @@ -1382,7 +1391,7 @@ else { $key = 'idprof'.$i; - if (($j % 2) == 0) print ''; + if (($j % $NBCOLS) == 0) print ''; $idprof_mandatory = 'SOCIETE_IDPROF'.($i).'_MANDATORY'; print ''; + if ($conf->browser->layout == 'phone') print ''; print ''; print ''; + if ($conf->browser->layout == 'phone') print ''; print ''; @@ -842,7 +842,7 @@ if ($socid > 0) { print ''; @@ -851,7 +851,7 @@ if ($socid > 0) { print ''; @@ -862,7 +862,12 @@ if ($socid > 0) print $obj->description; print ''; } - print ''; + print ''; print ''; if (! empty($conf->multicurrency->enabled)) { @@ -909,8 +914,8 @@ if ($socid > 0) $sql.= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line, rc.fk_invoice_supplier,"; $sql.= " rc.fk_invoice_supplier_source,"; $sql.= " u.login, u.rowid as user_id,"; - $sql.= " f.rowid, f.ref as ref,"; - $sql.= " fa.ref, fa.type as type"; + $sql.= " f.rowid as invoiceid, f.ref as ref,"; + $sql.= " fa.ref as invoice_source_ref, fa.type as type"; $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql.= " , ".MAIN_DB_PREFIX."user as u"; $sql.= " , ".MAIN_DB_PREFIX."facture_fourn_det as fc"; @@ -928,8 +933,8 @@ if ($socid > 0) $sql2.= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line, rc.fk_invoice_supplier,"; $sql2.= " rc.fk_invoice_supplier_source,"; $sql2.= " u.login, u.rowid as user_id,"; - $sql2.= " f.rowid, f.ref as ref,"; - $sql2.= " fa.ref, fa.type as type"; + $sql2.= " f.rowid as invoiceid, f.ref as ref,"; + $sql2.= " fa.ref as invoice_source_ref, fa.type as type"; $sql2.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql2.= " , ".MAIN_DB_PREFIX."user as u"; $sql2.= " , ".MAIN_DB_PREFIX."societe_remise_except as rc"; @@ -1003,7 +1008,7 @@ if ($socid > 0) { print ''; @@ -1012,7 +1017,7 @@ if ($socid > 0) { print ''; @@ -1021,7 +1026,7 @@ if ($socid > 0) { print ''; @@ -1032,7 +1037,11 @@ if ($socid > 0) print $obj->description; print ''; } - print ''; + print ''; print ''; if (! empty($conf->multicurrency->enabled)) { From a8d02615a843a5b9debf34d80a64a1245fe937ef Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 21 Nov 2019 14:58:20 +0100 Subject: [PATCH 28/84] FIX : we need to be able to recalculate tva only if invoice not ventil --- htdocs/fourn/facture/card.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index a294cf3c6ad..f82a2aeac0b 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -2642,11 +2642,14 @@ else else $calculationrule=(empty($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)?'totalofround':'roundoftotal'); if ($calculationrule == 'totalofround') $calculationrulenum=1; else $calculationrulenum=2; - $s=$langs->trans("ReCalculate").' '; - $s.=''.$langs->trans("Mode1").''; - $s.=' / '; - $s.=''.$langs->trans("Mode2").''; - print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc",$calculationrulenum).'
'.$langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('','help')); + + if(empty($object->getVentilExportCompta())) { + $s=$langs->trans("ReCalculate").' '; + $s.=''.$langs->trans("Mode1").''; + $s.=' / '; + $s.=''.$langs->trans("Mode2").''; + print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc",$calculationrulenum).'
'.$langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('','help')); + } print '
'; // Amount Local Taxes From 9a8c5d5c2932a9f4c0c254ee18c6a08905ba68c7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 15:36:30 +0100 Subject: [PATCH 29/84] Sanitize param --- htdocs/projet/info.php | 2 +- htdocs/projet/list.php | 2 +- htdocs/resource/list.php | 2 +- htdocs/ticket/agenda.php | 2 +- htdocs/ticket/messaging.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index e6d35f5ee9e..7a9521c7518 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -39,7 +39,7 @@ $action = GETPOST('action', 'aZ09'); $limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); $sortorder = GETPOST("sortorder"); -$page = GETPOST("page"); +$page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; if (! $sortfield) $sortfield="a.datep,a.id"; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index d5c37b81fa6..1eed25433db 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -62,7 +62,7 @@ $diroutputmassaction = $conf->projet->dir_output.'/temp/massgeneration/'.$user-> $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); $sortorder = GETPOST("sortorder"); -$page = GETPOST("page"); +$page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; if (!$sortfield) $sortfield = "p.ref"; diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 98f30ac22db..e1bf458b6e4 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -93,7 +93,7 @@ if (empty($sortfield)) $sortfield="t.ref"; if (empty($arch)) $arch = 0; $limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; -$page = GETPOST("page"); +$page = GETPOST("page", 'int'); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page ; $pageprev = $page - 1; diff --git a/htdocs/ticket/agenda.php b/htdocs/ticket/agenda.php index 49b901c6d12..68cef779261 100644 --- a/htdocs/ticket/agenda.php +++ b/htdocs/ticket/agenda.php @@ -43,7 +43,7 @@ $action = GETPOST('action', 'aZ09'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); $sortorder = GETPOST("sortorder"); -$page = GETPOST("page"); +$page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; if (!$sortfield) $sortfield = "a.datep,a.id"; diff --git a/htdocs/ticket/messaging.php b/htdocs/ticket/messaging.php index da7bf1aaadc..ee90a166b68 100644 --- a/htdocs/ticket/messaging.php +++ b/htdocs/ticket/messaging.php @@ -43,7 +43,7 @@ $action = GETPOST('action', 'aZ09'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); $sortorder = GETPOST("sortorder"); -$page = GETPOST("page"); +$page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; if (!$sortfield) $sortfield = "a.datep,a.id"; From 0fffdd891e9549d697d05dbb8343f34a77c8c0bb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 15:37:59 +0100 Subject: [PATCH 30/84] Sanitize data --- htdocs/product/stock/replenishorders.php | 4 ++-- htdocs/product/stock/valo.php | 4 ++-- htdocs/projet/info.php | 2 +- htdocs/projet/list.php | 2 +- htdocs/ticket/agenda.php | 2 +- htdocs/ticket/messaging.php | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/product/stock/replenishorders.php b/htdocs/product/stock/replenishorders.php index 13f7cca301f..c39f498d9b6 100644 --- a/htdocs/product/stock/replenishorders.php +++ b/htdocs/product/stock/replenishorders.php @@ -54,8 +54,8 @@ $search_dateday = GETPOST('search_dateday', 'int'); $search_date = dol_mktime(0, 0, 0, $search_datemonth, $search_dateday, $search_dateyear); $limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; -$sortfield = GETPOST("sortfield"); -$sortorder = GETPOST("sortorder"); +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); if (!$sortorder) $sortorder = 'DESC'; if (!$sortfield) $sortfield = 'cf.date_creation'; $page = GETPOST('page', 'int') ? GETPOST('page', 'int') : 0; diff --git a/htdocs/product/stock/valo.php b/htdocs/product/stock/valo.php index 32ffebdba76..e814bdfaac0 100644 --- a/htdocs/product/stock/valo.php +++ b/htdocs/product/stock/valo.php @@ -36,8 +36,8 @@ $sref=GETPOST("sref", 'alpha'); $snom=GETPOST("snom", 'alpha'); $sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); -$sortfield = GETPOST("sortfield"); -$sortorder = GETPOST("sortorder"); +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); if (! $sortfield) $sortfield="e.ref"; if (! $sortorder) $sortorder="ASC"; $page = $_GET["page"]; diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index 7a9521c7518..c28460e1045 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -38,7 +38,7 @@ $action = GETPOST('action', 'aZ09'); $limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); -$sortorder = GETPOST("sortorder"); +$sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 1eed25433db..63240e9f842 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -61,7 +61,7 @@ $diroutputmassaction = $conf->projet->dir_output.'/temp/massgeneration/'.$user-> $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); -$sortorder = GETPOST("sortorder"); +$sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; diff --git a/htdocs/ticket/agenda.php b/htdocs/ticket/agenda.php index 68cef779261..c5ffc4b0ab8 100644 --- a/htdocs/ticket/agenda.php +++ b/htdocs/ticket/agenda.php @@ -42,7 +42,7 @@ $action = GETPOST('action', 'aZ09'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); -$sortorder = GETPOST("sortorder"); +$sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; diff --git a/htdocs/ticket/messaging.php b/htdocs/ticket/messaging.php index ee90a166b68..fd432fa6dde 100644 --- a/htdocs/ticket/messaging.php +++ b/htdocs/ticket/messaging.php @@ -42,7 +42,7 @@ $action = GETPOST('action', 'aZ09'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); -$sortorder = GETPOST("sortorder"); +$sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; From d6ba06e271f7b98a410243416438f163a8678de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 21 Nov 2019 15:50:06 +0100 Subject: [PATCH 31/84] API New get attribute by ref + security update --- htdocs/product/class/api_products.class.php | 70 ++++++++++++++++----- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index c9e95cb5fe0..6010f6dbcdf 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -814,7 +814,7 @@ class Products extends DolibarrApi */ public function getAttributes() { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } @@ -836,7 +836,7 @@ class Products extends DolibarrApi */ public function getAttributeById($id) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } @@ -849,6 +849,42 @@ class Products extends DolibarrApi return $prodattr; } + + /** + * Get attributes by ref. + * + * @param string $ref Reference of Attribute + * @return array + * + * @throws RestException + * @throws 401 + * + * @url GET attributes/ref/{ref} + */ + public function getAttributesByRef($ref) + { + if(! DolibarrApiAccess::$user->rights->produit->lire) { + throw new RestException(401); + } + + $sql = "SELECT rowid, ref, label, rang FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '". trim($ref) ."' AND entity IN (".getEntity('product').")"; + + $query = $this->db->query($sql); + + if (!$this->db->num_rows($query)) { + throw new RestException(404); + } + + $result = $this->db->fetch_object($query); + + $attr = []; + $attr['id'] = $result->rowid; + $attr['ref'] = $result->ref; + $attr['label'] = $result->label; + $attr['rang'] = $result->rang; + + return $attr; + } /** * Add attributes. @@ -864,7 +900,7 @@ class Products extends DolibarrApi */ public function addAttributes($ref, $label) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } @@ -895,7 +931,7 @@ class Products extends DolibarrApi */ public function putAttributes($id, $ref, $label) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } @@ -931,7 +967,7 @@ class Products extends DolibarrApi */ public function deleteAttributes($id) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } @@ -958,7 +994,7 @@ class Products extends DolibarrApi */ public function deleteAttributesByRef($ref) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } @@ -983,7 +1019,7 @@ class Products extends DolibarrApi */ public function getAttributeValues($id) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } @@ -1004,7 +1040,7 @@ class Products extends DolibarrApi */ public function getAttributeValuesByRef($ref) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } @@ -1044,7 +1080,7 @@ class Products extends DolibarrApi */ public function addAttributeValue($id, $ref, $value) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } @@ -1076,7 +1112,7 @@ class Products extends DolibarrApi */ public function deleteAttributeValueById($id) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } @@ -1102,7 +1138,7 @@ class Products extends DolibarrApi */ public function deleteAttributeValueByRef($ref) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } @@ -1128,7 +1164,7 @@ class Products extends DolibarrApi */ public function getVariants($id) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } @@ -1156,7 +1192,7 @@ class Products extends DolibarrApi */ public function getVariantsByProdRef($ref) { - if(! (DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) { + if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } @@ -1196,7 +1232,7 @@ class Products extends DolibarrApi */ public function addVariant($id, $weight_impact, $price_impact, $price_impact_is_percent, $features) { - if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { + if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } @@ -1255,7 +1291,7 @@ class Products extends DolibarrApi */ public function addVariantByProductRef($ref, $weight_impact, $price_impact, $price_impact_is_percent, $features) { - if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { + if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } @@ -1308,7 +1344,7 @@ class Products extends DolibarrApi */ public function putVariant($id, $request_data = null) { - if(! (DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) { + if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } @@ -1344,7 +1380,7 @@ class Products extends DolibarrApi */ public function deleteVariant($id) { - if(! (DolibarrApiAccess::$user->rights->produit->supprimer || DolibarrApiAccess::$user->rights->service->supprimer)) { + if(! DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } From 4f747e2eb8e5054a8836eb99e0e4ef7fd1f623e2 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 21 Nov 2019 14:50:47 +0000 Subject: [PATCH 32/84] Fixing style errors. --- htdocs/product/class/api_products.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 6010f6dbcdf..faf312e77ff 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -849,7 +849,7 @@ class Products extends DolibarrApi return $prodattr; } - + /** * Get attributes by ref. * @@ -866,23 +866,23 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, ref, label, rang FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '". trim($ref) ."' AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$this->db->num_rows($query)) { throw new RestException(404); } - + $result = $this->db->fetch_object($query); - + $attr = []; $attr['id'] = $result->rowid; $attr['ref'] = $result->ref; $attr['label'] = $result->label; $attr['rang'] = $result->rang; - + return $attr; } From 1068d9a62388606adceabcac241c681155ebc2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 21 Nov 2019 17:23:46 +0100 Subject: [PATCH 33/84] FIX deleteAttributeValueByRef / ADD getAttributeValueById, getAttributeValueByRef --- htdocs/product/class/api_products.class.php | 102 ++++++++++++++++++-- 1 file changed, 93 insertions(+), 9 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index faf312e77ff..5be52795437 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -980,30 +980,114 @@ class Products extends DolibarrApi } throw new RestException(500, "Error deleting attribute"); } - + /** - * Delete attributes by ref. + * Get attribute value by id. * - * @param string $ref Reference of Attribute + * @param int $id ID of Attribute value + * @param string $ref Ref of Attribute value + * @return array + * + * @throws RestException + * @throws 401 + * + * @url GET attributes/values/{id} + */ + public function getAttributeValueById($id) + { + if(! DolibarrApiAccess::$user->rights->produit->lire) { + throw new RestException(401); + } + + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $id." AND entity IN (".getEntity('product').")"; + + $query = $this->db->query($sql); + + if (!$query) { + throw new RestException(401); + } + + if (!$this->db->num_rows($query)) { + throw new RestException(404, 'Attribute value not found'); + } + + $result = $this->db->fetch_object($query); + + $attrval = []; + $attrval['id'] = $result->rowid; + $attrval['fk_product_attribute'] = $result->fk_product_attribute; + $attrval['ref'] = $result->ref; + $attrval['value'] = $result->value; + + return $attrval; + } + + /** + * Get attribute value by ref. + * + * @param int $id ID of Attribute value + * @param string $ref Ref of Attribute value + * @return array + * + * @throws RestException + * @throws 401 + * + * @url GET attributes/{id}/values/ref/{ref} + */ + public function getAttributeValueByRef($id, $ref) + { + if(! DolibarrApiAccess::$user->rights->produit->lire) { + throw new RestException(401); + } + + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '". trim($ref) ."' AND fk_product_attribute = ". (int) $id ." AND entity IN (".getEntity('product').")"; + + $query = $this->db->query($sql); + + if (!$query) { + throw new RestException(401); + } + + if (!$this->db->num_rows($query)) { + throw new RestException(404, 'Attribute value not found'); + } + + $result = $this->db->fetch_object($query); + + $attrval = []; + $attrval['id'] = $result->rowid; + $attrval['fk_product_attribute'] = $result->fk_product_attribute; + $attrval['ref'] = $result->ref; + $attrval['value'] = $result->value; + + return $attrval; + } + + /** + * Delete attribute value by ref. + * + * @param int $id ID of Attribute + * @param string $ref Ref of Attribute value * @return int * * @throws RestException * @throws 401 * - * @url DELETE attributes/ref/{ref} + * @url DELETE attributes/{id}/values/ref/{ref} */ - public function deleteAttributesByRef($ref) + public function deleteAttributeValueByRef($id, $ref) { if(! DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '". trim($ref) ."'"; - + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '". trim($ref) ."' AND fk_product_attribute = ". (int) $id; + if ($this->db->query($sql)) { return 1; } - throw new RestException(500, "Error deleting attribute"); + + throw new RestException(500, "Error deleting attribute value"); } /** From 0074589b6fa689ca1c355a78e153690292c3bb6f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 21 Nov 2019 16:24:25 +0000 Subject: [PATCH 34/84] Fixing style errors. --- htdocs/product/class/api_products.class.php | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 5be52795437..c614b013f83 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -980,7 +980,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error deleting attribute"); } - + /** * Get attribute value by id. * @@ -998,30 +998,30 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $id." AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$query) { throw new RestException(401); } - + if (!$this->db->num_rows($query)) { throw new RestException(404, 'Attribute value not found'); } - + $result = $this->db->fetch_object($query); - + $attrval = []; $attrval['id'] = $result->rowid; $attrval['fk_product_attribute'] = $result->fk_product_attribute; $attrval['ref'] = $result->ref; $attrval['value'] = $result->value; - + return $attrval; } - + /** * Get attribute value by ref. * @@ -1039,30 +1039,30 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '". trim($ref) ."' AND fk_product_attribute = ". (int) $id ." AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$query) { throw new RestException(401); } - + if (!$this->db->num_rows($query)) { throw new RestException(404, 'Attribute value not found'); } - + $result = $this->db->fetch_object($query); - + $attrval = []; $attrval['id'] = $result->rowid; $attrval['fk_product_attribute'] = $result->fk_product_attribute; $attrval['ref'] = $result->ref; $attrval['value'] = $result->value; - + return $attrval; } - + /** * Delete attribute value by ref. * @@ -1080,13 +1080,13 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '". trim($ref) ."' AND fk_product_attribute = ". (int) $id; - + if ($this->db->query($sql)) { return 1; } - + throw new RestException(500, "Error deleting attribute value"); } From 416a2f7f1c0056c3cdebe6eb4505c8526bf10655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 21 Nov 2019 17:41:09 +0100 Subject: [PATCH 35/84] FIX putAttributes, ADD putAttributeValue --- htdocs/product/class/api_products.class.php | 80 +++++++++++++++++---- 1 file changed, 67 insertions(+), 13 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index c614b013f83..2f3f7463b8d 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -914,14 +914,13 @@ class Products extends DolibarrApi } return $resid; } - + /** * Update attributes by id. * * @param int $id ID of Attribute - * @param string $ref Reference of Attribute - * @param string $label Label of Attribute - * @return int + * @param array $request_data Datas + * @return array * * @throws RestException * @throws 401 @@ -929,27 +928,36 @@ class Products extends DolibarrApi * * @url PUT attributes/{id} */ - public function putAttributes($id, $ref, $label) + public function putAttributes($id, $request_data = null) { if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); - + $result = $prodattr->fetch((int) $id); if ($result == 0) { throw new RestException(404, 'Attribute not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute"); } - - - $prodattr->label = $label; - $prodattr->ref = $ref; - + + foreach($request_data as $field => $value) { + if ($field == 'rowid') { continue; + } + $prodattr->$field = $value; + } + if ($prodattr->update(DolibarrApiAccess::$user) > 0) { - return 1; + $result = $prodattr->fetch((int) $id); + if ($result == 0) { + throw new RestException(404, 'Attribute not found'); + } elseif ($result < 0) { + throw new RestException(500, "Error fetching attribute"); + } else { + return $prodattr; + } } throw new RestException(500, "Error updating attribute"); } @@ -1182,6 +1190,52 @@ class Products extends DolibarrApi } throw new RestException(500, "Error creating new attribute value"); } + + /** + * Update attribute value. + * + * @param int $id ID of Attribute + * @param array $request_data Datas + * @return array + * + * @throws RestException + * @throws 401 + * + * @url PUT attributes/values/{id} + */ + public function putAttributeValue($id, $request_data) + { + if(! DolibarrApiAccess::$user->rights->produit->creer) { + throw new RestException(401); + } + + $objectval = new ProductAttributeValue($this->db); + $result = $objectval->fetch((int) $id); + + if ($result == 0) { + throw new RestException(404, 'Attribute value not found'); + } elseif ($result < 0) { + throw new RestException(500, "Error fetching attribute value"); + } + + foreach($request_data as $field => $value) { + if ($field == 'rowid') { continue; + } + $objectval->$field = $value; + } + + if ($objectval->update(DolibarrApiAccess::$user) > 0) { + $result = $objectval->fetch((int) $id); + if ($result == 0) { + throw new RestException(404, 'Attribute not found'); + } elseif ($result < 0) { + throw new RestException(500, "Error fetching attribute"); + } else { + return $objectval; + } + } + throw new RestException(500, "Error updating attribute"); + } /** * Delete attribute value by id. From cfa0860d244896fe64ca5e2e29b01b210e915a0a Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 21 Nov 2019 16:41:45 +0000 Subject: [PATCH 36/84] Fixing style errors. --- htdocs/product/class/api_products.class.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 2f3f7463b8d..04d9979cefe 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -914,7 +914,7 @@ class Products extends DolibarrApi } return $resid; } - + /** * Update attributes by id. * @@ -933,22 +933,22 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); - + $result = $prodattr->fetch((int) $id); if ($result == 0) { throw new RestException(404, 'Attribute not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute"); } - + foreach($request_data as $field => $value) { if ($field == 'rowid') { continue; } $prodattr->$field = $value; } - + if ($prodattr->update(DolibarrApiAccess::$user) > 0) { $result = $prodattr->fetch((int) $id); if ($result == 0) { @@ -1190,7 +1190,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error creating new attribute value"); } - + /** * Update attribute value. * @@ -1208,22 +1208,22 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $result = $objectval->fetch((int) $id); - + if ($result == 0) { throw new RestException(404, 'Attribute value not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute value"); } - + foreach($request_data as $field => $value) { if ($field == 'rowid') { continue; } $objectval->$field = $value; } - + if ($objectval->update(DolibarrApiAccess::$user) > 0) { $result = $objectval->fetch((int) $id); if ($result == 0) { From 351ba58bbe65f9ddf6e1f85d852ea39d620c613f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 21 Nov 2019 17:43:40 +0100 Subject: [PATCH 37/84] Fix Superfluous parameter comment --- htdocs/product/class/api_products.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 04d9979cefe..32423c015fc 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -993,7 +993,6 @@ class Products extends DolibarrApi * Get attribute value by id. * * @param int $id ID of Attribute value - * @param string $ref Ref of Attribute value * @return array * * @throws RestException From e8bc8b68c1283226fd8b42e8d06006e257658e2c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 18:17:40 +0100 Subject: [PATCH 38/84] Fix missing field in migration --- htdocs/core/lib/functions.lib.php | 4 ++-- htdocs/install/mysql/migration/10.0.0-11.0.0.sql | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 00ca3f3d45f..9faa3762111 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3911,9 +3911,9 @@ function dol_print_error($db = '', $error = '', $errors = null) } if (empty($dolibarr_main_prod)) print $out; - else + else // This should not happen, except if there is a bug somewhere. Enabled and check log in such case. { - print 'This website is currently temporarly offline. This may be due to a maintenance operation. Current status of operation are on next line...

'."\n"; + print 'This website is currently temporarly offline.

This may be due to a maintenance operation. Current status of operation are on next line...

'."\n"; $langs->load("errors"); print $langs->trans("DolibarrHasDetectedError").'. '; print $langs->trans("YouCanSetOptionDolibarrMainProdToZero"); diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index fc488071d54..573facf541f 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -51,6 +51,11 @@ ALTER TABLE llx_adherent_type ADD UNIQUE INDEX uk_adherent_type_libelle (libelle ALTER TABLE llx_mailing_cibles MODIFY COLUMN lastname varchar(160); ALTER TABLE llx_mailing_cibles MODIFY COLUMN firstname varchar(160); +ALTER TABLE llx_emailcollector_emailcollector ADD COLUMN login varchar(128); +ALTER TABLE llx_emailcollector_emailcollector ADD COLUMN codelastresult varchar(16); + + + -- For v11 From 5a3f78088e2c42fd763d6493a4143783164c42fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 21 Nov 2019 18:18:11 +0100 Subject: [PATCH 39/84] Fix double deleteAttributeValueByRef --- htdocs/product/class/api_products.class.php | 26 --------------------- 1 file changed, 26 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 32423c015fc..2fa4f600b11 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1262,32 +1262,6 @@ class Products extends DolibarrApi throw new RestException(500, "Error deleting attribute value"); } - /** - * Delete attribute value by ref. - * - * @param string $ref Ref of Attribute value - * @return int - * - * @throws RestException - * @throws 401 - * - * @url DELETE attributes/values/ref/{ref} - */ - public function deleteAttributeValueByRef($ref) - { - if(! DolibarrApiAccess::$user->rights->produit->supprimer) { - throw new RestException(401); - } - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '". trim($ref) ."'"; - - if ($this->db->query($sql)) { - return 1; - } - - throw new RestException(500, "Error deleting attribute value"); - } - /** * Get product variants. * From f9045aa41230bf9138c92518395284f3b6627b51 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 18:39:41 +0100 Subject: [PATCH 40/84] Fix var not defined --- htdocs/admin/emailcollector_card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 43d0731c434..4662a12e6f8 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -509,11 +509,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea else { jQuery("#rulevalue").prop("disabled", false); } jQuery("#rulevalue").attr("placeholder", (jQuery("#filtertype option:selected").attr("data-placeholder"))); '; - $noparam = array(); + /*$noparam = array(); foreach ($arrayoftypes as $key => $value) { if ($value['noparam']) $noparam[] = $key; - } + }*/ print '})'; print ''."\n"; From 11be3b53f39b373f8818bff391869f956a585f7f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 18:39:51 +0100 Subject: [PATCH 41/84] Fix migration --- htdocs/install/mysql/migration/10.0.0-11.0.0.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index 573facf541f..90e3b03319c 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -53,7 +53,7 @@ ALTER TABLE llx_mailing_cibles MODIFY COLUMN firstname varchar(160); ALTER TABLE llx_emailcollector_emailcollector ADD COLUMN login varchar(128); ALTER TABLE llx_emailcollector_emailcollector ADD COLUMN codelastresult varchar(16); - +ALTER TABLE llx_emailcollector_emailcollectoraction ADD COLUMN position integer DEFAULT 0; From 6ef01a09f3393303e2c11cc2b53169b18d23e00e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 18:51:26 +0100 Subject: [PATCH 42/84] Fix error management --- htdocs/admin/emailcollector_card.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 4662a12e6f8..bfa2904d02d 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -418,10 +418,17 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (function_exists('imap_open')) { $connectstringserver = $object->getConnectStringIMAP(); - $connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); - $connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); - $connection = imap_open($connectstringsource, $object->login, $object->password); + try { + $connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); + $connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); + + $connection = imap_open($connectstringsource, $object->login, $object->password); + } + catch(Exception $e) + { + print $e->getMessage(); + } } else { From 394dc4b403874a055e84ab5a6cd66ffb084b154e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 19:03:00 +0100 Subject: [PATCH 43/84] Try to fix php error with imap_utf7_encode --- .../class/emailcollector.class.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index efdb3ea5d3b..c464e38d4a7 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -683,6 +683,38 @@ class EmailCollector extends CommonObject return $connectstringserver; } + /** + * Convert str to UTF-7 imap default mailbox names + * + * @param string $str String to encode + * @return string Encode string + */ + function getEncodedUtf7($str) { + if (function_exists('mb_convert_encoding')) { + # change spaces by entropy because mb_convert fail with spaces + $str=ereg_replace(" ","xyxy",$str); + # if mb_convert work + if ($str = mb_convert_encoding($str,"UTF-7")) { + # change characters + $str=preg_replace("/\+A/","&A",$str); + # change to spaces again + $str=preg_replace("/xyxy/"," ",$str); + # return encoded string + return $str; + # else + } else { + # print error and return false + echo "error: is not possible to encode this string '$str'.[". + imap_last_error(). + "]"; + return false; + } + } + else { + return $str; + } + } + /** * Action executed by scheduler * CAN BE A CRON TASK. In such a case, paramerts come from the schedule job setup field 'Parameters' From feb6e09a64071ede8979f6528350a0d6abbc3790 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 19:09:23 +0100 Subject: [PATCH 44/84] Fix phpcs --- htdocs/emailcollector/class/emailcollector.class.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index c464e38d4a7..10a9a847d74 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -692,21 +692,19 @@ class EmailCollector extends CommonObject function getEncodedUtf7($str) { if (function_exists('mb_convert_encoding')) { # change spaces by entropy because mb_convert fail with spaces - $str=ereg_replace(" ","xyxy",$str); + $str=preg_replace("/ /", "xyxy", $str); # if mb_convert work - if ($str = mb_convert_encoding($str,"UTF-7")) { + if ($str = mb_convert_encoding($str, "UTF-7")) { # change characters - $str=preg_replace("/\+A/","&A",$str); + $str=preg_replace("/\+A/", "&A", $str); # change to spaces again - $str=preg_replace("/xyxy/"," ",$str); + $str=preg_replace("/xyxy/", " ", $str); # return encoded string return $str; # else } else { # print error and return false - echo "error: is not possible to encode this string '$str'.[". - imap_last_error(). - "]"; + $this->error = "error: is not possible to encode this string '".$str."'"; return false; } } From ab7c5a7575f887c69c5cdf742c2e07ba150f2f82 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 19:12:25 +0100 Subject: [PATCH 45/84] Fix connectstring imap --- htdocs/admin/emailcollector_card.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index bfa2904d02d..e690c8839e3 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -420,8 +420,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $connectstringserver = $object->getConnectStringIMAP(); try { - $connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); - $connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); + if ($sourcedir) { + //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); + $connectstringsource = $connectstringserver.$object->getEncodedUtf7($sourcedir); + } + if ($targetdir) { + //$connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); + $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir); + } $connection = imap_open($connectstringsource, $object->login, $object->password); } From dcb52110b956fbc08cf6c0c80fe4f11e423a34a6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 19:42:31 +0100 Subject: [PATCH 46/84] Clean code --- htdocs/emailcollector/class/emailcollector.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 10a9a847d74..1b2baa4e335 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1090,7 +1090,6 @@ class EmailCollector extends CommonObject // If there is a filter on trackid if ($searchfilterdoltrackid > 0) { - //if (empty($headers['X-Dolibarr-TRACKID'])) continue; if (empty($headers['References']) || !preg_match('/@'.preg_quote($host, '/').'/', $headers['References'])) { $nbemailprocessed++; @@ -1104,7 +1103,6 @@ class EmailCollector extends CommonObject $nbemailprocessed++; continue; } - //if (! empty($headers['X-Dolibarr-TRACKID']) continue; } $thirdpartystatic = new Societe($this->db); From 432a37522b0025bd98c46760a20c43d143e1770b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 19:56:00 +0100 Subject: [PATCH 47/84] Add TODO to avoid duplicate --- .../class/emailcollector.class.php | 137 +++++++++--------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 1b2baa4e335..f2750f7e042 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1487,78 +1487,85 @@ class EmailCollector extends CommonObject // Create event elseif ($operation['type'] == 'recordevent') { - if ($projectstatic->id > 0) - { - if ($projectfoundby) $descriptionmeta = dol_concatdesc($descriptionmeta, 'Project found from '.$projectfoundby); - } - if ($thirdpartystatic->id > 0) - { - if ($thirdpartyfoundby) $descriptionmeta = dol_concatdesc($descriptionmeta, 'Third party found from '.$thirdpartyfoundby); - } - if ($contactstatic->id > 0) - { - if ($contactfoundby) $descriptionmeta = dol_concatdesc($descriptionmeta, 'Contact/address found from '.$contactfoundby); - } + $alreadycreated = 0; + // TODO Check if $msg ID already in database for $conf->entity - $description = $descriptiontitle; - $description = dol_concatdesc($description, "-----"); - $description = dol_concatdesc($description, $descriptionmeta); - $description = dol_concatdesc($description, "-----"); - $description = dol_concatdesc($description, $messagetext); - $descriptionfull = $description; - $descriptionfull = dol_concatdesc($descriptionfull, "----- Header"); - $descriptionfull = dol_concatdesc($descriptionfull, $header); + if (! $alreadycreated) + { + if ($projectstatic->id > 0) + { + if ($projectfoundby) $descriptionmeta = dol_concatdesc($descriptionmeta, 'Project found from '.$projectfoundby); + } + if ($thirdpartystatic->id > 0) + { + if ($thirdpartyfoundby) $descriptionmeta = dol_concatdesc($descriptionmeta, 'Third party found from '.$thirdpartyfoundby); + } + if ($contactstatic->id > 0) + { + if ($contactfoundby) $descriptionmeta = dol_concatdesc($descriptionmeta, 'Contact/address found from '.$contactfoundby); + } - // Insert record of emails sent - $actioncomm = new ActionComm($this->db); - $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) - $actioncomm->code = 'AC_'.$actioncode; - $actioncomm->label = $langs->trans("ActionAC_".$actioncode).' - '.$langs->trans("MailFrom").' '.$from; - $actioncomm->note_private= $descriptionfull; - $actioncomm->fk_project = $projectstatic->id; - $actioncomm->datep = $date; - $actioncomm->datef = $date; - $actioncomm->percentage = -1; // Not applicable - $actioncomm->socid = $thirdpartystatic->id; - $actioncomm->contactid = $contactstatic->id; - $actioncomm->socpeopleassigned = (!empty($contactstatic->id) ? array($contactstatic->id => '') : array()); - $actioncomm->authorid = $user->id; // User saving action - $actioncomm->userownerid = $user->id; // Owner of action - // Fields when action is an email (content should be added into note) - $actioncomm->email_msgid = $msgid; - $actioncomm->email_from = $fromstring; - $actioncomm->email_sender= $sender; - $actioncomm->email_to = $to; - $actioncomm->email_tocc = $sendtocc; - $actioncomm->email_tobcc = $sendtobcc; - $actioncomm->email_subject = $subject; - $actioncomm->errors_to = ''; + $description = $descriptiontitle; + $description = dol_concatdesc($description, "-----"); + $description = dol_concatdesc($description, $descriptionmeta); + $description = dol_concatdesc($description, "-----"); + $description = dol_concatdesc($description, $messagetext); - if (! in_array($fk_element_type, array('societe','contact','project','user'))) - { - $actioncomm->fk_element = $fk_element_id; - $actioncomm->elementtype = $fk_element_type; - } + $descriptionfull = $description; + $descriptionfull = dol_concatdesc($descriptionfull, "----- Header"); + $descriptionfull = dol_concatdesc($descriptionfull, $header); - //$actioncomm->extraparams = $extraparams; + // Insert record of emails sent + $actioncomm = new ActionComm($this->db); + $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) + $actioncomm->code = 'AC_'.$actioncode; + $actioncomm->label = $langs->trans("ActionAC_".$actioncode).' - '.$langs->trans("MailFrom").' '.$from; + $actioncomm->note_private= $descriptionfull; + $actioncomm->fk_project = $projectstatic->id; + $actioncomm->datep = $date; + $actioncomm->datef = $date; + $actioncomm->percentage = -1; // Not applicable + $actioncomm->socid = $thirdpartystatic->id; + $actioncomm->contactid = $contactstatic->id; + $actioncomm->socpeopleassigned = (!empty($contactstatic->id) ? array($contactstatic->id => '') : array()); + $actioncomm->authorid = $user->id; // User saving action + $actioncomm->userownerid = $user->id; // Owner of action + // Fields when action is an email (content should be added into note) + $actioncomm->email_msgid = $msgid; + $actioncomm->email_from = $fromstring; + $actioncomm->email_sender= $sender; + $actioncomm->email_to = $to; + $actioncomm->email_tocc = $sendtocc; + $actioncomm->email_tobcc = $sendtobcc; + $actioncomm->email_subject = $subject; + $actioncomm->errors_to = ''; - // Overwrite values with values extracted from source email - $errorforthisaction = $this->overwritePropertiesOfObject($actioncomm, $operation['actionparam'], $messagetext, $subject, $header); + if (! in_array($fk_element_type, array('societe','contact','project','user'))) + { + $actioncomm->fk_element = $fk_element_id; + $actioncomm->elementtype = $fk_element_type; + } - if ($errorforthisaction) - { - $errorforactions++; - } - else - { - $result = $actioncomm->create($user); - if ($result <= 0) - { - $errorforactions++; - $this->errors = $actioncomm->errors; - } - } + //$actioncomm->extraparams = $extraparams; + + // Overwrite values with values extracted from source email + $errorforthisaction = $this->overwritePropertiesOfObject($actioncomm, $operation['actionparam'], $messagetext, $subject, $header); + + if ($errorforthisaction) + { + $errorforactions++; + } + else + { + $result = $actioncomm->create($user); + if ($result <= 0) + { + $errorforactions++; + $this->errors = $actioncomm->errors; + } + } + } } // Create event elseif ($operation['type'] == 'project') From c9b79c8aa10416c1234d22b20f60f8144ec59ab0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 20:07:22 +0100 Subject: [PATCH 48/84] Fix norsh --- htdocs/admin/emailcollector_card.php | 2 ++ htdocs/emailcollector/class/emailcollector.class.php | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index e690c8839e3..f6146cb409b 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -435,6 +435,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea { print $e->getMessage(); } + + $morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver); } else { diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index f2750f7e042..55b6907f912 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -667,16 +667,20 @@ class EmailCollector extends CommonObject /** * Return the connectstring to use with IMAP connection function * + * @param int $norsh Add /norsh to connectstring * @return string */ - public function getConnectStringIMAP() + public function getConnectStringIMAP($ssl = 1, $norsh = 0) { + global $conf; + // Connect to IMAP $flags = '/service=imap'; // IMAP - $flags .= '/ssl'; // '/tls' + if ($ssl) $flags .= '/ssl'; // '/tls' $flags .= '/novalidate-cert'; //$flags.='/readonly'; //$flags.='/debug'; + if ($norsh || ! empty($conf->global->IMPA_FORCE_NORSH)) $flags .= '/norsh'; $connectstringserver = '{'.$this->host.':993'.$flags.'}'; From b46362dff980562832fbb839191e7e704dfc771b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 20:45:19 +0100 Subject: [PATCH 49/84] More complete error message --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 335c1b50111..fc5dff72a69 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -776,7 +776,7 @@ class CMailFile else { if (empty($this->error)) $this->error = $result; - dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); + dol_syslog("CMailFile::sendfile: mail end error with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."
".$this->error, LOG_ERR); $res = false; } } From 5fdd6f698d3b550c7537d37deab1e54b69a50033 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 20:45:19 +0100 Subject: [PATCH 50/84] More complete error message Conflicts: htdocs/core/class/CMailFile.class.php --- htdocs/core/class/CMailFile.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index bf9b617693f..9b1a5a69525 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -752,9 +752,9 @@ class CMailFile } else { - if (empty($this->error)) $this->error=$result; - dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); - $res=false; + if (empty($this->error)) $this->error = $result; + dol_syslog("CMailFile::sendfile: mail end error with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."
".$this->error, LOG_ERR); + $res = false; } } } From 2f2ac90fbf49021e66ee0d515d409b7fc9f36d62 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 21:35:16 +0100 Subject: [PATCH 51/84] Try to disable autocomplete --- htdocs/admin/mails.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index c52f899a03f..546a322fcdf 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -315,7 +315,7 @@ if ($action == 'edit') // SuperAdministrator access only if (empty($conf->multicompany->enabled) || ($user->admin && ! $user->entity)) { - print ''; + print ''; print ''; print ''.$langs->trans("SeeLocalSendMailSetup").''; } @@ -388,7 +388,7 @@ if ($action == 'edit') // SuperAdministrator access only if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) { - print ''; + print ''; } else { From 92a65a8039edad855ba5e927658218bba24acd89 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 21:36:03 +0100 Subject: [PATCH 52/84] Log --- htdocs/core/class/CMailFile.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index fc5dff72a69..eb15710eb7c 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -626,6 +626,7 @@ class CMailFile } // Force parameters + //dol_syslog("CMailFile::sendfile conf->global->".$keyforsmtpserver."=".$conf->global->$keyforsmtpserver." cpnf->global->".$keyforsmtpport."=".$conf->global->$keyforsmtpport, LOG_DEBUG); if (!empty($conf->global->$keyforsmtpserver)) ini_set('SMTP', $conf->global->$keyforsmtpserver); if (!empty($conf->global->$keyforsmtpport)) ini_set('smtp_port', $conf->global->$keyforsmtpport); From 1bc8c57d6d2486d5f3919bf12dc5ff5204968f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 21 Nov 2019 22:54:13 +0100 Subject: [PATCH 53/84] Fix $weight_impact $price_impact --- htdocs/product/class/api_products.class.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 2fa4f600b11..bb83630bb72 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1347,9 +1347,12 @@ class Products extends DolibarrApi throw new RestException(401); } - if (empty($id) || empty($weight_impact) || empty($price_impact) || empty($features) || !is_array($features)) { + if (empty($id) || empty($features) || !is_array($features)) { throw new RestException(401); } + + $weight_impact = price2num($weight_impact); + $price_impact = price2num($price_impact); $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); @@ -1406,9 +1409,12 @@ class Products extends DolibarrApi throw new RestException(401); } - if (empty($ref) || empty($weight_impact) || empty($price_impact) || empty($features) || !is_array($features)) { + if (empty($ref) || empty($features) || !is_array($features)) { throw new RestException(401); } + + $weight_impact = price2num($weight_impact); + $price_impact = price2num($price_impact); $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); From 821ca724a5031f0825efec5a94334596505d8292 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 21 Nov 2019 21:54:51 +0000 Subject: [PATCH 54/84] Fixing style errors. --- htdocs/product/class/api_products.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index bb83630bb72..c5ca4271f75 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1350,7 +1350,7 @@ class Products extends DolibarrApi if (empty($id) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); @@ -1412,7 +1412,7 @@ class Products extends DolibarrApi if (empty($ref) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); From e76a112099ec5eff39d77a3f4f87ba049e78146e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 21 Nov 2019 23:09:18 +0100 Subject: [PATCH 55/84] Remove unecessary dol_clone in ::putVariant --- htdocs/product/class/api_products.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index c5ca4271f75..37c950e9956 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1468,8 +1468,6 @@ class Products extends DolibarrApi $prodcomb = new ProductCombination($this->db); $prodcomb->fetch((int) $id); - $old_prodcomb = dol_clone($prodcomb, 0); - foreach($request_data as $field => $value) { if ($field == 'rowid') { continue; } From f4e1361d068b62902b96ae787fba5d7c37005137 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 22 Nov 2019 06:53:05 +0100 Subject: [PATCH 56/84] NEW small fix --- htdocs/core/boxes/box_shipments.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/boxes/box_shipments.php b/htdocs/core/boxes/box_shipments.php index 4852934af74..957c738ad22 100644 --- a/htdocs/core/boxes/box_shipments.php +++ b/htdocs/core/boxes/box_shipments.php @@ -124,7 +124,6 @@ class box_shipments extends ModeleBoxes $orderstatic->id= $objp->commande_id; $orderstatic->ref=$objp->commande_ref; - print $orderstatic->getNomUrl(1); $societestatic->id = $objp->socid; $societestatic->name = $objp->name; From 383f095063b0bf5e7e214f1708c1ebeccac101d8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 22 Nov 2019 09:45:14 +0100 Subject: [PATCH 57/84] Fix trans --- htdocs/langs/en_US/admin.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index e7685ef25b9..05c076625f1 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1905,8 +1905,8 @@ CodeLastResult=Latest result code NbOfEmailsInInbox=Number of emails in source directory LoadThirdPartyFromName=Load third party searching on %s (load only) LoadThirdPartyFromNameOrCreate=Load third party searching on %s (create if not found) -WithDolTrackingID=Dolibarr Tracking ID found -WithoutDolTrackingID=Dolibarr Tracking ID not found +WithDolTrackingID=Dolibarr Reference found in Message ID +WithoutDolTrackingID=Dolibarr Reference not found in Message ID FormatZip=Zip MainMenuCode=Menu entry code (mainmenu) ECMAutoTree=Show automatic ECM tree From 61913078654c3846cecfbcb3227ca15f450f875a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 22 Nov 2019 12:22:27 +0100 Subject: [PATCH 58/84] Debug v11 --- htdocs/admin/mails_senderprofile_list.php | 14 +++++-- .../core/class/emailsenderprofile.class.php | 37 ++++++++++++------- .../install/mysql/migration/10.0.0-11.0.0.sql | 1 + htdocs/theme/md/style.css.php | 3 ++ 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index c5201adedeb..a22c9d79ac5 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -135,6 +135,10 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { + // Actions cancel, add, update, delete or clone + $backurlforlist = $_SERVER["PHP_SELF"].'?action=list'; + include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; + // Selection of new fields include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; @@ -344,7 +348,7 @@ print ''; print ''; print ''; -print ''; +print ''; print ''; print ''; print ''; @@ -365,10 +369,14 @@ if ($action != 'create') { print '
'; $tmpcode = $object->code_client; @@ -1241,6 +1243,10 @@ else if (!empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT)) $default = 1; print $form->selectyesno("fournisseur", (GETPOST('fournisseur', 'int') != '' ?GETPOST('fournisseur', 'int') : (GETPOST("type", 'alpha') == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type", 'alpha') == '' ? 1 : 0)); print '
'; if (!empty($conf->fournisseur->enabled) && !empty($user->rights->fournisseur->lire)) { @@ -1283,7 +1289,9 @@ else // Zip / Town print '
'.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).''; print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 0, '', 'maxwidth100 quatrevingtpercent'); - print ''.$form->editfieldkey('Town', 'town', '', $object, 0).''; + print '
'.$form->editfieldkey('Town', 'town', '', $object, 0).''; print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id'), 0, 0, '', 'maxwidth100 quatrevingtpercent'); print '
'.img_picto('', 'object_phoning').' '.$form->editfieldkey('Phone', 'phone', '', $object, 0).'
'.img_picto('', 'object_phoning_fax').' '.$form->editfieldkey('Fax', 'fax', '', $object, 0).'
'.$form->editfieldkey($idprof, $key, '', $object, 0, 'string', '', (empty($conf->global->$idprof_mandatory) ? 0 : 1)).''; @@ -1401,6 +1410,7 @@ else print ''; print $form->selectyesno('assujtva_value', GETPOSTISSET('assujtva_value') ?GETPOST('assujtva_value', 'int') : 1, 1); // Assujeti par defaut en creation print '
'.$form->editfieldkey('VATIntra', 'intra_vat', '', $object, 0).''; $s = ''; @@ -1462,6 +1472,7 @@ else print $form->selectarray("typent_id", $formcompany->typent_array(0), $object->typent_id, 0, 0, 0, '', 0, 0, 0, $sortparam); if ($user->admin) print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); print '
'.$form->editfieldkey('Staff', 'effectif_id', '', $object, 0).''; print $form->selectarray("effectif_id", $formcompany->effectif_array(0), $object->effectif_id); if ($user->admin) print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 03863576379..e076d6eb58a 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -293,7 +293,7 @@ hr { border: 0; border-top: 1px solid #ccc; } margin-top: 0; margin-left: 5px; margin-right: 5px; - font-family: ; + font-family: ; display: inline-block; padding: 4px 14px; text-align: center; @@ -529,7 +529,9 @@ body[class*="colorblind-"] .text-success{ .fa-toggle-on, .fa-toggle-off { font-size: 2em; } .websiteselectionsection .fa-toggle-on, .websiteselectionsection .fa-toggle-off, -.asetresetmodule .fa-toggle-on, .asetresetmodule .fa-toggle-off { font-size: 1.5em; vertical-align: text-bottom; } +.asetresetmodule .fa-toggle-on, .asetresetmodule .fa-toggle-off { + font-size: 1.5em; vertical-align: text-bottom; +} /* Themes for badges */ @@ -1263,7 +1265,6 @@ div.fiche>table:first-child { margin-bottom: 15px !important; } div.fichecenter { - /* margin-top: 10px; */ width: 100%; clear: both; /* This is to have div fichecenter that are true rectangles */ } @@ -1630,18 +1631,6 @@ li.tmenusel::after, li.tmenu:hover::after{ border-width: 0px 6px 5px 6px; border-color: transparent transparent #ffffff transparent; } -/* -// Add a bottom arrow -li.tmenusel::before, li.tmenu:hover::before{ - content: ""; - position:absolute; - top:0px; - left:0; - width: 100%; - height: 2px; - background: #fff; -}*/ - .tmenuend .tmenuleft { width: 0px; } .tmenuend { display: none; } @@ -2431,6 +2420,11 @@ div.popuptab { padding-left: 5px; padding-right: 5px; } + +/* ============================================================================== */ +/* Buttons for actions */ +/* ============================================================================== */ + div.tabsAction { margin: 20px 0em 30px 0em; padding: 0em 0em; @@ -3113,7 +3107,9 @@ tr.liste_titre:last-child th.liste_titre, tr.liste_titre:last-child th.liste_tit border-bottom: unset; } - +div.liste_titre { + padding-left: 3px; +} tr.liste_titre_sel th, th.liste_titre_sel, tr.liste_titre_sel td, td.liste_titre_sel, form.liste_titre_sel div { font-family: ; @@ -3246,7 +3242,6 @@ ul.noborder li:nth-child(even):not(.liste_titre) { min-height: 40px; padding-right: 0px; padding-left: 0px; - /*padding-bottom: 25px;*/ padding-bottom: 10px; } .ficheaddleft div.boxstats, .ficheaddright div.boxstats { @@ -3380,9 +3375,6 @@ span.dashboardlineok { } span.dashboardlineko { color: #FFF; - /*color: #8c4446 ! important; - padding-left: 1px;*/ - font-size: 80%; } .dashboardlinelatecoin { @@ -4493,7 +4485,6 @@ td.gminorheading { .ecmfiletree { width: 99%; height: 99%; - /* background: #FFF; */ padding-left: 2px; font-weight: normal; } @@ -5962,6 +5953,11 @@ div.tabsElem a.tab { .text-plus-circle { display: none; } + + table.table-fiche-title .col-title div.titre{ + line-height: unset; + } + } global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255'; // card $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234'; $conf->global->THEME_ELDY_TEXT='0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1='0.86em'; + $conf->global->THEME_ELDY_FONT_SIZE1=$fontsize; $conf->global->THEME_ELDY_FONT_SIZE2='0.75em'; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index ea1a70b6c2b..d704ce13cbf 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -44,7 +44,6 @@ define('ISLOADEDBYSTEELSHEET', '1'); require __DIR__.'/theme_vars.inc.php'; if (defined('THEME_ONLY_CONSTANT')) return; - session_cache_limiter('public'); @@ -112,7 +111,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_BACKTABCARD1 = '255,255,255'; // card $conf->global->THEME_ELDY_BACKTABACTIVE = '234,234,234'; $conf->global->THEME_ELDY_TEXT = '0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1 = '14'; + $conf->global->THEME_ELDY_FONT_SIZE1 = $fontsize; $conf->global->THEME_ELDY_FONT_SIZE2 = '11'; } @@ -238,7 +237,7 @@ body { background: rgb(); color: rgb(); - font-size: px; + font-size: ; line-height: 1.3; font-family: ; margin-top: 0; @@ -300,7 +299,6 @@ select#date_startday, select#date_startmonth, select#date_endday, select#date_en margin-right: 4px; } input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select { - font-size: px; font-family: ; border: none; borderglobal->THEME_HIDE_BORDER_ON_INPUT) ? '-bottom' : ''; ?>: solid 1px rgba(0,0,0,.2); @@ -422,7 +420,7 @@ a.buttonticket { padding-right: 5px; } -/* Used for timesheets */ +/* Used by timesheets */ span.timesheetalreadyrecorded input { border: none; border-bottom: solid 1px rgba(0,0,0,0.1); @@ -434,9 +432,6 @@ td.onholidaymorning, td.onholidayafternoon { td.onholidayallday { background-color: #f4eede; } -td.actionbuttons a { - padding-left: 6px; -} td.leftborder, td.hide0 { border-left: 1px solid #ccc; } @@ -447,6 +442,9 @@ td.rightborder { border-right: 1px solid #ccc; } +td.actionbuttons a { + padding-left: 6px; +} select.flat, form.flat select { font-weight: normal; font-size: unset; @@ -467,8 +465,9 @@ select.flat, form.flat select { .opacitytransp { opacity: 0; } -select:invalid { color: gray; } - +select:invalid { + color: gray; +} input:disabled, textarea:disabled, select[disabled='disabled'] { background:#eee; @@ -514,13 +513,13 @@ div#moretabsList, div#moretabsListaction { hr { border: 0; border-top: 1px solid #ccc; } .button, .buttonDelete, input[name="sbmtConnexion"] { - font-family: ; border-color: #c5c5c5; border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); display: inline-block; padding: 4px 14px; margin-bottom: 0; margin-top: 0; + font-family: ; text-align: center; cursor: pointer; color: #333333 !important; @@ -567,6 +566,9 @@ hr { border: 0; border-top: 1px solid #ccc; } border: unset; background: unset; } +.button_search:hover, .button_removefilter:hover { + cursor: pointer; +} form { padding:0px; margin:0px; @@ -621,6 +623,19 @@ th .button { textarea.centpercent { width: 96%; } +.small, small { + font-size: 85%; +} + +.h1 .small, .h1 small, .h2 .small, .h2 small, .h3 .small, .h3 small, h1 .small, h1 small, h2 .small, h2 small, h3 .small, h3 small { + font-size: 65%; +} +.h1 .small, .h1 small, .h2 .small, .h2 small, .h3 .small, .h3 small, .h4 .small, .h4 small, .h5 .small, .h5 small, .h6 .small, .h6 small, h1 .small, h1 small, h2 .small, h2 small, h3 .small, h3 small, h4 .small, h4 small, h5 .small, h5 small, h6 .small, h6 small { + font-weight: 400; + line-height: 1; + color: #777; +} + .center { text-align: center; margin: 0px auto; @@ -634,6 +649,12 @@ textarea.centpercent { .justify { text-align: justify; } +.pull-left { + float: left!important; +} +.pull-right { + float: right!important; +} .nowrap { white-space: ; } @@ -722,15 +743,18 @@ body[class*="colorblind-"] .text-success{ color : } -.editfielda span.fa-pencil-alt { +.editfielda span.fa-pencil-alt, .editfielda span.fa-trash { color: #ccc !important; } -.editfielda span.fa-pencil-alt:hover { +.editfielda span.fa-pencil-alt:hover, .editfielda span.fa-trash:hover { color: rgb() !important; } .fa-toggle-on, .fa-toggle-off { font-size: 2em; } -.websiteselectionsection .fa-toggle-on, .websiteselectionsection .fa-toggle-off { font-size: 1.5em; vertical-align: text-bottom; } +.websiteselectionsection .fa-toggle-on, .websiteselectionsection .fa-toggle-off, +.asetresetmodule .fa-toggle-on, .asetresetmodule .fa-toggle-off { + font-size: 1.5em; vertical-align: text-bottom; +} /* Themes for badges */ @@ -768,6 +792,14 @@ div.divsearchfield { padding-bottom: 5px; opacity: 0.6; } +browser->layout == 'phone') { + ?> +.divsearchfieldfilter { + white-space: nowrap; +} + div.confirmmessage { padding-top: 6px; } @@ -804,13 +836,13 @@ select.flat.selectlimit { margin-right: 10px !important; } .marginleftonly { - margin-left: 10px !important; + margin-: 10px !important; } .marginleftonlyshort { - margin-left: 4px !important; + margin-: 4px !important; } .nomarginleft { - margin-left: 0px !important; + margin-: 0px !important; } .margintoponly { margin-top: 10px !important; @@ -871,6 +903,20 @@ select.flat.selectlimit { max-width: 0; overflow: auto; } +.divintdwithtwolinesmax { + width: 75px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} +.twolinesmax { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} + .tablelistofcalendars { margin-top: 25px !important; } @@ -914,6 +960,10 @@ select.flat.selectlimit { color: #505; } +.fa-15 { + font-size: 1.5em; +} + /* DOL_XXX for future usage (when left menu has been removed). If we do not use datatable */ /*.table-responsive { width: calc(100% - 330px); @@ -938,7 +988,7 @@ div.fiche>form>div.div-table-responsive { } .flexcontainer { - browser->browsername, array('chrome', 'firefox'))) echo 'display: inline-flex;' ?> + browser->name, array('chrome', 'firefox'))) echo 'display: inline-flex;' ?> flex-flow: row wrap; justify-content: flex-start; } @@ -1032,6 +1082,16 @@ table[summary="list_of_modules"] .fa-cog { .titlefield { /* width: 25%; */ width: 250px; } .titlefieldmiddle { width: 50%; } .imgmaxwidth180 { max-width: 180px; } +.imgmaxheight50 { max-height: 50px; } + +.width20p { width:20%; } +.width25p { width:25%; } +.width40p { width:40%; } +.width50p { width:50%; } +.width60p { width:60%; } +.width75p { width:75%; } +.width80p { width:80%; } +.width100p { width:100%; } /* Force values for small screen 1400 */ @@ -1047,6 +1107,11 @@ table[summary="list_of_modules"] .fa-cog { .minwidth300imp { min-width: 300px !important; } .minwidth400imp { min-width: 300px !important; } .minwidth500imp { min-width: 300px !important; } + + + .linkedcol-element { + min-width: unset; + } } /* Force values for small screen 1000 */ @@ -1067,10 +1132,10 @@ table[summary="list_of_modules"] .fa-cog { @media only screen and (max-width: 767px) { body { - font-size: ; + font-size: ; } div.refidno { - font-size: !important; + font-size: !important; } } @@ -1078,10 +1143,10 @@ table[summary="list_of_modules"] .fa-cog { @media only screen and (max-width: 570px) { body { - font-size: px; + font-size: ; } div.refidno { - font-size: px !important; + font-size: !important; } .login_vertical_align { @@ -1099,7 +1164,7 @@ table[summary="list_of_modules"] .fa-cog { div.fiche { margin-top: px !important; } - .border tbody tr, .border tbody tr td, div.tabBar table.border tr { + .border tbody tr, .border tbody tr td, div.tabBar table.border tr, div.tabBar table.border tr td, div.tabBar div.border .table-border-row, div.tabBar div.border .table-key-border-col, div.tabBar div.border .table-val-border-col { height: 40px !important; } @@ -1112,6 +1177,9 @@ table[summary="list_of_modules"] .fa-cog { padding-bottom: 5px; } + .login_table .tdinputlogin { + min-width: unset !important; + } input, input[type=text], input[type=password], select, textarea { min-width: 20px; min-height: 1.4em; @@ -1119,6 +1187,7 @@ table[summary="list_of_modules"] .fa-cog { } .hideonsmartphone { display: none; } + .hideonsmartphoneimp { display: none !important; } .noenlargeonsmartphone { width : 50px !important; display: inline !important; } .maxwidthonsmartphone, #search_newcompany.ui-autocomplete-input { max-width: 100px; } .maxwidth50onsmartphone { max-width: 40px; } @@ -1152,7 +1221,7 @@ table[summary="list_of_modules"] .fa-cog { } div.divphotoref { - padding-right: 5px; + padding-: 5px; padding-bottom: 5px; } img.photoref, div.photoref { @@ -1410,6 +1479,9 @@ div.fiche { body.onlinepaymentbody div.fiche { /* For online payment page */ margin: 20px !important; } +div.fiche>table:first-child { + margin-bottom: 15px !important; +} div.fichecenter { width: 100%; clear: both; /* This is to have div fichecenter that are true rectangles */ @@ -1496,17 +1568,13 @@ div.secondcolumn div.box { } /* For table into table into card */ -div.fichehalfright tr.liste_titre:first-child td table.nobordernopadding td, div.nopadding { +div.fichehalfright tr.liste_titre:first-child td table.nobordernopadding td { padding: 0 0 0 0; } div.nopadding { padding: 0 !important; } -/*table.noborder tr.liste_titre td { - padding: 3px !important; -}*/ - .containercenter { display : table; margin : 0px auto; @@ -1575,7 +1643,7 @@ div.heightref { min-height: 80px; } div.divphotoref { - padding-right: 20px; + padding-: 20px; } div.paginationref { padding-bottom: 10px; @@ -1626,7 +1694,7 @@ img.photorefnoborder { .underrefbanner { } .underbanner { - border-bottom: px solid rgb(); + border-bottom: px solid rgb(); } .trextrafieldseparator td { @@ -1922,9 +1990,7 @@ div.mainmenu.website { 'don'=>'accountancy', 'tax'=>'accountancy', 'banque'=>'accountancy', 'facture'=>'accountancy', 'compta'=>'accountancy', 'accounting'=>'accountancy', 'adherent'=>'members', 'import'=>'tools', 'export'=>'tools', 'mailing'=>'tools', 'contrat'=>'commercial', 'ficheinter'=>'commercial', 'ticket'=>'ticket', 'deplacement'=>'commercial', 'fournisseur'=>'companies', - 'barcode'=>'', - 'fckeditor'=>'', - 'categorie'=>'', + 'barcode'=>'', 'fckeditor'=>'', 'categorie'=>'', ); $mainmenuused = 'home'; foreach ($conf->modules as $val) @@ -2507,6 +2573,7 @@ div.tabBar.tabBarNoTop { } */ +/* tabBar used for creation/update/send forms */ div.tabBarWithBottom { padding-bottom: 18px; border-bottom: 1px solid #aaa; @@ -2517,6 +2584,10 @@ div.tabBar table.tableforservicepart2:last-child { .tableforservicepart1 .tdhrthin { height: unset; } +/* Payment Screen : Pointer cursor in the autofill image */ +.AutoFillAmount { + cursor:pointer; +} /* ============================================================================== */ /* Buttons for actions */ @@ -2680,6 +2751,10 @@ tr.nocellnopadd td.nobordernopadding, tr.nocellnopadd td.nocellnopadd margin: 0px 0px 0px 0px; } +table.tableforemailform tr td { + padding-top: 3px; + padding-bottom: 3px; +} table.border, table.bordernooddeven, table.dataTable, .table-border, .table-border-col, .table-key-border-col, .table-val-border-col, div.border { border: 1px solid #f4f4f4; @@ -2690,7 +2765,7 @@ table.borderplus { border: 1px solid #BBB; } -.border tbody tr, .border tbody tr td, div.tabBar table.border tr, div.tabBar table.border tr td, div.tabBar div.border .table-border-row, div.tabBar div.border .table-key-border-col, div.tabBar div.border .table-val-border-col { +.border tbody tr, .bordernooddeven tbody tr, .border tbody tr td, .bordernooddeven tbody tr td, div.tabBar table.border tr, div.tabBar table.border tr td, div.tabBar div.border .table-border-row, div.tabBar div.border .table-key-border-col, div.tabBar div.border .table-val-border-col { height: 26px; } tr.liste_titre.box_titre td table td, .bordernooddeven tr td { @@ -3051,7 +3126,16 @@ ul.noborder li:nth-child(odd):not(.liste_titre) { } -.oddeven, .evenodd, .impair, .nohover .impair:hover, tr.impair td.nohover +.nohover:hover { + background: unset; +} +.nohoverborder:hover { + border: unset; + box-shadow: unset; + -webkit-box-shadow: unset; +} + +.oddeven, .evenodd, .impair, .nohover .impair:hover, tr.impair td.nohover, .tagtr.oddeven { font-family: ; border: 0px; @@ -3063,10 +3147,10 @@ ul.noborder li:nth-child(odd):not(.liste_titre) { background: #; } #GanttChartDIV { - background: #; + background-color: #; } -.oddeven, .evenodd, .pair, .nohover .pair:hover, tr.pair td.nohover { +.oddeven, .evenodd, .pair, .nohover .pair:hover, tr.pair td.nohover, .tagtr.oddeven { font-family: ; margin-bottom: 1px; color: #202020; @@ -3083,7 +3167,7 @@ td.oddeven, table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.imp background-color: # !important; background: # !important; } -td.evenodd, tr.nohoverpair td { +td.evenodd, tr.nohoverpair td, #trlinefordates td { background-color: # !important; background: # !important; } @@ -3388,9 +3472,9 @@ ul.noborder li:nth-child(even):not(.liste_titre) { box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.20); } span.boxstatstext { + /* opacity: 0.7; */ /* a bug if browser make z-index infintie when opacity is set so we disable it */ line-height: 18px; color: #000; - /* opacity: 0.7; */ /* a bug if browser make z-index infintie when opacity is set so we disable it */ } .boxstatsindicator.thumbstat150 { /* If we remove this, box position is ko on ipad */ display: inline-flex; @@ -3499,7 +3583,10 @@ img.boxhandle, img.boxclose { vertical-align: middle; } - +.modulebuilderbox { + border: 1px solid #888; + padding: 16px; +} @@ -3667,6 +3754,9 @@ div.titre, .secondary { color: rgb(); } +table.centpercent.notopnoleftnoright.table-fiche-title { + margin-bottom: 10px !important; +} table.table-fiche-title .col-title div.titre{ line-height: 40px; } @@ -3743,6 +3833,19 @@ div#card-errors { font-size: px !important; } + +/* ============================================================================== */ +/* For content of image preview */ +/* ============================================================================== */ + +/* +.ui-dialog-content.ui-widget-content > object { + max-height: none; + width: auto; margin-left: auto; margin-right: auto; display: block; +} +*/ + + /* ============================================================================== */ /* Formulaire confirmation (When HTML is used) */ /* ============================================================================== */ @@ -3939,6 +4042,9 @@ tr.visible { display: inline-block; padding: 4px 0 4px 0; } +.websitebar .buttonDelete, .websitebar .button { + text-shadow: none; +} .websitebar .button, .websitebar .buttonDelete { padding: 2px 4px 2px 4px !important; @@ -3958,17 +4064,21 @@ tr.visible { float: right; } .websiteselection, .websitetools { - margin-top: 3px; + /* margin-top: 3px; padding-top: 3px; - padding-bottom: 3px; + padding-bottom: 3px; */ } .websiteinputurl { display: inline-block; vertical-align: top; + line-height: 28px; } .websiteiframenoborder { border: 0px; } +span.websitebuttonsitepreview, a.websitebuttonsitepreview { + vertical-align: middle; +} span.websitebuttonsitepreview img, a.websitebuttonsitepreview img { width: 26px; display: inline-block; @@ -3984,6 +4094,14 @@ span.websitebuttonsitepreviewdisabled img, a.websitebuttonsitepreviewdisabled im float: right; padding-top: 8px; } +.websiteselectionsection { + border-left: 1px solid #bbb; + border-right: 1px solid #bbb; + margin-left: 0px; + padding-left: 8px; + margin-right: 5px; +} + /* ============================================================================== */ /* Module agenda */ @@ -4028,6 +4146,8 @@ table.cal_event td.cal_event_right { padding: 4px 4px !important; } .cal_event_busy { } .cal_peruserviewname { max-width: 140px; height: 22px; } +.calendarviewcontainertr { height: 100px; } + .topmenuimage { background-size: 24px auto; } @@ -4262,7 +4382,6 @@ A.none, A.none:active, A.none:visited, A.none:hover { } .ui-widget { font-family:; - font-size:px; } .ui-button { margin-left: -2px; browser->name) ? 'padding-top: 1px;' : ''); ?> } .ui-button-icon-only .ui-button-text { height: 8px; } @@ -4278,6 +4397,10 @@ A.none, A.none:active, A.none:visited, A.none:hover { /* CKEditor */ /* ============================================================================== */ +body.cke_show_borders { + margin: 5px !important; +} + .cke_dialog { border: 1px #bbb solid ! important; } @@ -4387,6 +4510,65 @@ pre#editfilecontentaceeditorid { } +/* ============================================================================== */ +/* Comments */ +/* ============================================================================== */ + +#comment div { + box-sizing:border-box; +} +#comment .comment { + border-radius:7px; + margin-bottom:10px; + overflow:hidden; +} +#comment .comment-table { + display:table; + height:100%; +} +#comment .comment-cell { + display:table-cell; +} +#comment .comment-info { + font-size:0.8em; + border-right:1px solid #dedede; + margin-right:10px; + width:160px; + text-align:center; + background:rgba(255,255,255,0.5); + vertical-align:middle; + padding:10px 2px; +} +#comment .comment-info a { + color:inherit; +} +#comment .comment-right { + vertical-align:top; +} +#comment .comment-description { + padding:10px; + vertical-align:top; +} +#comment .comment-delete { + width: 100px; + text-align:center; + vertical-align:middle; +} +#comment .comment-delete:hover { + background:rgba(250,20,20,0.8); +} +#comment .comment-edit { + width: 100px; + text-align:center; + vertical-align:middle; +} +#comment .comment-edit:hover { + background:rgba(0,184,148,0.8); +} +#comment textarea { + width: 100%; +} + /* ============================================================================== */ /* JSGantt */ @@ -4481,10 +4663,6 @@ ul.filedirelem li { border: solid 1px #f4f4f4; } -.ui-layout-north { - -} - ul.ecmjqft { line-height: 16px; padding: 0px; @@ -4554,6 +4732,7 @@ div#ecm-layout-center { max-width: 1024px; padding-left: 10px !important; padding-right: 10px !important; + word-wrap: break-word; } .jnotify-container .jnotify-notification .jnotify-message { font-weight: normal; @@ -4591,7 +4770,7 @@ div.dolEventError h1, div.dolEventError h2 { /* Maps */ /* ============================================================================== */ -.divmap, #google-visualization-geomap-embed-0, #google-visualization-geomap-embed-1, google-visualization-geomap-embed-2 { +.divmap, #google-visualization-geomap-embed-0, #google-visualization-geomap-embed-1, #google-visualization-geomap-embed-2 { } @@ -5031,7 +5210,7 @@ dl.dropdown { } .dropdown ul { margin: -1px 0 0 0; - text-align: left; + text-align: ; } .dropdown dd { position:relative; @@ -5053,7 +5232,7 @@ dl.dropdown { background-color: #FFF; box-shadow: 1px 1px 10px #aaa; display:none; - right:0px; /* pop is align on right */ + :0px; /* pop is align on right */ padding: 0 0 0 0; position:absolute; top:2px; @@ -5065,13 +5244,14 @@ dl.dropdown { white-space: nowrap; font-weight: normal; padding: 7px 8px 7px 8px; + /* color: rgb(); */ color: #000; } .dropdown dd ul li:hover { background: #eee; } .dropdown dd ul li input[type="checkbox"] { - margin-right: 3px; + margin-: 3px; } .dropdown dd ul li a, .dropdown dd ul li span { padding: 3px; @@ -5125,7 +5305,7 @@ a.ui-link, a.ui-link:hover, .ui-btn:hover, span.ui-btn-text:hover, span.ui-btn-i min-width: .4em; padding-left: 6px; padding-right: 6px; - font-size: px; + font-size: ; /* white-space: normal; */ /* Warning, enable this break the truncate feature */ } .ui-btn-icon-right .ui-btn-inner { @@ -5845,7 +6025,7 @@ border-top-right-radius: 6px; } .titlefield { - width: auto !important; /* We want to ignor the 30%, try to use more if you can */ + width: auto !important; /* We want to ignore the 30%, try to use more if you can */ } .tableforfield>tr>td:first-child, .tableforfield>tbody>tr>td:first-child, div.tableforfield div.tagtr>div.tagtd:first-of-type { /* max-width: 100px; */ /* but no more than 100px */ @@ -5853,6 +6033,10 @@ border-top-right-radius: 6px; .tableforfield>tr>td:nth-child(2), .tableforfield>tbody>tr>td:nth-child(2), div.tableforfield div.tagtr>div.tagtd:nth-child(2) { word-break: break-word; } + + table.table-fiche-title .col-title div.titre{ + line-height: unset; + } } diff --git a/htdocs/theme/md/theme_vars.inc.php b/htdocs/theme/md/theme_vars.inc.php index 6bf6ae20138..720879eadec 100644 --- a/htdocs/theme/md/theme_vars.inc.php +++ b/htdocs/theme/md/theme_vars.inc.php @@ -67,7 +67,7 @@ $colortexttitlenotab='90,90,90'; $colortexttitle='20,20,20'; $colortext='0,0,0'; $colortextlink='0,0,120'; -$fontsize='14'; +$fontsize = '14'; $fontsizesmaller='11'; // text color From 58c38912ab1abc03b58a40f9cffa13b1f7db92c2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2019 16:42:18 +0100 Subject: [PATCH 20/84] Fix action into actionlogin to avoid conflict --- htdocs/core/tpl/login.tpl.php | 2 +- htdocs/main.inc.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index e74f76669cf..6ea964bbc66 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -91,7 +91,7 @@ $(document).ready(function () {
- + diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 3e623433db8..44a61a9ac39 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -553,7 +553,7 @@ if (!defined('NOLOGIN')) // Validation of login/pass/entity // If ok, the variable login will be returned // If error, we will put error message in session under the name dol_loginmesg - if ($test && $goontestloop && GETPOST('action', 'aZ09') == 'login') + if ($test && $goontestloop && GETPOST('actionlogin', 'aZ09') == 'login') { $login = checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $authmode); if ($login) @@ -611,8 +611,8 @@ if (!defined('NOLOGIN')) // End test login / passwords if (! $login || (in_array('ldap', $authmode) && empty($passwordtotest))) // With LDAP we refused empty password because some LDAP are "opened" for anonymous access so connexion is a success. { - // No data to test login, so we show the login page - dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." - action=".GETPOST('action', 'aZ09').", showing the login form and exit"); + // No data to test login, so we show the login page. + dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." - action=".GETPOST('action', 'aZ09')." - actionlogin=".GETPOST('actionlogin', 'aZ09')." - showing the login form and exit"); if (defined('NOREDIRECTBYMAINTOLOGIN')) return 'ERROR_NOT_LOGGED'; else dol_loginfunction($langs, $conf, (! empty($mysoc)?$mysoc:'')); exit; From f7319aeefbde8ceee530793003640d69a4094925 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2019 18:50:03 +0100 Subject: [PATCH 21/84] Fix size of field --- htdocs/install/mysql/migration/10.0.0-11.0.0.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index 03b04979896..fc488071d54 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -48,9 +48,13 @@ UPDATE llx_c_units SET label = 'SurfaceUnitm2' WHERE code IN ('M2'); ALTER TABLE llx_adherent_type ADD UNIQUE INDEX uk_adherent_type_libelle (libelle, entity); +ALTER TABLE llx_mailing_cibles MODIFY COLUMN lastname varchar(160); +ALTER TABLE llx_mailing_cibles MODIFY COLUMN firstname varchar(160); + -- For v11 + insert into llx_c_type_container (code,label,module,active) values ('menu', 'Menu', 'system', 1); INSERT INTO llx_c_ticket_type (code, pos, label, active, use_default, description) VALUES('HELP', '15', 'Request for functionnal help', 1, 0, NULL); From 2f064567efbc2d505efa4801acd66ae06ca9645d Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 21 Nov 2019 07:50:44 +0100 Subject: [PATCH 22/84] NEW Add shipment widget --- htdocs/core/boxes/box_shipments.php | 191 ++++++++++++++++++++ htdocs/core/modules/modExpedition.class.php | 4 +- htdocs/langs/en_US/boxes.lang | 3 + 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 htdocs/core/boxes/box_shipments.php diff --git a/htdocs/core/boxes/box_shipments.php b/htdocs/core/boxes/box_shipments.php new file mode 100644 index 00000000000..4852934af74 --- /dev/null +++ b/htdocs/core/boxes/box_shipments.php @@ -0,0 +1,191 @@ + + * Copyright (C) 2004-2009 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2019 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/boxes/box_shipments.php + * \ingroup shipment + * \brief Module for generating the display of the shipment box + */ + +include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php'; + + +/** + * Class to manage the box to show last shipments + */ +class box_shipments extends ModeleBoxes +{ + public $boxcode="lastcustomershipments"; + public $boximg="sending"; + public $boxlabel="BoxLastCustomerShipments"; + public $depends = array("expedition"); + + /** + * @var DoliDB Database handler. + */ + public $db; + + public $param; + + public $info_box_head = array(); + public $info_box_contents = array(); + + + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param string $param More parameters + */ + public function __construct($db, $param) + { + global $user; + + $this->db=$db; + + $this->hidden=! ($user->rights->expedition->lire); + } + + /** + * Load data for box to show them later + * + * @param int $max Maximum number of records to load + * @return void + */ + public function loadBox($max = 5) + { + global $user, $langs, $conf; + $langs->loadLangs(array('orders', 'sendings')); + + $this->max = $max; + + include_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; + include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + + $shipmentstatic = new Expedition($this->db); + $orderstatic = new Commande($this->db); + $societestatic = new Societe($this->db); + + $this->info_box_head = array('text' => $langs->trans("BoxTitleLastCustomerShipments", $max)); + + if ($user->rights->expedition->lire) + { + $sql = "SELECT s.nom as name"; + $sql.= ", s.rowid as socid"; + $sql.= ", s.code_client"; + $sql.= ", s.logo, s.email"; + $sql.= ", e.ref, e.tms"; + $sql.= ", e.rowid"; + $sql.= ", e.ref_customer"; + $sql.= ", e.fk_statut"; + $sql.= ", e.fk_user_valid"; + $sql.= ", c.ref as commande_ref"; + $sql.= ", c.rowid as commande_id"; + $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON e.rowid = el.fk_target AND el.targettype = 'shipping' AND el.sourcetype IN ('commande')"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON el.fk_source = c.rowid AND el.sourcetype IN ('commande') AND el.targettype = 'shipping'"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc"; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON e.fk_soc = sc.fk_soc"; + $sql.= " WHERE e.entity = ".$conf->entity; + if (! empty($conf->global->ORDER_BOX_LAST_SHIPMENTS_VALIDATED_ONLY)) $sql.=" AND e.fk_statut = 1"; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND sc.fk_user = " .$user->id; + else $sql.= " ORDER BY e.date_delivery, e.ref DESC "; + $sql.= $this->db->plimit($max, 0); + + $result = $this->db->query($sql); + if ($result) { + $num = $this->db->num_rows($result); + + $line = 0; + + while ($line < $num) { + $objp = $this->db->fetch_object($result); + + $shipmentstatic->id = $objp->rowid; + $shipmentstatic->ref = $objp->ref; + $shipmentstatic->ref_customer = $objp->ref_customer; + + $orderstatic->id= $objp->commande_id; + $orderstatic->ref=$objp->commande_ref; + print $orderstatic->getNomUrl(1); + + $societestatic->id = $objp->socid; + $societestatic->name = $objp->name; + $societestatic->email = $objp->email; + $societestatic->code_client = $objp->code_client; + $societestatic->logo = $objp->logo; + + $this->info_box_contents[$line][] = array( + 'td' => '', + 'text' => $shipmentstatic->getNomUrl(1), + 'asis' => 1, + ); + + $this->info_box_contents[$line][] = array( + 'td' => 'class="tdoverflowmax150 maxwidth150onsmartphone"', + 'text' => $societestatic->getNomUrl(1), + 'asis' => 1, + ); + + $this->info_box_contents[$line][] = array( + 'td' => '', + 'text' => $orderstatic->getNomUrl(1), + 'asis' => 1, + ); + + $this->info_box_contents[$line][] = array( + 'td' => 'class="right" width="18"', + 'text' => $shipmentstatic->LibStatut($objp->fk_statut, 3), + ); + + $line++; + } + + if ($num==0) $this->info_box_contents[$line][0] = array('td' => 'class="center"','text'=>$langs->trans("NoRecordedShipments")); + + $this->db->free($result); + } else { + $this->info_box_contents[0][0] = array( + 'td' => '', + 'maxlength'=>500, + 'text' => ($this->db->error().' sql='.$sql), + ); + } + } else { + $this->info_box_contents[0][0] = array( + 'td' => 'class="nohover opacitymedium left"', + 'text' => $langs->trans("ReadPermissionNotAllowed") + ); + } + } + + /** + * Method to show box + * + * @param array $head Array with properties of box title + * @param array $contents Array with properties of box lines + * @param int $nooutput No print, only return string + * @return string + */ + public function showBox($head = null, $contents = null, $nooutput = 0) + { + return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput); + } +} diff --git a/htdocs/core/modules/modExpedition.class.php b/htdocs/core/modules/modExpedition.class.php index 68f4a3d5fba..d8225a1b2a5 100644 --- a/htdocs/core/modules/modExpedition.class.php +++ b/htdocs/core/modules/modExpedition.class.php @@ -133,7 +133,9 @@ class modExpedition extends DolibarrModules $r++; // Boxes - $this->boxes = array(); + $this->boxes = array( + 0=>array('file'=>'box_shipments.php','enabledbydefaulton'=>'Home'), + ); // Permissions $this->rights = array(); diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index a55a0194632..8fe1f84b149 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -97,3 +97,6 @@ BoxSuspenseAccount=Count accountancy operation with suspense account BoxTitleSuspenseAccount=Number of unallocated lines NumberOfLinesInSuspenseAccount=Number of line in suspense account SuspenseAccountNotDefined=Suspense account isn't defined +BoxLastCustomerShipments=Last customer shipments +BoxTitleLastCustomerShipments=Latest %s customer shipments +NoRecordedShipments=No recorded customer shipment From f6c5605fd5fdf05c38a6c4b86bae7f48c2be0895 Mon Sep 17 00:00:00 2001 From: Tobias Sekan Date: Thu, 21 Nov 2019 08:29:47 +0100 Subject: [PATCH 23/84] Fix number of tasks on dashboard always zero --- htdocs/projet/class/task.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index bc122367312..60657b08061 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1985,7 +1985,7 @@ class Task extends CommonObject $sql .= " WHERE p.entity IN (".getEntity('project', 0).')'; $sql .= " AND p.fk_statut = 1"; $sql .= " AND t.fk_projet = p.rowid"; - $sql .= " AND t.progress < 100"; // tasks to do + $sql .= " AND (t.progress IS NULL OR t.progress < 100)"; // tasks to do if (!$user->rights->projet->all->lire) $sql .= " AND p.rowid IN (".$projectsListId.")"; // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; From 2c183fe279cf34753c0b56942ba749743a57f264 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Thu, 21 Nov 2019 09:22:44 +0100 Subject: [PATCH 24/84] fix : invoid sql injection --- htdocs/commande/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 1de1e64e0c7..9e34c745fab 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -80,7 +80,7 @@ $search_total_ttc = GETPOST('search_total_ttc', 'alpha'); $search_categ_cus = trim(GETPOST("search_categ_cus", 'int')); $optioncss = GETPOST('optioncss', 'alpha'); $billed = GETPOST('billed', 'int'); -$viewstatut = GETPOST('viewstatut'); +$viewstatut = GETPOST('viewstatut', 'int'); $search_btn = GETPOST('button_search', 'alpha'); $search_remove_btn = GETPOST('button_removefilter', 'alpha'); $search_project_ref = GETPOST('search_project_ref', 'alpha'); From 54d67de538b017aa47dbce26d103c75e3bd37244 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Thu, 21 Nov 2019 09:44:13 +0100 Subject: [PATCH 25/84] fix : invoid sql injection --- htdocs/accountancy/bookkeeping/balance.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 02174ea2524..86ec1162832 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; // Load translation files required by the page $langs->loadLangs(array("accountancy")); -$page = GETPOST("page"); +$page = GETPOST("page", 'int'); $sortorder = GETPOST("sortorder", 'alpha'); $sortfield = GETPOST("sortfield", 'alpha'); $action = GETPOST('action', 'aZ09'); From 9996c1ca7a9e19b89b0a6c4f122c11a4d43c4f41 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Thu, 21 Nov 2019 09:49:53 +0100 Subject: [PATCH 26/84] fix : invoid sql injection --- htdocs/accountancy/bookkeeping/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index d898be2b208..0db4c7b6c24 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -575,8 +575,8 @@ if ($action == 'delmouv') { } if ($action == 'delbookkeepingyear') { $form_question = array(); - $delyear = GETPOST('delyear'); - $deljournal = GETPOST('deljournal'); + $delyear = GETPOST('delyear', 'int'); + $deljournal = GETPOST('deljournal', 'alpha'); if (empty($delyear)) { $delyear = dol_print_date(dol_now(), '%Y'); From 3daeb24da1ff2adf2d0c312156c41bb46254441f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2019 13:05:13 +0100 Subject: [PATCH 27/84] Fix confusion with field name in sql --- htdocs/comm/remx.php | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index eabb217fb99..7a8b03cde4e 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -739,8 +739,8 @@ if ($socid > 0) $sql.= " rc.datec as dc, rc.description, rc.fk_facture_line, rc.fk_facture,"; $sql.= " rc.fk_facture_source,"; $sql.= " u.login, u.rowid as user_id,"; - $sql.= " f.rowid, f.ref,"; - $sql.= " fa.ref as ref, fa.type as type"; + $sql.= " f.rowid as invoiceid, f.ref,"; + $sql.= " fa.ref as invoice_source_ref, fa.type as type"; $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql.= " , ".MAIN_DB_PREFIX."user as u"; $sql.= " , ".MAIN_DB_PREFIX."facturedet as fc"; @@ -758,8 +758,8 @@ if ($socid > 0) $sql2.= " rc.datec as dc, rc.description, rc.fk_facture_line, rc.fk_facture,"; $sql2.= " rc.fk_facture_source,"; $sql2.= " u.login, u.rowid as user_id,"; - $sql2.= " f.rowid, f.ref,"; - $sql2.= " fa.ref as ref, fa.type as type"; + $sql2.= " f.rowid as invoiceid, f.ref,"; + $sql2.= " fa.ref as invoice_source_ref, fa.type as type"; $sql2.= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql2.= " , ".MAIN_DB_PREFIX."user as u"; $sql2.= " , ".MAIN_DB_PREFIX."societe_remise_except as rc"; @@ -833,7 +833,7 @@ if ($socid > 0) { print '
'; $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; + $facturestatic->ref=$obj->invoice_source_ref; $facturestatic->type=$obj->type; print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).' '.$facturestatic->getNomURl(1); print ''; $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; + $facturestatic->ref=$obj->invoice_source_ref; $facturestatic->type=$obj->type; print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).' '.$facturestatic->getNomURl(1); print ''; $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; + $facturestatic->ref=$obj->invoice_source_ref; $facturestatic->type=$obj->type; print preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("Invoice"), $obj->description).' '.$facturestatic->getNomURl(1); print ''.img_object($langs->trans("ShowBill"), 'bill').' '.$obj->ref.''; + if ($obj->invoiceid) + { + print ''.img_object($langs->trans("ShowBill"), 'bill').' '.$obj->ref.''; + } + print ''.price($obj->amount_ht).''; $facturefournstatic->id=$obj->fk_invoice_supplier_source; - $facturefournstatic->ref=$obj->ref; + $facturefournstatic->ref=$obj->invoice_source_ref; $facturefournstatic->type=$obj->type; print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).' '.$facturefournstatic->getNomURl(1); print ''; $facturefournstatic->id=$obj->fk_invoice_supplier_source; - $facturefournstatic->ref=$obj->ref; + $facturefournstatic->ref=$obj->invoice_source_ref; $facturefournstatic->type=$obj->type; print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).' '.$facturefournstatic->getNomURl(1); print ''; $facturefournstatic->id=$obj->fk_invoice_supplier_source; - $facturefournstatic->ref=$obj->ref; + $facturefournstatic->ref=$obj->invoice_source_ref; $facturefournstatic->type=$obj->type; print preg_replace('/\(EXCESS PAID\)/', $langs->trans("Invoice"), $obj->description).' '.$facturefournstatic->getNomURl(1); print ''.img_object($langs->trans("ShowBill"), 'bill').' '.$obj->ref.''; + if ($obj->invoiceid) { + print ''.img_object($langs->trans("ShowBill"), 'bill').' '.$obj->ref.''; + } + print ''.price($obj->amount_ht).'
'; print ''; print ''; - print ''; + print ''; print ''; print ''; print '
'.$langs->trans("Label").'
'.$langs->trans("Email").'
'.$langs->trans("Signature").'
'.$langs->trans("Signature").''; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor = new DolEditor('signature', GETPOST('signature'), '', 138, 'dolibarr_notes', 'In', true, true, empty($conf->global->FCKEDITOR_ENABLE_USERSIGN) ? 0 : 1, ROWS_4, '90%'); + print $doleditor->Create(1); + print '
'.$langs->trans("Position").'
'.$langs->trans("Status").''; - print ''; + print $form->selectyesno('active', GETPOST('active', 'int'), 1); print '
'; print '
'; diff --git a/htdocs/core/class/emailsenderprofile.class.php b/htdocs/core/class/emailsenderprofile.class.php index b65d72332e0..41a0d485ce0 100644 --- a/htdocs/core/class/emailsenderprofile.class.php +++ b/htdocs/core/class/emailsenderprofile.class.php @@ -56,19 +56,28 @@ class EmailSenderProfile extends CommonObject public $picto = 'emailsenderprofile@monmodule'; + const STATUS_DISABLED = 0; + const STATUS_ENABLED = 1; + + /** - * 'type' if the field format. - * 'label' the translation key. - * 'enabled' is a condition when the filed must be managed. - * 'visible' says if field is visible in list (-1 means not shown by default but can be added into list to be viewed). - * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). - * 'index' if we want an index in database. - * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). - * 'position' is the sort order of field. - * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. - * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). - * 'help' is a string visible as a tooltip on field - * 'comment' is not used. You can store here any text of your choice. + * 'type' if the field format ('integer', 'integer:Class:pathtoclass', 'varchar(x)', 'double(24,8)', 'text', 'html', 'datetime', 'timestamp', 'float') + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed. + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'default' is a default value for creation (can still be replaced by the global setup of default values) + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'position' is the sort order of field. + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") */ // BEGIN MODULEBUILDER PROPERTIES @@ -78,7 +87,7 @@ class EmailSenderProfile extends CommonObject public $fields=array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>-1, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>'Id',), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'visible'=>-1, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>1), 'email' => array('type'=>'varchar(255)', 'label'=>'Email', 'visible'=>1, 'enabled'=>1, 'position'=>40, 'notnull'=>-1), //'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>1,), //'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>-1,), @@ -86,7 +95,7 @@ class EmailSenderProfile extends CommonObject 'position' => array('type'=>'integer', 'label'=>'Position', 'visible'=>1, 'enabled'=>1, 'position'=>405, 'notnull'=>-1, 'index'=>1,), 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>1,), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>1,), - 'active' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1), + 'active' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'default'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1), ); /** diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index 90e3b03319c..96ac938883c 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -59,6 +59,7 @@ ALTER TABLE llx_emailcollector_emailcollectoraction ADD COLUMN position integer -- For v11 +ALTER TABLE llx_c_email_senderprofile MODIFY COLUMN active tinyint DEFAULT 1 NOT NULL; insert into llx_c_type_container (code,label,module,active) values ('menu', 'Menu', 'system', 1); diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index d704ce13cbf..d25c106bf39 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -972,6 +972,9 @@ select.flat.selectlimit { -ms-overflow-style: -ms-autohiding-scrollbar; }*/ /* Style used for most tables */ +div.fiche>div.tabBar>form>div.div-table-responsive { + min-height: 392px; +} .div-table-responsive, .div-table-responsive-no-min { overflow-x: auto; min-height: 0.01%; From 1ed2eacbef482604cd2f120b21a84a854c366a2a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 22 Nov 2019 12:40:17 +0100 Subject: [PATCH 59/84] Debug add email profile --- htdocs/admin/mails_senderprofile_list.php | 7 ++++--- htdocs/core/actions_addupdatedelete.inc.php | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index a22c9d79ac5..e287db9c7c9 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -358,7 +358,7 @@ $newcardbutton = ''; if ($action != 'create') { $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', $_SERVER['PHP_SELF'].'?action=create', '', $permissiontoadd); } else { - print ''; + /*print ''; if ($optioncss != '') print ''; print ''; print ''; @@ -366,6 +366,7 @@ if ($action != 'create') { print ''; print ''; print ''; + */ print ''; print ''; print ''; @@ -374,7 +375,7 @@ if ($action != 'create') { $doleditor = new DolEditor('signature', GETPOST('signature'), '', 138, 'dolibarr_notes', 'In', true, true, empty($conf->global->FCKEDITOR_ENABLE_USERSIGN) ? 0 : 1, ROWS_4, '90%'); print $doleditor->Create(1); print ''; - print ''; + print ''; print ''; @@ -385,7 +386,7 @@ if ($action != 'create') { print '   '; print ''; print ''; - print ''; + //print ''; } print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_companies', 0, $newcardbutton, '', $limit); diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index ee4208cd65e..0d718c2abc2 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -75,6 +75,7 @@ if ($action == 'add' && !empty($permissiontoadd)) if (preg_match('/^integer:/i', $object->fields[$key]['type']) && $value == '-1') $value = ''; // This is an implicit foreign key field if (!empty($object->fields[$key]['foreignkey']) && $value == '-1') $value = ''; // This is an explicit foreign key field + //var_dump($key.' '.$value.' '.$object->fields[$key]['type']); $object->$key = $value; if ($val['notnull'] > 0 && $object->$key == '' && !is_null($val['default']) && $val['default'] == '(PROV)') { From 00ad95c01e671abc6e87d1c088c2fa4e89342df0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 22 Nov 2019 14:06:43 +0100 Subject: [PATCH 60/84] Figth against useless dependencies: Remove library the core never use. --- htdocs/core/class/html.form.class.php | 1 + .../multiselect/jquery.multi-select.js | 360 ------------------ .../multiselect/jquery.multi-select.min.js | 9 - htdocs/main.inc.php | 4 - 4 files changed, 1 insertion(+), 373 deletions(-) delete mode 100644 htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.js delete mode 100644 htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.min.js diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index cac859c53b5..d70993be51d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6521,6 +6521,7 @@ class Form elseif ($addjscombo == 2) { // Add other js lib + // TODO external lib multiselect/jquery.multi-select.js must have been loaded to use this multiselect plugin // ... $out .= '$(document).ready(function () { $(\'#'.$htmlname.'\').multiSelect({ diff --git a/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.js b/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.js deleted file mode 100644 index ee62d1f588d..00000000000 --- a/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.js +++ /dev/null @@ -1,360 +0,0 @@ -// jquery.multi-select.js -// by mySociety -// https://github.com/mysociety/jquery-multi-select - -;(function($) { - - "use strict"; - - var pluginName = "multiSelect", - defaults = { - 'containerHTML': '
', - 'menuHTML': '
', - 'buttonHTML': '', - 'menuItemsHTML': '
', - 'menuItemHTML': '
'; print ''. ''. ''. ''. ''; // Company - $href = DOL_URL_ROOT . '/fourn/card.php?socid=' . $obj->socid; + $href = DOL_URL_ROOT.'/fourn/card.php?socid='.$obj->socid; print ''; + ''. + img_object($langs->trans('ShowCompany'), 'company').' '. + $obj->name.''; // Author $userstatic->id = $obj->fk_user_author; @@ -288,7 +288,7 @@ if ($resql) if ($userstatic->id) { $txt = $userstatic->getLoginUrl(1); } else { - $txt = ' '; + $txt = ' '; } print ''; // Amount @@ -296,9 +296,9 @@ if ($resql) // Date if ($obj->dc) { - $date = dol_print_date($db->jdate($obj->dc), 'dayhour'); + $date = dol_print_date($db->jdate($obj->dc), 'dayhour'); } else { - $date = '-'; + $date = '-'; } print ''; // Statut diff --git a/htdocs/product/stock/valo.php b/htdocs/product/stock/valo.php index e814bdfaac0..816d97351b4 100644 --- a/htdocs/product/stock/valo.php +++ b/htdocs/product/stock/valo.php @@ -30,19 +30,19 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; $langs->load("stocks"); // Security check -$result=restrictedArea($user, 'stock'); +$result = restrictedArea($user, 'stock'); -$sref=GETPOST("sref", 'alpha'); -$snom=GETPOST("snom", 'alpha'); -$sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); +$sref = GETPOST("sref", 'alpha'); +$snom = GETPOST("snom", 'alpha'); +$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); -if (! $sortfield) $sortfield="e.ref"; -if (! $sortorder) $sortorder="ASC"; +if (!$sortfield) $sortfield = "e.ref"; +if (!$sortorder) $sortorder = "ASC"; $page = $_GET["page"]; if ($page < 0) $page = 0; -$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $offset = $limit * $page; $year = strftime("%Y", time()); @@ -53,23 +53,23 @@ $year = strftime("%Y", time()); */ $sql = "SELECT e.rowid, e.ref, e.statut, e.lieu, e.address, e.zip, e.town, e.fk_pays,"; -$sql.= " SUM(ps.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue"; -$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps ON e.rowid = ps.fk_entrepot"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; -$sql.= " WHERE e.entity IN (".getEntity('stock').")"; -if ($sref) $sql.= natural_search("e.ref", $sref); +$sql .= " SUM(ps.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue"; +$sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps ON e.rowid = ps.fk_entrepot"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; +$sql .= " WHERE e.entity IN (".getEntity('stock').")"; +if ($sref) $sql .= natural_search("e.ref", $sref); if ($sall) { - $sql.= " AND (e.ref LIKE '%".$db->escape($sall)."%'"; - $sql.= " OR e.description LIKE '%".$db->escape($sall)."%'"; - $sql.= " OR e.lieu LIKE '%".$db->escape($sall)."%'"; - $sql.= " OR e.address LIKE '%".$db->escape($sall)."%'"; - $sql.= " OR e.town LIKE '%".$db->escape($sall)."%')"; + $sql .= " AND (e.ref LIKE '%".$db->escape($sall)."%'"; + $sql .= " OR e.description LIKE '%".$db->escape($sall)."%'"; + $sql .= " OR e.lieu LIKE '%".$db->escape($sall)."%'"; + $sql .= " OR e.address LIKE '%".$db->escape($sall)."%'"; + $sql .= " OR e.town LIKE '%".$db->escape($sall)."%')"; } -$sql.= " GROUP BY e.rowid, e.ref, e.statut, e.lieu, e.address, e.zip, e.town, e.fk_pays"; -$sql.= $db->order($sortfield, $sortorder); -$sql.= $db->plimit($limit + 1, $offset); +$sql .= " GROUP BY e.rowid, e.ref, e.statut, e.lieu, e.address, e.zip, e.town, e.fk_pays"; +$sql .= $db->order($sortfield, $sortorder); +$sql .= $db->plimit($limit + 1, $offset); $result = $db->query($sql); if ($result) @@ -78,7 +78,7 @@ if ($result) $i = 0; - $help_url='EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; + $help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; llxHeader("", $langs->trans("EnhancedValueOfWarehouses"), $help_url); print_barre_liste($langs->trans("EnhancedValueOfWarehouses"), $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, '', $num); @@ -94,9 +94,9 @@ if ($result) if ($num) { - $entrepot=new Entrepot($db); + $entrepot = new Entrepot($db); $total = $totalsell = 0; - $var=false; + $var = false; while ($i < min($num, $limit)) { $objp = $db->fetch_object($result); @@ -136,17 +136,17 @@ if ($result) print '
'; - $file='entrepot-'.$year.'.png'; + $file = 'entrepot-'.$year.'.png'; if (file_exists($conf->stock->dir_temp.'/'.$file)) { - $url=DOL_URL_ROOT.'/viewimage.php?modulepart=graph_stock&file='.$file; + $url = DOL_URL_ROOT.'/viewimage.php?modulepart=graph_stock&file='.$file; print ''; } - $file='entrepot-'.($year-1).'.png'; + $file = 'entrepot-'.($year - 1).'.png'; if (file_exists($conf->stock->dir_temp.'/'.$file)) { - $url=DOL_URL_ROOT.'/viewimage.php?modulepart=graph_stock&file='.$file; + $url = DOL_URL_ROOT.'/viewimage.php?modulepart=graph_stock&file='.$file; print '
'; } } diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index c28460e1045..ddb7673dece 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -36,34 +36,34 @@ $ref = GETPOST('ref', 'alpha'); $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); -$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", "alpha"); $sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOST("page", 'int'); $page = is_numeric($page) ? $page : 0; $page = $page == -1 ? 0 : $page; -if (! $sortfield) $sortfield="a.datep,a.id"; -if (! $sortorder) $sortorder="DESC"; -$offset = $limit * $page ; +if (!$sortfield) $sortfield = "a.datep,a.id"; +if (!$sortorder) $sortorder = "DESC"; +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (GETPOST('actioncode', 'array')) { - $actioncode=GETPOST('actioncode', 'array', 3); - if (! count($actioncode)) $actioncode='0'; + $actioncode = GETPOST('actioncode', 'array', 3); + if (!count($actioncode)) $actioncode = '0'; } else { - $actioncode=GETPOST("actioncode", "alpha", 3)?GETPOST("actioncode", "alpha", 3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); + $actioncode = GETPOST("actioncode", "alpha", 3) ?GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); } -$search_agenda_label=GETPOST('search_agenda_label'); +$search_agenda_label = GETPOST('search_agenda_label'); // Security check $id = GETPOST("id", 'int'); -$socid=0; +$socid = 0; //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. -$result=restrictedArea($user, 'projet', $id, ''); +$result = restrictedArea($user, 'projet', $id, ''); if (!$user->rights->projet->lire) accessforbidden(); @@ -149,20 +149,20 @@ dol_fiche_end(); // Actions buttons -$out=''; -$permok=$user->rights->agenda->myactions->create; +$out = ''; +$permok = $user->rights->agenda->myactions->create; if ($permok) { - $out.='&projectid='.$object->id; + $out .= '&projectid='.$object->id; } //print '
'; -$morehtmlcenter=''; -if (! empty($conf->agenda->enabled)) +$morehtmlcenter = ''; +if (!empty($conf->agenda->enabled)) { - $addActionBtnRight = ! empty($user->rights->agenda->myactions->create) || ! empty($user->rights->agenda->allactions->create); - $morehtmlcenter.= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $addActionBtnRight); + $addActionBtnRight = !empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create); + $morehtmlcenter .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $addActionBtnRight); } //print '
'; diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index e1bf458b6e4..d0f85eb9fe2 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -50,56 +50,56 @@ $extrafields = new ExtraFields($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); -$search_array_options=$extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); -if (! is_array($search_array_options)) $search_array_options = array(); -$search_ref=GETPOST("search_ref"); -$search_type=GETPOST("search_type"); +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); +if (!is_array($search_array_options)) $search_array_options = array(); +$search_ref = GETPOST("search_ref"); +$search_type = GETPOST("search_type"); -$filter=array(); +$filter = array(); -if ($search_ref != ''){ - $param.='&search_ref='.$search_ref; - $filter['t.ref']=$search_ref; +if ($search_ref != '') { + $param .= '&search_ref='.$search_ref; + $filter['t.ref'] = $search_ref; } -if ($search_type != ''){ - $param.='&search_type='.$search_type; - $filter['ty.label']=$search_type; +if ($search_type != '') { + $param .= '&search_type='.$search_type; + $filter['ty.label'] = $search_type; } -if ($search_label != '') $param.='&search_label='.$search_label; +if ($search_label != '') $param .= '&search_label='.$search_label; // Add $param from extra fields foreach ($search_array_options as $key => $val) { - $crit=$val; - $tmpkey=preg_replace('/search_options_/', '', $key); - $typ=$extrafields->attributes[$object->table_element]['type'][$tmpkey]; + $crit = $val; + $tmpkey = preg_replace('/search_options_/', '', $key); + $typ = $extrafields->attributes[$object->table_element]['type'][$tmpkey]; if ($val != '') { - $param.='&search_options_'.$tmpkey.'='.urlencode($val); + $param .= '&search_options_'.$tmpkey.'='.urlencode($val); } - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) + $mode_search = 0; + if (in_array($typ, array('int', 'double', 'real'))) $mode_search = 1; // Search on a numeric + if (in_array($typ, array('sellist', 'link')) && $crit != '0' && $crit != '-1') $mode_search = 2; // Search on a foreign key int + if ($crit != '' && (!in_array($typ, array('select', 'sellist')) || $crit != '0') && (!in_array($typ, array('link')) || $crit != '-1')) { $filter['ef.'.$tmpkey] = natural_search('ef.'.$tmpkey, $crit, $mode_search); } } -if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.$contextpage; $hookmanager->initHooks(array('resourcelist')); -if (empty($sortorder)) $sortorder="ASC"; -if (empty($sortfield)) $sortfield="t.ref"; +if (empty($sortorder)) $sortorder = "ASC"; +if (empty($sortfield)) $sortfield = "t.ref"; if (empty($arch)) $arch = 0; -$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $page = GETPOST("page", 'int'); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$offset = $limit * $page ; +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if( ! $user->rights->resource->read) { +if (!$user->rights->resource->read) { accessforbidden(); } $arrayfields = array( @@ -115,10 +115,10 @@ $arrayfields = array( // Extra fields if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { - foreach($extrafields->attributes[$object->table_element]['label'] as $key => $val) + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (! empty($extrafields->attributes[$object->table_element]['list'][$key])) - $arrayfields["ef.".$key]=array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key]<0)?0:1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key])!=3 && $extrafields->attributes[$object->table_element]['perms'][$key])); + if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) + $arrayfields["ef.".$key] = array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key])); } } $object->fields = dol_sort_array($object->fields, 'position'); From e36ee63ab60337c162fbb0570e2ba20c204df16c Mon Sep 17 00:00:00 2001 From: Scrutinizer Auto-Fixer Date: Fri, 22 Nov 2019 13:16:38 +0000 Subject: [PATCH 64/84] Scrutinizer Auto-Fixes This commit consists of patches automatically generated for this project on https://scrutinizer-ci.com --- htdocs/commande/tpl/linkedobjectblock.tpl.php | 16 +- htdocs/compta/facture/card.php | 2 +- .../expedition/tpl/linkedobjectblock.tpl.php | 16 +- htdocs/main.inc.php | 848 +++++++++--------- htdocs/theme/eldy/style.css.php | 212 ++--- htdocs/theme/md/theme_vars.inc.php | 96 +- htdocs/ticket/tpl/linkedobjectblock.tpl.php | 18 +- htdocs/user/document.php | 66 +- 8 files changed, 637 insertions(+), 637 deletions(-) diff --git a/htdocs/commande/tpl/linkedobjectblock.tpl.php b/htdocs/commande/tpl/linkedobjectblock.tpl.php index 1b69e035fba..a593e10adf4 100644 --- a/htdocs/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/commande/tpl/linkedobjectblock.tpl.php @@ -18,7 +18,7 @@ */ // Protection to avoid direct call of template -if (empty($conf) || ! is_object($conf)) { +if (empty($conf) || !is_object($conf)) { print "Error, template page can't be called as URL"; exit; } @@ -36,14 +36,14 @@ $langs->load("orders"); $linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); -$total=0; -$ilink=0; -foreach($linkedObjectBlock as $key => $objectlink) +$total = 0; +$ilink = 0; +foreach ($linkedObjectBlock as $key => $objectlink) { $ilink++; - $trclass='oddeven'; - if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass.=' liste_sub_total'; + $trclass = 'oddeven'; + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass .= ' liste_sub_total'; echo ''; echo ''; echo ''; echo "\n"; } if (count($linkedObjectBlock) > 1) { - echo ''; + echo ''; echo ''; echo ''; echo ''; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 0d39cda6513..f0854eabde2 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1216,7 +1216,7 @@ if (empty($reshook)) // Si facture standard $object->socid = GETPOST('socid', 'int'); $object->type = GETPOST('type'); - $object->ref = $_POST['ref']; + $object->ref = $_POST['ref']; $object->date = $dateinvoice; $object->date_pointoftax = $date_pointoftax; $object->note_public = trim(GETPOST('note_public', 'none')); diff --git a/htdocs/expedition/tpl/linkedobjectblock.tpl.php b/htdocs/expedition/tpl/linkedobjectblock.tpl.php index 1cc0e30934d..fbc1763beb3 100644 --- a/htdocs/expedition/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expedition/tpl/linkedobjectblock.tpl.php @@ -17,7 +17,7 @@ */ // Protection to avoid direct call of template -if (empty($conf) || ! is_object($conf)) +if (empty($conf) || !is_object($conf)) { print "Error, template page can't be called as URL"; exit; @@ -35,14 +35,14 @@ $linkedObjectBlock = $GLOBALS['linkedObjectBlock']; // Load translation files required by the page $langs->load("sendings"); -$total=0; -$ilink=0; -foreach($linkedObjectBlock as $key => $objectlink) +$total = 0; +$ilink = 0; +foreach ($linkedObjectBlock as $key => $objectlink) { $ilink++; - $trclass='oddeven'; - if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass.=' liste_sub_total'; + $trclass = 'oddeven'; + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass .= ' liste_sub_total'; ?> @@ -58,7 +58,7 @@ foreach($linkedObjectBlock as $key => $objectlink) $objectlink) } if (count($linkedObjectBlock) > 1) { ?> - + diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 2fe3dbc140a..6b17bb6f947 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -89,28 +89,28 @@ function testSqlAndScriptInject($val, $type) $inj += preg_match('/'."\n"; + print ''."\n"; } } // Global js function print ''."\n"; - print ''."\n"; + print ''."\n"; // JS forced by modules (relative url starting with /) - if (! empty($conf->modules_parts['js'])) // $conf->modules_parts['js'] is array('module'=>array('file1','file2')) + if (!empty($conf->modules_parts['js'])) // $conf->modules_parts['js'] is array('module'=>array('file1','file2')) { - $arrayjs=(array) $conf->modules_parts['js']; - foreach($arrayjs as $modjs => $filesjs) + $arrayjs = (array) $conf->modules_parts['js']; + foreach ($arrayjs as $modjs => $filesjs) { - $filesjs=(array) $filesjs; // To be sure filejs is an array - foreach($filesjs as $jsfile) + $filesjs = (array) $filesjs; // To be sure filejs is an array + foreach ($filesjs as $jsfile) { // jsfile is a relative path - print ''."\n".''."\n"; + print ''."\n".''."\n"; } } } @@ -1613,15 +1613,15 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead // Add login user link - $toprightmenu.=''."\n"; - $toprightmenu.=''; print $toprightmenu; - print "\n"; // end div class="login_block" + print "\n"; // end div class="login_block" print ''; @@ -1752,94 +1752,94 @@ function top_menu_user() global $menumanager; $userImage = $userDropDownImage = ''; - if (! empty($user->photo)) + if (!empty($user->photo)) { $userImage = Form::showphoto('userphoto', $user, 0, 0, 0, 'photouserphoto userphoto', 'small', 0, 1); $userDropDownImage = Form::showphoto('userphoto', $user, 0, 0, 0, 'dropdown-user-image', 'small', 0, 1); } else { - $nophoto='/public/theme/common/user_anonymous.png'; - if ($user->gender == 'man') $nophoto='/public/theme/common/user_man.png'; - if ($user->gender == 'woman') $nophoto='/public/theme/common/user_woman.png'; + $nophoto = '/public/theme/common/user_anonymous.png'; + if ($user->gender == 'man') $nophoto = '/public/theme/common/user_man.png'; + if ($user->gender == 'woman') $nophoto = '/public/theme/common/user_woman.png'; $userImage = 'No photo'; $userDropDownImage = 'No photo'; } $dropdownBody = ''; - $dropdownBody.= ' '.$langs->trans("ShowMoreInfos").''; - $dropdownBody.= '
'; + $dropdownBody .= ' '.$langs->trans("ShowMoreInfos").''; + $dropdownBody .= '
'; // login infos - if (! empty($user->admin)) { - $dropdownBody.= '
' . $langs->trans("Administrator").': '.yn($user->admin); + if (!empty($user->admin)) { + $dropdownBody .= '
'.$langs->trans("Administrator").': '.yn($user->admin); } - if (! empty($user->socid)) // Add thirdparty for external users + if (!empty($user->socid)) // Add thirdparty for external users { $thirdpartystatic = new Societe($db); $thirdpartystatic->fetch($user->socid); - $companylink = ' '.$thirdpartystatic->getNomUrl(2); // picto only of company - $company=' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')'; + $companylink = ' '.$thirdpartystatic->getNomUrl(2); // picto only of company + $company = ' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')'; } - $type=($user->socid?$langs->trans("External").$company:$langs->trans("Internal")); - $dropdownBody.= '
' . $langs->trans("Type") . ': ' . $type; - $dropdownBody.= '
' . $langs->trans("Status").': '.$user->getLibStatut(0); - $dropdownBody.= '
'; + $type = ($user->socid ? $langs->trans("External").$company : $langs->trans("Internal")); + $dropdownBody .= '
'.$langs->trans("Type").': '.$type; + $dropdownBody .= '
'.$langs->trans("Status").': '.$user->getLibStatut(0); + $dropdownBody .= '
'; - $dropdownBody.= '
'.$langs->trans("Session").''; - $dropdownBody.= '
'.$langs->trans("IPAddress").': '.dol_escape_htmltag($_SERVER["REMOTE_ADDR"]); - if (! empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $dropdownBody.= '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (user entity '.$user->entity.')'; - $dropdownBody.= '
'.$langs->trans("AuthenticationMode").': '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo)?'':' (demo)'); - $dropdownBody.= '
'.$langs->trans("ConnectedSince").': '.dol_print_date($user->datelastlogin, "dayhour", 'tzuser'); - $dropdownBody.= '
'.$langs->trans("PreviousConnexion").': '.dol_print_date($user->datepreviouslogin, "dayhour", 'tzuser'); - $dropdownBody.= '
'.$langs->trans("CurrentTheme").': '.$conf->theme; - $dropdownBody.= '
'.$langs->trans("CurrentMenuManager").': '.$menumanager->name; - $langFlag=picto_from_langcode($langs->getDefaultLang()); - $dropdownBody.= '
'.$langs->trans("CurrentUserLanguage").': '.($langFlag?$langFlag.' ':'').$langs->getDefaultLang(); - $dropdownBody.= '
'.$langs->trans("Browser").': '.$conf->browser->name.($conf->browser->version?' '.$conf->browser->version:'').' ('.dol_escape_htmltag($_SERVER['HTTP_USER_AGENT']).')'; - $dropdownBody.= '
'.$langs->trans("Layout").': '.$conf->browser->layout; - $dropdownBody.= '
'.$langs->trans("Screen").': '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']; - if ($conf->browser->layout == 'phone') $dropdownBody.= '
'.$langs->trans("Phone").': '.$langs->trans("Yes"); - if (! empty($_SESSION["disablemodules"])) $dropdownBody.= '
'.$langs->trans("DisabledModules").':
'.join(', ', explode(',', $_SESSION["disablemodules"])); - $dropdownBody.= '
'; + $dropdownBody .= '
'.$langs->trans("Session").''; + $dropdownBody .= '
'.$langs->trans("IPAddress").': '.dol_escape_htmltag($_SERVER["REMOTE_ADDR"]); + if (!empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $dropdownBody .= '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (user entity '.$user->entity.')'; + $dropdownBody .= '
'.$langs->trans("AuthenticationMode").': '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)'); + $dropdownBody .= '
'.$langs->trans("ConnectedSince").': '.dol_print_date($user->datelastlogin, "dayhour", 'tzuser'); + $dropdownBody .= '
'.$langs->trans("PreviousConnexion").': '.dol_print_date($user->datepreviouslogin, "dayhour", 'tzuser'); + $dropdownBody .= '
'.$langs->trans("CurrentTheme").': '.$conf->theme; + $dropdownBody .= '
'.$langs->trans("CurrentMenuManager").': '.$menumanager->name; + $langFlag = picto_from_langcode($langs->getDefaultLang()); + $dropdownBody .= '
'.$langs->trans("CurrentUserLanguage").': '.($langFlag ? $langFlag.' ' : '').$langs->getDefaultLang(); + $dropdownBody .= '
'.$langs->trans("Browser").': '.$conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.dol_escape_htmltag($_SERVER['HTTP_USER_AGENT']).')'; + $dropdownBody .= '
'.$langs->trans("Layout").': '.$conf->browser->layout; + $dropdownBody .= '
'.$langs->trans("Screen").': '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']; + if ($conf->browser->layout == 'phone') $dropdownBody .= '
'.$langs->trans("Phone").': '.$langs->trans("Yes"); + if (!empty($_SESSION["disablemodules"])) $dropdownBody .= '
'.$langs->trans("DisabledModules").':
'.join(', ', explode(',', $_SESSION["disablemodules"])); + $dropdownBody .= '
'; // Execute hook - $parameters=array('user'=>$user, 'langs' => $langs); - $result=$hookmanager->executeHooks('printTopRightMenuLoginDropdownBody', $parameters); // Note that $action and $object may have been modified by some hooks + $parameters = array('user'=>$user, 'langs' => $langs); + $result = $hookmanager->executeHooks('printTopRightMenuLoginDropdownBody', $parameters); // Note that $action and $object may have been modified by some hooks if (is_numeric($result)) { - if ($result == 0){ - $dropdownBody.= $hookmanager->resPrint; // add + if ($result == 0) { + $dropdownBody .= $hookmanager->resPrint; // add } - else{ - $dropdownBody = $hookmanager->resPrint; // replace + else { + $dropdownBody = $hookmanager->resPrint; // replace } } - $logoutLink =' '.$langs->trans("Logout").''; - $profilLink =' '.$langs->trans("Card").''; + $logoutLink = ' '.$langs->trans("Logout").''; + $profilLink = ' '.$langs->trans("Card").''; $profilName = $user->getFullName($langs).' ('.$user->login.')'; - if (! empty($user->admin)) { + if (!empty($user->admin)) { $profilName = ' '.$profilName; } // Define version to show - $appli=constant('DOL_APPLICATION_TITLE'); - if (! empty($conf->global->MAIN_APPLICATION_TITLE)) + $appli = constant('DOL_APPLICATION_TITLE'); + if (!empty($conf->global->MAIN_APPLICATION_TITLE)) { - $appli=$conf->global->MAIN_APPLICATION_TITLE; + $appli = $conf->global->MAIN_APPLICATION_TITLE; if (preg_match('/\d\.\d/', $appli)) { - if (! preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli.=" (".DOL_VERSION.")"; // If new title contains a version that is different than core + if (!preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli .= " (".DOL_VERSION.")"; // If new title contains a version that is different than core } - else $appli.=" ".DOL_VERSION; + else $appli .= " ".DOL_VERSION; } - else $appli.=" ".DOL_VERSION; + else $appli .= " ".DOL_VERSION; $btnUser = ''; - if (! defined('JS_JQUERY_DISABLE_DROPDOWN')) // This may be set by some pages that use different jquery version to avoid errors + if (!defined('JS_JQUERY_DISABLE_DROPDOWN')) // This may be set by some pages that use different jquery version to avoid errors { $btnUser .= ' @@ -1919,12 +1919,12 @@ function top_menu_bookmark() $html = ''; // Define $bookmarks - if (! empty($conf->bookmark->enabled) && $user->rights->bookmark->lire) + if (!empty($conf->bookmark->enabled) && $user->rights->bookmark->lire) { include_once DOL_DOCUMENT_ROOT.'/bookmarks/bookmarks.lib.php'; $langs->load("bookmarks"); - $html.= ' + $html .= '
'.$langs->trans("Label").'
'.$langs->trans("Email").'
'.$langs->trans("Position").'
'.$langs->trans("Position").'
'.$langs->trans("Status").''; print $form->selectyesno('active', GETPOST('active', 'int'), 1); print '
'. - ''. + ''. ''. - ''. + ''. ''. - ''. + ''. ''. - ''. + ''. ''. $form->selectDate($search_date, 'search_date', 0, 0, 1, '', 1, 0, 0, ''). @@ -260,7 +260,7 @@ if ($resql) $userstatic = new User($db); - while ($i < min($num, $sproduct?$num:$conf->liste_limit)) + while ($i < min($num, $sproduct ? $num : $conf->liste_limit)) { $obj = $db->fetch_object($resql); @@ -276,11 +276,11 @@ if ($resql) print ''. - ''. - img_object($langs->trans('ShowCompany'), 'company'). ' '. - $obj->name . ''.$txt.''.$date.'
'.$langs->trans("CustomerOrder"); if (!empty($showImportButton) && $conf->global->MAIN_ENABLE_IMPORT_LINKED_OBJECT_LINES) { @@ -62,14 +62,14 @@ foreach($linkedObjectBlock as $key => $objectlink) echo ''.$objectlink->getLibStatut(3).''; // For now, shipments must stay linked to order, so link is not deletable - if($object->element != 'shipping') { + if ($object->element != 'shipping') { echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; } echo '
'.$langs->trans("Total").'
trans("Shipment"); ?> element != 'commande') { + if ($object->element != 'commande') { ?> ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?>
trans("Total"); ?>