';
// Model
if (! empty($modellist))
From 414bac6fb48e394cb35555a30c9e590c4d05acc2 Mon Sep 17 00:00:00 2001
From: Christophe Battarel
Date: Wed, 6 Mar 2019 17:56:43 +0100
Subject: [PATCH 19/42] avoid logging empty query
---
htdocs/core/db/mysqli.class.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php
index 6c3bfd2362f..1b040ddfa18 100644
--- a/htdocs/core/db/mysqli.class.php
+++ b/htdocs/core/db/mysqli.class.php
@@ -256,6 +256,8 @@ class DoliDBMysqli extends DoliDB
$query = trim($query);
+ if (empty($query)) return null;
+
if (! in_array($query, array('BEGIN','COMMIT','ROLLBACK'))) dol_syslog('sql='.$query, LOG_DEBUG);
if (! $this->database_name)
From 8743b43fdbcc3c3433ede604318e007f6f4cc063 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:01:18 +0100
Subject: [PATCH 20/42] add oldcopy of category before updating
---
htdocs/categories/edit.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/htdocs/categories/edit.php b/htdocs/categories/edit.php
index a85c320a992..9416ddae748 100644
--- a/htdocs/categories/edit.php
+++ b/htdocs/categories/edit.php
@@ -81,6 +81,7 @@ if ($cancel)
// Action mise a jour d'une categorie
if ($action == 'update' && $user->rights->categorie->creer)
{
+ $object->oldcopy = dol_clone($object);
$object->label = $label;
$object->description = dol_htmlcleanlastbr($description);
$object->color = $color;
From 401ad659758df2cc1f236251cae5ae64ba3e2ec7 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Wed, 6 Mar 2019 18:04:36 +0100
Subject: [PATCH 21/42] Fix API explorer was broken due to corrupted API
---
.../{api_bom.class.php => api_boms.class.php} | 77 +++++++++----------
htdocs/commande/class/api_orders.class.php | 6 +-
.../template/class/api_mymodule.class.php | 30 ++++----
3 files changed, 55 insertions(+), 58 deletions(-)
rename htdocs/bom/class/{api_bom.class.php => api_boms.class.php} (84%)
diff --git a/htdocs/bom/class/api_bom.class.php b/htdocs/bom/class/api_boms.class.php
similarity index 84%
rename from htdocs/bom/class/api_bom.class.php
rename to htdocs/bom/class/api_boms.class.php
index 4d13475be1a..adda9ceb238 100644
--- a/htdocs/bom/class/api_bom.class.php
+++ b/htdocs/bom/class/api_boms.class.php
@@ -18,12 +18,11 @@
use Luracast\Restler\RestException;
-dol_include_once('/bom/class/bom.class.php');
-
+require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
/**
- * \file bom/class/api_bom.class.php
+ * \file bom/class/api_boms.class.php
* \ingroup bom
* \brief File for API management of bom.
*/
@@ -31,36 +30,32 @@ dol_include_once('/bom/class/bom.class.php');
/**
* API class for bom bom
*
- * @smart-auto-routing false
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
-class BillOfMaterialsApi extends DolibarrApi
+class BOMs extends DolibarrApi
{
/**
* @var array $FIELDS Mandatory fields, checked when create and update object
*/
static $FIELDS = array(
- 'name',
+ 'label'
);
/**
- * @var BillOfMaterials $bom {@type BillOfMaterials}
+ * @var BOM $bom {@type BOM}
*/
public $bom;
/**
* Constructor
- *
- * @url GET /
- *
*/
public function __construct()
{
global $db, $conf;
$this->db = $db;
- $this->bom = new BillOfMaterials($this->db);
+ $this->bom = new BOM($this->db);
}
/**
@@ -71,7 +66,7 @@ class BillOfMaterialsApi extends DolibarrApi
* @param int $id ID of bom
* @return array|mixed data without useless information
*
- * @url GET boms/{id}
+ * @url GET {id}
* @throws RestException
*/
public function get($id)
@@ -82,7 +77,7 @@ class BillOfMaterialsApi extends DolibarrApi
$result = $this->bom->fetch($id);
if( ! $result ) {
- throw new RestException(404, 'BillOfMaterials not found');
+ throw new RestException(404, 'BOM not found');
}
if( ! DolibarrApi::_checkAccessToResource('bom', $this->bom->id)) {
@@ -106,8 +101,6 @@ class BillOfMaterialsApi extends DolibarrApi
* @return array Array of order objects
*
* @throws RestException
- *
- * @url GET /boms/
*/
public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
{
@@ -134,7 +127,7 @@ class BillOfMaterialsApi extends DolibarrApi
//if ($mode == 1) $sql.= " AND s.client IN (1, 3)";
//if ($mode == 2) $sql.= " AND s.client IN (2, 3)";
- $tmpobject = new BillOfMaterials($db);
+ $tmpobject = new BOM($db);
if ($tmpobject->ismultientitymanaged) $sql.= ' AND t.entity IN ('.getEntity('bom').')';
if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
if ($restictonsocid && $socid) $sql.= " AND t.fk_soc = ".$socid;
@@ -172,7 +165,7 @@ class BillOfMaterialsApi extends DolibarrApi
while ($i < $num)
{
$obj = $db->fetch_object($result);
- $bom_static = new BillOfMaterials($db);
+ $bom_static = new BOM($db);
if($bom_static->fetch($obj->rowid)) {
$obj_ret[] = $this->_cleanObjectDatas($bom_static);
}
@@ -193,8 +186,6 @@ class BillOfMaterialsApi extends DolibarrApi
*
* @param array $request_data Request datas
* @return int ID of bom
- *
- * @url POST boms/
*/
public function post($request_data = null)
{
@@ -208,7 +199,7 @@ class BillOfMaterialsApi extends DolibarrApi
$this->bom->$field = $value;
}
if( ! $this->bom->create(DolibarrApiAccess::$user)) {
- throw new RestException(500);
+ throw new RestException(500, "Error creating BOM", array_merge(array($this->bom->error), $this->bom->errors));
}
return $this->bom->id;
}
@@ -218,9 +209,8 @@ class BillOfMaterialsApi extends DolibarrApi
*
* @param int $id Id of bom to update
* @param array $request_data Datas
- * @return int
*
- * @url PUT boms/{id}
+ * @return int
*/
public function put($id, $request_data = null)
{
@@ -230,7 +220,7 @@ class BillOfMaterialsApi extends DolibarrApi
$result = $this->bom->fetch($id);
if( ! $result ) {
- throw new RestException(404, 'BillOfMaterials not found');
+ throw new RestException(404, 'BOM not found');
}
if( ! DolibarrApi::_checkAccessToResource('bom', $this->bom->id)) {
@@ -238,46 +228,49 @@ class BillOfMaterialsApi extends DolibarrApi
}
foreach($request_data as $field => $value) {
+ if ($field == 'id') continue;
$this->bom->$field = $value;
}
- if($this->bom->update($id, DolibarrApiAccess::$user))
+ if($this->bom->update($id, DolibarrApiAccess::$user) > 0)
+ {
return $this->get($id);
-
- return false;
+ }
+ else
+ {
+ throw new RestException(500, $this->commande->error);
+ }
}
/**
* Delete bom
*
- * @param int $id BillOfMaterials ID
+ * @param int $id BOM ID
* @return array
- *
- * @url DELETE bom/{id}
*/
public function delete($id)
{
- if(! DolibarrApiAccess::$user->rights->bom->delete) {
+ if (! DolibarrApiAccess::$user->rights->bom->delete) {
throw new RestException(401);
}
$result = $this->bom->fetch($id);
- if( ! $result ) {
- throw new RestException(404, 'BillOfMaterials not found');
+ if (! $result) {
+ throw new RestException(404, 'BOM not found');
}
- if( ! DolibarrApi::_checkAccessToResource('bom', $this->bom->id)) {
+ if (! DolibarrApi::_checkAccessToResource('bom', $this->bom->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
- if( !$this->bom->delete(DolibarrApiAccess::$user, 0))
+ if (! $this->bom->delete(DolibarrApiAccess::$user))
{
- throw new RestException(500);
+ throw new RestException(500, 'Error when deleting BOM : '.$this->bom->error);
}
return array(
'success' => array(
'code' => 200,
- 'message' => 'BillOfMaterials deleted'
+ 'message' => 'BOM deleted'
)
);
}
@@ -287,8 +280,8 @@ class BillOfMaterialsApi extends DolibarrApi
/**
* Clean sensible object datas
*
- * @param object $object Object to clean
- * @return array Array of cleaned object properties
+ * @param object $object Object to clean
+ * @return array Array of cleaned object properties
*/
protected function _cleanObjectDatas($object)
{
@@ -308,15 +301,15 @@ class BillOfMaterialsApi extends DolibarrApi
/**
* Validate fields before create or update object
*
- * @param array $data Data to validate
- * @return array
+ * @param array $data Array of data to validate
+ * @return array
*
- * @throws RestException
+ * @throws RestException
*/
private function _validate($data)
{
$bom = array();
- foreach (BillOfMaterialsApi::$FIELDS as $field) {
+ foreach (BOMs::$FIELDS as $field) {
if (!isset($data[$field]))
throw new RestException(400, "$field field missing");
$bom[$field] = $data[$field];
diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php
index 24508d6fb11..ca7823a6ac1 100644
--- a/htdocs/commande/class/api_orders.class.php
+++ b/htdocs/commande/class/api_orders.class.php
@@ -16,9 +16,9 @@
* along with this program. If not, see .
*/
- use Luracast\Restler\RestException;
+use Luracast\Restler\RestException;
- require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
+require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
/**
* API class for orders
@@ -544,7 +544,7 @@ class Orders extends DolibarrApi
}
if( ! $this->commande->delete(DolibarrApiAccess::$user)) {
- throw new RestException(500, 'Error when delete order : '.$this->commande->error);
+ throw new RestException(500, 'Error when deleting order : '.$this->commande->error);
}
return array(
diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php
index 566fe56affb..acf7f65454d 100644
--- a/htdocs/modulebuilder/template/class/api_mymodule.class.php
+++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php
@@ -31,7 +31,6 @@ dol_include_once('/mymodule/class/myobject.class.php');
/**
* API class for mymodule myobject
*
- * @smart-auto-routing false
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
@@ -205,7 +204,7 @@ class MyModuleApi extends DolibarrApi
$this->myobject->$field = $value;
}
if( ! $this->myobject->create(DolibarrApiAccess::$user)) {
- throw new RestException(500);
+ throw new RestException(500, "Error creating MyObject", array_merge(array($this->myobject->error), $this->myobject->errors));
}
return $this->myobject->id;
}
@@ -235,13 +234,18 @@ class MyModuleApi extends DolibarrApi
}
foreach($request_data as $field => $value) {
+ if ($field == 'id') continue;
$this->myobject->$field = $value;
}
- if($this->myobject->update($id, DolibarrApiAccess::$user))
+ if ($this->myobject->update($id, DolibarrApiAccess::$user) > 0)
+ {
return $this->get($id);
-
- return false;
+ }
+ else
+ {
+ throw new RestException(500, $this->myobject->error);
+ }
}
/**
@@ -254,21 +258,21 @@ class MyModuleApi extends DolibarrApi
*/
public function delete($id)
{
- if(! DolibarrApiAccess::$user->rights->myobject->delete) {
+ if (! DolibarrApiAccess::$user->rights->myobject->delete) {
throw new RestException(401);
}
$result = $this->myobject->fetch($id);
- if( ! $result ) {
+ if (! $result) {
throw new RestException(404, 'MyObject not found');
}
- if( ! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id)) {
+ if (! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
- if( !$this->myobject->delete(DolibarrApiAccess::$user, 0))
+ if (! $this->myobject->delete(DolibarrApiAccess::$user))
{
- throw new RestException(500);
+ throw new RestException(500, 'Error when deleting MyObject : '.$this->myobject->error);
}
return array(
@@ -305,10 +309,10 @@ class MyModuleApi extends DolibarrApi
/**
* Validate fields before create or update object
*
- * @param array $data Data to validate
- * @return array
+ * @param array $data Array of data to validate
+ * @return array
*
- * @throws RestException
+ * @throws RestException
*/
private function _validate($data)
{
From 8246c79b15fa039a79c0e48af63b734d6bcfc2be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:20:44 +0100
Subject: [PATCH 22/42] Update bom_card.php
---
htdocs/bom/bom_card.php | 45 ++++++-----------------------------------
1 file changed, 6 insertions(+), 39 deletions(-)
diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php
index 0054e427996..28deae35d86 100644
--- a/htdocs/bom/bom_card.php
+++ b/htdocs/bom/bom_card.php
@@ -1,6 +1,6 @@
- * Copyright (C) ---Put here your own copyright and developer email---
+/* Copyright (C) 2017 Laurent Destailleur
+ * Copyright (C) 2019 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,50 +17,17 @@
*/
/**
- * \file bom_card.php
+ * \file htdocs/bom/bom_card.php
* \ingroup bom
* \brief Page to create/edit/view bom
*/
-//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db
-//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Do not load object $user
-//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check injection attack on POST parameters
-//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on).
-//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
-//if (! defined("FORCECSP")) define('FORCECSP','none'); // Disable all Content Security Policies
-
-
// Load Dolibarr environment
-$res=0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
-while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
-if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
-if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
-// Try main.inc.php using relative path
-if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
-if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
-if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
-if (! $res) die("Include of main fails");
-
+require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-dol_include_once('/bom/class/bom.class.php');
-dol_include_once('/bom/lib/bom_bom.lib.php');
+require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
+require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom_bom.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("mrp","other"));
From 6067994119a42eb355cba41f61ec5e458e77fb71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:23:25 +0100
Subject: [PATCH 23/42] Update bom_document.php
---
htdocs/bom/bom_document.php | 23 +++++------------------
1 file changed, 5 insertions(+), 18 deletions(-)
diff --git a/htdocs/bom/bom_document.php b/htdocs/bom/bom_document.php
index b13277cd82b..ff8887bb4e8 100644
--- a/htdocs/bom/bom_document.php
+++ b/htdocs/bom/bom_document.php
@@ -1,6 +1,6 @@
- * Copyright (C) ---Put here your own copyright and developer email---
+/* Copyright (C) 2007-2017 Laurent Destailleur
+ * Copyright (C) 2019 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,26 +23,13 @@
*/
// Load Dolibarr environment
-$res=0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
-while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
-if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
-if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
-// Try main.inc.php using relative path
-if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
-if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
-if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
-if (! $res) die("Include of main fails");
-
+require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-dol_include_once('/bom/class/bom.class.php');
-dol_include_once('/bom/lib/bom_bom.lib.php');
+require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
+require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom_bom.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("mrp","companies","other","mails"));
From e4de89e3eb17ec315f5802c191fa2c4576109235 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:25:02 +0100
Subject: [PATCH 24/42] Update bom_list.php
---
htdocs/bom/bom_list.php | 39 +++------------------------------------
1 file changed, 3 insertions(+), 36 deletions(-)
diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php
index 25fad036b65..6aec37c5f2c 100644
--- a/htdocs/bom/bom_list.php
+++ b/htdocs/bom/bom_list.php
@@ -17,49 +17,16 @@
*/
/**
- * \file bom_list.php
+ * \file htdocs/bom/bom_list.php
* \ingroup bom
* \brief List page for bom
*/
-
-//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db
-//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Do not load object $user
-//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check injection attack on POST parameters
-//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on).
-//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
-//if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session)
-//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
-//if (! defined("XFRAMEOPTIONS_ALLOWALL")) define('XFRAMEOPTIONS_ALLOWALL',1); // Do not add the HTTP header 'X-Frame-Options: SAMEORIGIN' but 'X-Frame-Options: ALLOWALL'
-
// Load Dolibarr environment
-$res=0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
-while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
-if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
-if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
-// Try main.inc.php using relative path
-if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
-if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
-if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
-if (! $res) die("Include of main fails");
-
+require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-dol_include_once('/bom/class/bom.class.php');
+require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
// Load translation files required by the page
$langs->loadLangs(array("mrp", "other"));
From cf00b2a2df5e69b84261e6253826415bbb52ad7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:26:23 +0100
Subject: [PATCH 25/42] Update bom_note.php
---
htdocs/bom/bom_note.php | 23 +++++------------------
1 file changed, 5 insertions(+), 18 deletions(-)
diff --git a/htdocs/bom/bom_note.php b/htdocs/bom/bom_note.php
index fb0d58509d7..4c45512c064 100644
--- a/htdocs/bom/bom_note.php
+++ b/htdocs/bom/bom_note.php
@@ -1,6 +1,6 @@
- * Copyright (C) ---Put here your own copyright and developer email---
+/* Copyright (C) 2007-2017 Laurent Destailleur
+ * Copyright (C) 2019 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,22 +23,9 @@
*/
// Load Dolibarr environment
-$res=0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
-while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
-if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
-if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
-// Try main.inc.php using relative path
-if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
-if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
-if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
-if (! $res) die("Include of main fails");
-
-dol_include_once('/bom/class/bom.class.php');
-dol_include_once('/bom/lib/bom_bom.lib.php');
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
+require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom_bom.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("mrp","companies"));
From 02d4a234b71b3fd07279c971adc698aada23c8e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:30:34 +0100
Subject: [PATCH 26/42] Update bom.lib.php
---
htdocs/bom/lib/bom.lib.php | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/htdocs/bom/lib/bom.lib.php b/htdocs/bom/lib/bom.lib.php
index 0085d06b69c..98f5370217e 100644
--- a/htdocs/bom/lib/bom.lib.php
+++ b/htdocs/bom/lib/bom.lib.php
@@ -1,5 +1,6 @@
+/* Copyright (C) 2019 Maxime Kohlhaas
+ * Copyright (C) 2019 Frédéric France
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,7 +17,7 @@
*/
/**
- * \file bom/lib/bom.lib.php
+ * \file htdocs/bom/lib/bom.lib.php
* \ingroup bom
* \brief Library files with common functions for BillOfMaterials
*/
@@ -40,7 +41,7 @@ function bomAdminPrepareHead()
$head[$h][2] = 'settings';
$h++;
- /*$head[$h][0] = dol_buildpath("/bom/admin/about.php", 1);
+ /*$head[$h][0] = DOL_URL_ROOT."/bom/admin/about.php";
$head[$h][1] = $langs->trans("About");
$head[$h][2] = 'about';
$h++;
@@ -77,7 +78,7 @@ function bomPrepareHead($object)
$h = 0;
$head = array();
- $head[$h][0] = dol_buildpath("/bom/bom_card.php", 1).'?id='.$object->id;
+ $head[$h][0] = DOL_URL_ROOT."/bom/bom_card.php?id=".$object->id;
$head[$h][1] = $langs->trans("Card");
$head[$h][2] = 'card';
$h++;
@@ -87,7 +88,7 @@ function bomPrepareHead($object)
$nbNote = 0;
if (!empty($object->note_private)) $nbNote++;
if (!empty($object->note_public)) $nbNote++;
- $head[$h][0] = dol_buildpath('/bom/bom_note.php', 1).'?id='.$object->id;
+ $head[$h][0] = DOL_URL_ROOT.'/bom/bom_note.php?id=".$object->id;
$head[$h][1] = $langs->trans('Notes');
if ($nbNote > 0) $head[$h][1].= ' '.$nbNote.'';
$head[$h][2] = 'note';
@@ -99,13 +100,13 @@ function bomPrepareHead($object)
$upload_dir = $conf->bom->dir_output . "/bom/" . dol_sanitizeFileName($object->ref);
$nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
$nbLinks=Link::count($db, $object->element, $object->id);
- $head[$h][0] = dol_buildpath("/bom/bom_document.php", 1).'?id='.$object->id;
+ $head[$h][0] = DOL_URL_ROOT."/bom/bom_document.php?id=".$object->id;
$head[$h][1] = $langs->trans('Documents');
if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' '.($nbFiles+$nbLinks).'';
$head[$h][2] = 'document';
$h++;
- $head[$h][0] = dol_buildpath("/bom/bom_agenda.php", 1).'?id='.$object->id;
+ $head[$h][0] = DOL_URL_ROOT."/bom/bom_agenda.php?id=".$object->id;
$head[$h][1] = $langs->trans("Events");
$head[$h][2] = 'agenda';
$h++;
From e57a67493905f7c050d0886f849d3b61ca7aa517 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:36:48 +0100
Subject: [PATCH 27/42] Update setup.php
---
htdocs/bom/admin/setup.php | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
diff --git a/htdocs/bom/admin/setup.php b/htdocs/bom/admin/setup.php
index 561b44fa262..a484718ac32 100644
--- a/htdocs/bom/admin/setup.php
+++ b/htdocs/bom/admin/setup.php
@@ -1,6 +1,7 @@
- * Copyright (C) 2019 Maxime Kohlhaas
+/* Copyright (C) 2004-2017 Laurent Destailleur
+ * Copyright (C) 2019 Maxime Kohlhaas
+ * Copyright (C) 2019 Frédéric France
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,21 +24,7 @@
*/
// Load Dolibarr environment
-$res=0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
-while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
-if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
-if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
-// Try main.inc.php using relative path
-if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
-if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
-if (! $res) die("Include of main fails");
-
-global $langs, $user;
-
+require '../../main.inc.php';
// Libraries
require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
require_once '../lib/bom.lib.php';
@@ -62,11 +49,7 @@ $arrayofparameters=array(
/*
* Actions
*/
-if ((float) DOL_VERSION >= 6)
-{
- include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
-}
-
+include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
/*
* View
From 2185f129cd3b78007f5b95ee49acf8340b94c99b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 18:44:03 +0100
Subject: [PATCH 28/42] syntax error
---
htdocs/bom/lib/bom.lib.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/htdocs/bom/lib/bom.lib.php b/htdocs/bom/lib/bom.lib.php
index 98f5370217e..20f9fccfb01 100644
--- a/htdocs/bom/lib/bom.lib.php
+++ b/htdocs/bom/lib/bom.lib.php
@@ -88,7 +88,7 @@ function bomPrepareHead($object)
$nbNote = 0;
if (!empty($object->note_private)) $nbNote++;
if (!empty($object->note_public)) $nbNote++;
- $head[$h][0] = DOL_URL_ROOT.'/bom/bom_note.php?id=".$object->id;
+ $head[$h][0] = DOL_URL_ROOT.'/bom/bom_note.php?id='.$object->id;
$head[$h][1] = $langs->trans('Notes');
if ($nbNote > 0) $head[$h][1].= ' '.$nbNote.'';
$head[$h][2] = 'note';
@@ -100,13 +100,13 @@ function bomPrepareHead($object)
$upload_dir = $conf->bom->dir_output . "/bom/" . dol_sanitizeFileName($object->ref);
$nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
$nbLinks=Link::count($db, $object->element, $object->id);
- $head[$h][0] = DOL_URL_ROOT."/bom/bom_document.php?id=".$object->id;
+ $head[$h][0] = DOL_URL_ROOT.'/bom/bom_document.php?id='.$object->id;
$head[$h][1] = $langs->trans('Documents');
if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' '.($nbFiles+$nbLinks).'';
$head[$h][2] = 'document';
$h++;
- $head[$h][0] = DOL_URL_ROOT."/bom/bom_agenda.php?id=".$object->id;
+ $head[$h][0] = DOL_URL_ROOT.'/bom/bom_agenda.php?id='.$object->id;
$head[$h][1] = $langs->trans("Events");
$head[$h][2] = 'agenda';
$h++;
From edf9913c20c5d606fe545145c772384d23ebff1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 19:00:12 +0100
Subject: [PATCH 29/42] Update bom_list.php
---
htdocs/bom/bom_list.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php
index 6aec37c5f2c..cf9ad7ffaf2 100644
--- a/htdocs/bom/bom_list.php
+++ b/htdocs/bom/bom_list.php
@@ -56,7 +56,7 @@ $pagenext = $page + 1;
//if (! $sortorder) $sortorder="DESC";
// Initialize technical objects
-$object = new BillOfMaterials($db);
+$object = new BOM($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->bom->dir_output . '/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('bomlist')); // Note that conf->hooks_modules contains array
@@ -146,7 +146,7 @@ if (empty($reshook))
}
// Mass actions
- $objectclass='BillOfMaterials';
+ $objectclass='BOM';
$objectlabel='BillOfMaterials';
$permtoread = $user->rights->bom->read;
$permtodelete = $user->rights->bom->delete;
From 7b0956297636057d4f976ebc96722c3f20884b8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 19:05:13 +0100
Subject: [PATCH 30/42] Update bom_card.php
---
htdocs/bom/bom_card.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php
index 28deae35d86..19d7fdaa60b 100644
--- a/htdocs/bom/bom_card.php
+++ b/htdocs/bom/bom_card.php
@@ -42,7 +42,7 @@ $contextpage= GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'bomcard
$backtopage = GETPOST('backtopage', 'alpha');
// Initialize technical objects
-$object=new BillOfMaterials($db);
+$object=new BOM($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction=$conf->bom->dir_output . '/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('bomcard', 'globalcard')); // Note that conf->hooks_modules contains array
@@ -86,10 +86,10 @@ if (empty($reshook))
$permissiontoadd = $user->rights->bom->write;
$permissiontodelete = $user->rights->bom->delete || ($permissiontoadd && $object->status == 0);
- $backurlforlist = dol_buildpath('/bom/bom_list.php', 1);
+ $backurlforlist = DOL_URL_ROOT.'/bom/bom_list.php';
if (empty($backtopage)) {
if (empty($id)) $backtopage = $backurlforlist;
- else $backtopage = dol_buildpath('/bom/bom_card.php', 1).($id > 0 ? $id : '__ID__');
+ else $backtopage = DOL_URL_ROOT.'/bom/bom_card.php?id='.$id;
}
$triggermodname = 'BILLOFMATERIALS_BILLOFMATERIALS_MODIFY'; // Name of trigger action code to execute when we modify record
From e163849d05ec8f28c64bdc94f4cb9cb04f80b71e Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Wed, 6 Mar 2019 19:13:59 +0100
Subject: [PATCH 31/42] Fix label
---
htdocs/langs/en_US/blockedlog.lang | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/htdocs/langs/en_US/blockedlog.lang b/htdocs/langs/en_US/blockedlog.lang
index 5081b1c0384..9e8771ad68b 100644
--- a/htdocs/langs/en_US/blockedlog.lang
+++ b/htdocs/langs/en_US/blockedlog.lang
@@ -14,9 +14,9 @@ OkCheckFingerprintValidityButChainIsKo=Archived log seems valid compared to prev
AddedByAuthority=Stored into remote authority
NotAddedByAuthorityYet=Not yet stored into remote authority
ShowDetails=Show stored details
-logPAYMENT_VARIOUS_CREATE=Payment (not assigned to invoice) created
-logPAYMENT_VARIOUS_MODIFY=Payment (not assigned to invoice) modified
-logPAYMENT_VARIOUS_DELETE=Payment (not assigned to invoice) logical deletion
+logPAYMENT_VARIOUS_CREATE=Payment (not assigned to an invoice) created
+logPAYMENT_VARIOUS_MODIFY=Payment (not assigned to an invoice) modified
+logPAYMENT_VARIOUS_DELETE=Payment (not assigned to an invoice) logical deletion
logPAYMENT_ADD_TO_BANK=Payment added to bank
logPAYMENT_CUSTOMER_CREATE=Customer payment created
logPAYMENT_CUSTOMER_DELETE=Customer payment logical deletion
From 31c296f44b795503858b9aa26682b05f6dd29430 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Wed, 6 Mar 2019 20:01:21 +0100
Subject: [PATCH 32/42] Fix bad tooltip to rm file
---
htdocs/admin/system/filecheck.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php
index ba8307792fc..f00164698e8 100644
--- a/htdocs/admin/system/filecheck.php
+++ b/htdocs/admin/system/filecheck.php
@@ -339,8 +339,8 @@ if (! $error && $xml)
$out.='
'.$i.'
' . "\n";
$out.='
'.$file['filename'];
if (! preg_match('/^win/i',PHP_OS)) {
- $htmltext=$langs->trans("YouCanDeleteFileOnServerWith", 'rm '.DOL_DOCUMENT_ROOT.'/'.$file['filename']);
- $out.=' '.$form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helprm');
+ $htmltext=$langs->trans("YouCanDeleteFileOnServerWith", 'rm '.DOL_DOCUMENT_ROOT.$file['filename']); // The slash is included int file['filename']
+ $out.=' '.$form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helprm'.$i);
}
$out.='
' . "\n";
$out.='
'.$file['expectedmd5'].'
' . "\n";
From d39b600ff4cd6eb4b702fef71899e38dffe67837 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
Date: Wed, 6 Mar 2019 20:29:58 +0100
Subject: [PATCH 33/42] Update CMailFile.class.php
---
htdocs/core/class/CMailFile.class.php | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
index e23b32c5fb7..3c0e979cbed 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -1,11 +1,12 @@
- * Copyright (C) 2003 Jean-Louis Bergamo
- * Copyright (C) 2004-2015 Laurent Destailleur
- * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) Dan Potter
+ * Copyright (C) Eric Seigne
+ * Copyright (C) 2000-2005 Rodolphe Quiedeville
+ * Copyright (C) 2003 Jean-Louis Bergamo
+ * Copyright (C) 2004-2015 Laurent Destailleur
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2019 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1429,7 +1430,7 @@ class CMailFile
* Return a formatted address string for SMTP protocol
*
* @param string $address Example: 'John Doe , Alan Smith ' or 'john@doe.com, alan@smith.com'
- * @param int $format 0=auto, 1=emails with <>, 2=emails without <>, 3=auto + label between "
+ * @param int $format 0=auto, 1=emails with <>, 2=emails without <>, 3=auto + label between ", 4 label or email, 5 mailto link
* @param int $encode 0=No encode name, 1=Encode name to RFC2822
* @param int $maxnumberofemail 0=No limit. Otherwise, maximum number of emails returned ($address may contains several email separated with ','). Add '...' if there is more.
* @return string If format 0: '' or 'John Doe ' or '=?UTF-8?B?Sm9obiBEb2U=?= '
@@ -1437,6 +1438,7 @@ class CMailFile
* If format 2: 'john@doe.com'
* If format 3: '' or '"John Doe" ' or '"=?UTF-8?B?Sm9obiBEb2U=?=" '
* If format 4: 'John Doe' or 'john@doe.com' if no label exists
+ * If format 5: John Doe or john@doe.com if no label exists
*/
public static function getValidAddress($address, $format, $encode = 0, $maxnumberofemail = 0)
{
@@ -1466,6 +1468,10 @@ class CMailFile
$i++;
$newemail='';
+ if ($format == 5) {
+ $newemail = $name?$name:$email;
+ $newemail = ''.$newemail.'';
+ }
if ($format == 4)
{
$newemail = $name?$name:$email;
From 1b0aec0847732d58da4a719afec45f7e99d14cf0 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Wed, 6 Mar 2019 20:51:07 +0100
Subject: [PATCH 34/42] Complete fields for template invoices
---
htdocs/install/mysql/migration/9.0.0-10.0.0.sql | 7 +++++++
htdocs/install/mysql/tables/llx_facturedet.sql | 8 ++++----
htdocs/install/mysql/tables/llx_facturedet_rec.sql | 7 +++++++
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/htdocs/install/mysql/migration/9.0.0-10.0.0.sql b/htdocs/install/mysql/migration/9.0.0-10.0.0.sql
index 5154d7311a9..7dd893b8dab 100644
--- a/htdocs/install/mysql/migration/9.0.0-10.0.0.sql
+++ b/htdocs/install/mysql/migration/9.0.0-10.0.0.sql
@@ -230,3 +230,10 @@ ALTER TABLE llx_bom_bom ADD INDEX idx_bom_bom_fk_product (fk_product);
ALTER TABLE llx_bom_bomline ADD INDEX idx_bom_bomline_rowid (rowid);
ALTER TABLE llx_bom_bomline ADD INDEX idx_bom_bomline_fk_product (fk_product);
ALTER TABLE llx_bom_bomline ADD INDEX idx_bom_bomline_fk_bom (fk_bom);
+
+ALTER TABLE llx_facturedet_rec ADD COLUMN buy_price_ht double(24,8) DEFAULT 0;
+ALTER TABLE llx_facturedet_rec ADD COLUMN fk_product_fournisseur_price integer DEFAULT NULL;
+
+ALTER TABLE llx_facturedet_rec ADD COLUMN fk_user_author integer;
+ALTER TABLE llx_facturedet_rec ADD COLUMN fk_user_modif integer;
+
diff --git a/htdocs/install/mysql/tables/llx_facturedet.sql b/htdocs/install/mysql/tables/llx_facturedet.sql
index ac7142c898d..deb52576a8a 100644
--- a/htdocs/install/mysql/tables/llx_facturedet.sql
+++ b/htdocs/install/mysql/tables/llx_facturedet.sql
@@ -55,16 +55,16 @@ create table llx_facturedet
buy_price_ht double(24,8) DEFAULT 0, -- buying price. Note: this value is saved as an always positive value, even on credit notes (it is price we bought the product before selling it).
fk_product_fournisseur_price integer DEFAULT NULL, -- reference of supplier price when line was added (may be used to update buy_price_ht current price when future invoice will be created)
- fk_code_ventilation integer DEFAULT 0 NOT NULL, -- Id in table llx_accounting_bookeeping to know accounting account for product line
-
special_code integer DEFAULT 0, -- code for special lines (may be 1=transport, 2=ecotax, 3=option, moduleid=...)
rang integer DEFAULT 0, -- position of line
fk_contract_line integer NULL, -- id of contract line when invoice comes from contract lines
+ fk_unit integer DEFAULT NULL, -- id of the unit code
import_key varchar(14),
+ fk_code_ventilation integer DEFAULT 0 NOT NULL, -- Id in table llx_accounting_bookeeping to know accounting account for product line
+
situation_percent real, -- % progression of lines invoicing
- fk_prev_id integer, -- id of the line in the previous situation,
- fk_unit integer DEFAULT NULL, -- id of the unit code¡
+ fk_prev_id integer, -- id of the line in the previous situation
fk_user_author integer, -- user making creation
fk_user_modif integer, -- user making last change
diff --git a/htdocs/install/mysql/tables/llx_facturedet_rec.sql b/htdocs/install/mysql/tables/llx_facturedet_rec.sql
index ac79dfd891d..267abcd5053 100644
--- a/htdocs/install/mysql/tables/llx_facturedet_rec.sql
+++ b/htdocs/install/mysql/tables/llx_facturedet_rec.sql
@@ -48,11 +48,18 @@ create table llx_facturedet_rec
date_start_fill integer DEFAULT 0, -- 1=autofill the date_start of invoice with __INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__
date_end_fill integer DEFAULT 0, -- 1=autofill the date_start of invoice with __INVOICE_PREVIOUS_DATE_NEXT_INVOICE_AFTER_GEN__
info_bits integer DEFAULT 0, -- TVA NPR ou non
+
+ buy_price_ht double(24,8) DEFAULT 0, -- buying price. Note: this value is saved as an always positive value, even on credit notes (it is price we bought the product before selling it).
+ fk_product_fournisseur_price integer DEFAULT NULL, -- reference of supplier price when line was added (may be used to update buy_price_ht current price when future invoice will be created)
+
special_code integer UNSIGNED DEFAULT 0, -- code pour les lignes speciales
rang integer DEFAULT 0, -- ordre d'affichage
fk_contract_line integer NULL, -- id of contract line when template invoice comes from contract lines
fk_unit integer DEFAULT NULL,
import_key varchar(14),
+
+ fk_user_author integer, -- user making creation
+ fk_user_modif integer, -- user making last change
fk_multicurrency integer,
multicurrency_code varchar(255),
From b15e00cae798c8792a7b5c7aef104bdfa94f665b Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Wed, 6 Mar 2019 21:39:09 +0100
Subject: [PATCH 35/42] FIX Autodetect buy price for invoices autogenerated
with templates.
---
htdocs/compta/facture/card.php | 2 +-
htdocs/compta/facture/class/facture.class.php | 31 +++++++++++++++++--
htdocs/product/class/product.class.php | 7 +++--
3 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 1df96583ce3..e37d2c3d2a9 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -1129,7 +1129,7 @@ if (empty($reshook))
// Source facture
$object->fac_rec = GETPOST('fac_rec', 'int');
- $id = $object->create($user); // This include recopy of links from recurring invoice and invoice lines
+ $id = $object->create($user); // This include recopy of links from recurring invoice and recurring invoice lines
}
}
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index dda877d0a1f..86ee5482261 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -723,7 +723,7 @@ class Facture extends CommonInvoice
}
/*
- * Insert lines of predefined invoices
+ * Insert lines of template invoices
*/
if (! $error && $this->fac_rec > 0)
{
@@ -749,6 +749,31 @@ class Facture extends CommonInvoice
$localtax1_tx = $_facrec->lines[$i]->localtax1_tx;
$localtax2_tx = $_facrec->lines[$i]->localtax2_tx;
+ $fk_product_fournisseur_price = empty($_facrec->lines[$i]->fk_product_fournisseur_price)?null:$_facrec->lines[$i]->fk_product_fournisseur_price;
+ $buyprice = empty($_facrec->lines[$i]->buyprice)?0:$_facrec->lines[$i]->buyprice;
+ // If buyprice not defined from template invoice, we try to guess the best value
+ if (! $buyprice && $_facrec->lines[$i]->fk_product > 0)
+ {
+ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
+ $producttmp = new ProductFournisseur($this->db);
+ $producttmp->fetch($_facrec->lines[$i]->fk_product);
+
+ // If margin module defined on costprice, we try the costprice
+ // If not defined or if module margin defined and pmp and stock module enabled, we try pmp price
+ // else we get the best supplier price
+ if ($conf->global->MARGIN_TYPE == 'costprice' && ! empty($producttmp->cost_price)) $buyprice = $producttmp->cost_price;
+ elseif (! empty($conf->stock->enabled) && ($conf->global->MARGIN_TYPE == 'costprice' || $conf->global->MARGIN_TYPE == 'pmp') && ! empty($producttmp->pmp)) $buyprice = $producttmp->pmp;
+ else {
+ if ($producttmp->find_min_price_product_fournisseur($_facrec->lines[$i]->fk_product) > 0)
+ {
+ if ($producttmp->product_fourn_price_id > 0)
+ {
+ $buyprice = price2num($producttmp->fourn_unitprice * (1 - $producttmp->fourn_remise_percent/100) + $producttmp->fourn_remise, 'MU');
+ }
+ }
+ }
+ }
+
$result_insert = $this->addline(
$_facrec->lines[$i]->desc,
$_facrec->lines[$i]->subprice,
@@ -771,8 +796,8 @@ class Facture extends CommonInvoice
'',
0,
0,
- null,
- 0,
+ $fk_product_fournisseur_price,
+ $buyprice,
$_facrec->lines[$i]->label,
empty($_facrec->lines[$i]->array_options)?null:$_facrec->lines[$i]->array_options,
$_facrec->lines[$i]->situation_percent,
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 316a911d5a3..88b410da7fa 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -1528,8 +1528,8 @@ class Product extends CommonObject
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
/**
- * Read price used by a provider.
- * We enter as input couple prodfournprice/qty or triplet qty/product_id/fourn_ref.
+ * Read price used by a provider.
+ * We enter as input couple prodfournprice/qty or triplet qty/product_id/fourn_ref.
* This also set some properties on product like ->buyprice, ->fourn_pu, ...
*
* @param int $prodfournprice Id du tarif = rowid table product_fournisseur_price
@@ -1537,7 +1537,8 @@ class Product extends CommonObject
* @param int $product_id Filter on a particular product id
* @param string $fourn_ref Filter on a supplier price ref. 'none' to exclude ref in search.
* @param int $fk_soc If of supplier
- * @return int <-1 if KO, -1 if qty not enough, 0 if OK but nothing found, id_product if OK and found. May also initialize some properties like (->ref_supplier, buyprice, fourn_pu, vatrate_supplier...)
+ * @return int <-1 if KO, -1 if qty not enough, 0 if OK but nothing found, id_product if OK and found. May also initialize some properties like (->ref_supplier, buyprice, fourn_pu, vatrate_supplier...)
+ * @see find_min_price_product_fournisseur()
*/
function get_buyprice($prodfournprice, $qty, $product_id=0, $fourn_ref='', $fk_soc=0)
{
From c5131167171cd9c1f977599c47ea18fc88e5f722 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Thu, 7 Mar 2019 10:56:48 +0100
Subject: [PATCH 36/42] FIX missing vat_src_code when inserting an expense
report line
---
htdocs/expensereport/class/expensereport.class.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php
index a8e5f80244c..dd2818f28bf 100644
--- a/htdocs/expensereport/class/expensereport.class.php
+++ b/htdocs/expensereport/class/expensereport.class.php
@@ -1729,6 +1729,7 @@ class ExpenseReport extends CommonObject
$tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller, $localtaxes_type);
$this->line->value_unit = $up;
+ $this->line->vat_src_code = $vat_src_code;
$this->line->vatrate = price2num($vatrate);
$this->line->total_ttc = $tmp[2];
$this->line->total_ht = $tmp[0];
From 2cd09aaf0929181894da2660e46e3deed8df9901 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Thu, 7 Mar 2019 10:57:15 +0100
Subject: [PATCH 37/42] Prepare version 9.0.2
---
htdocs/filefunc.inc.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
index b2213c5d03c..03f949c6fe6 100644
--- a/htdocs/filefunc.inc.php
+++ b/htdocs/filefunc.inc.php
@@ -31,7 +31,7 @@
*/
if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
-if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
+if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.2'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
if (! defined('EURO')) define('EURO',chr(128));
From 96d4e2847324d093a1fd7709ea637ef0f750e8a5 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur
Date: Thu, 7 Mar 2019 11:08:01 +0100
Subject: [PATCH 38/42] FIX Vat src code lost after editing expense report line
---
htdocs/expensereport/card.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
index eb71a30e083..fab70b1200a 100644
--- a/htdocs/expensereport/card.php
+++ b/htdocs/expensereport/card.php
@@ -2137,7 +2137,7 @@ else
// VAT
print '
';
diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
index 2ce6ca0f70a..3c7253f9065 100644
--- a/htdocs/expensereport/card.php
+++ b/htdocs/expensereport/card.php
@@ -133,6 +133,7 @@ if (empty($reshook))
$date='';
$comments='';
$vatrate='';
+ $value_unit_ht='';
$value_unit='';
$qty=1;
$fk_c_type_fees=-1;
@@ -1095,10 +1096,16 @@ if (empty($reshook))
// if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
if (empty($vatrate)) $vatrate = "0.000";
- $vatrate = price2num($vatrate);
+ $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate));
+ $value_unit_ht=price2num(GETPOST('value_unit_ht', 'alpha'), 'MU');
$value_unit=price2num(GETPOST('value_unit', 'alpha'), 'MU');
- $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
+ if (empty($value_unit))
+ {
+ $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU');
+ }
+
+ $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
$qty = GETPOST('qty', 'int');
if (empty($qty)) $qty=1;
@@ -1110,23 +1117,13 @@ if (empty($reshook))
$action='';
}
- if ($vatrate < 0 || $vatrate == '')
+ if ((int) $tmpvat < 0 || $tmpvat == '')
{
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("VAT")), null, 'errors');
$action='';
}
- /* Projects are never required. To force them, check module forceproject
- if ($conf->projet->enabled)
- {
- if (empty($object_ligne->fk_projet) || $object_ligne->fk_projet==-1)
- {
- $error++;
- setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Project")), null, 'errors');
- }
- }*/
-
// Si aucune date n'est rentrée
if (empty($date) || $date=="--")
{
@@ -1134,7 +1131,7 @@ if (empty($reshook))
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
}
// Si aucun prix n'est rentré
- if ($value_unit==0)
+ if ($value_unit == 0)
{
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PriceUTTC")), null, 'errors');
@@ -1171,6 +1168,7 @@ if (empty($reshook))
}
unset($qty);
+ unset($value_unit_ht);
unset($value_unit);
unset($vatrate);
unset($comments);
@@ -1240,12 +1238,18 @@ if (empty($reshook))
$projet_id = $fk_projet;
$comments = GETPOST('comments', 'none');
$qty = GETPOST('qty', 'int');
- $value_unit = price2num(GETPOST('value_unit', 'alpha'), 'MU');
$vatrate = GETPOST('vatrate', 'alpha');
- // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
- if (empty($vatrate)) $vatrate = "0.000";
- $vatrate = price2num($vatrate);
+ // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
+ if (empty($vatrate)) $vatrate = "0.000";
+ $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate));
+
+ $value_unit_ht=price2num(GETPOST('value_unit_ht', 'alpha'), 'MU');
+ $value_unit=price2num(GETPOST('value_unit', 'alpha'), 'MU');
+ if (empty($value_unit))
+ {
+ $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU');
+ }
if (! GETPOST('fk_c_type_fees', 'int') > 0)
{
@@ -1253,7 +1257,7 @@ if (empty($reshook))
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
$action='';
}
- if ((int) $vatrate < 0 || $vatrate == '')
+ if ((int) $tmpvat < 0 || $tmpvat == '')
{
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Vat")), null, 'errors');
@@ -1742,7 +1746,7 @@ else
print '
';
// User to inform for approval
- if ($object->fk_statut < 3) // informed
+ if ($object->fk_statut <= ExpenseReport::STATUS_VALIDATED) // informed
{
print '
';
}
// TODO Replace this. It should be SetUnpaid and should go back to status unpaid not canceled.
- if (($user->rights->expensereport->approve || $user->rights->expensereport->to_paid) && $object->fk_statut == 6)
+ if (($user->rights->expensereport->approve || $user->rights->expensereport->to_paid) && $object->fk_statut == ExpenseReport::STATUS_CLOSED)
{
// Cancel
print '
';
@@ -2412,12 +2449,12 @@ if ($action != 'create' && $action != 'edit')
}
/* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */
- if ($user->rights->expensereport->creer && $user->id == $object->fk_user_author && $object->fk_statut <= 4)
+ if ($user->rights->expensereport->creer && $user->id == $object->fk_user_author && $object->fk_statut < ExpenseReport::STATUS_APPROVED)
{
// Delete
print '
';
diff --git a/htdocs/adherents/stats/geo.php b/htdocs/adherents/stats/geo.php
index f5816f46aca..79aa5ab6a82 100644
--- a/htdocs/adherents/stats/geo.php
+++ b/htdocs/adherents/stats/geo.php
@@ -77,8 +77,10 @@ if ($mode)
$tab='statscountry';
$data = array();
- $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, c.code, c.label";
- $sql.=" FROM ".MAIN_DB_PREFIX."adherent as d LEFT JOIN ".MAIN_DB_PREFIX."c_country as c on d.country = c.rowid";
+ $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, c.code, c.label";
+ $sql.=" FROM ".MAIN_DB_PREFIX."adherent as d";
+ $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_country as c on d.country = c.rowid";
+ $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."subscription as s ON s.fk_adherent = d.rowid";
$sql.=" WHERE d.entity IN (".getEntity('adherent').")";
$sql.=" AND d.statut = 1";
$sql.=" GROUP BY c.label, c.code";
@@ -92,10 +94,12 @@ if ($mode)
$tab='statsstate';
$data = array();
- $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, co.code, co.label, c.nom as label2"; //
- $sql.=" FROM ".MAIN_DB_PREFIX."adherent as d LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c on d.state_id = c.rowid";
+ $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, co.code, co.label, c.nom as label2"; //
+ $sql.=" FROM ".MAIN_DB_PREFIX."adherent as d";
+ $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c on d.state_id = c.rowid";
$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_regions as r on c.fk_region = r.code_region";
$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_country as co on d.country = co.rowid";
+ $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."subscription as s ON s.fk_adherent = d.rowid";
$sql.=" WHERE d.entity IN (".getEntity('adherent').")";
$sql.=" AND d.statut = 1";
$sql.=" GROUP BY co.label, co.code, c.nom";
@@ -108,10 +112,12 @@ if ($mode)
$tab='statsregion'; //onglet
$data = array(); //tableau de donnée
- $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, co.code, co.label, r.nom as label2";
- $sql.=" FROM ".MAIN_DB_PREFIX."adherent as d LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c on d.state_id = c.rowid";
+ $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, co.code, co.label, r.nom as label2";
+ $sql.=" FROM ".MAIN_DB_PREFIX."adherent as d";
+ $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c on d.state_id = c.rowid";
$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_regions as r on c.fk_region = r.code_region";
$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_country as co on d.country = co.rowid";
+ $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."subscription as s ON s.fk_adherent = d.rowid";
$sql.=" WHERE d.entity IN (".getEntity('adherent').")";
$sql.=" AND d.statut = 1";
$sql.=" GROUP BY co.label, co.code, r.nom"; //+
@@ -124,9 +130,10 @@ if ($mode)
$tab='statstown';
$data = array();
- $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, c.code, c.label, d.town as label2";
+ $sql.="SELECT COUNT(d.rowid) as nb, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, c.code, c.label, d.town as label2";
$sql.=" FROM ".MAIN_DB_PREFIX."adherent as d";
$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_country as c on d.country = c.rowid";
+ $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."subscription as s ON s.fk_adherent = d.rowid";
$sql.=" WHERE d.entity IN (".getEntity('adherent').")";
$sql.=" AND d.statut = 1";
$sql.=" GROUP BY c.label, c.code, d.town";
@@ -154,7 +161,8 @@ if ($mode)
'label_en'=>(($obj->code && $langsen->transnoentitiesnoconv("Country".$obj->code)!="Country".$obj->code)?$langsen->transnoentitiesnoconv("Country".$obj->code):($obj->label?$obj->label:$langs->trans("Unknown"))),
'code'=>$obj->code,
'nb'=>$obj->nb,
- 'lastdate'=>$db->jdate($obj->lastdate)
+ 'lastdate'=>$db->jdate($obj->lastdate),
+ 'lastsubscriptiondate'=>$db->jdate($obj->lastsubscriptiondate)
);
}
if ($mode == 'memberbyregion') //+
@@ -164,7 +172,8 @@ if ($mode)
'label_en'=>(($obj->code && $langsen->transnoentitiesnoconv("Country".$obj->code)!="Country".$obj->code)?$langsen->transnoentitiesnoconv("Country".$obj->code):($obj->label?$obj->label:$langs->trans("Unknown"))),
'label2'=>($obj->label2?$obj->label2:$langs->trans("Unknown")),
'nb'=>$obj->nb,
- 'lastdate'=>$db->jdate($obj->lastdate)
+ 'lastdate'=>$db->jdate($obj->lastdate),
+ 'lastsubscriptiondate'=>$db->jdate($obj->lastsubscriptiondate)
);
}
if ($mode == 'memberbystate')
@@ -173,7 +182,8 @@ if ($mode)
'label_en'=>(($obj->code && $langsen->transnoentitiesnoconv("Country".$obj->code)!="Country".$obj->code)?$langsen->transnoentitiesnoconv("Country".$obj->code):($obj->label?$obj->label:$langs->trans("Unknown"))),
'label2'=>($obj->label2?$obj->label2:$langs->trans("Unknown")),
'nb'=>$obj->nb,
- 'lastdate'=>$db->jdate($obj->lastdate)
+ 'lastdate'=>$db->jdate($obj->lastdate),
+ 'lastsubscriptiondate'=>$db->jdate($obj->lastsubscriptiondate)
);
}
if ($mode == 'memberbytown')
@@ -182,7 +192,8 @@ if ($mode)
'label_en'=>(($obj->code && $langsen->transnoentitiesnoconv("Country".$obj->code)!="Country".$obj->code)?$langsen->transnoentitiesnoconv("Country".$obj->code):($obj->label?$obj->label:$langs->trans("Unknown"))),
'label2'=>($obj->label2?$obj->label2:$langs->trans("Unknown")),
'nb'=>$obj->nb,
- 'lastdate'=>$db->jdate($obj->lastdate)
+ 'lastdate'=>$db->jdate($obj->lastdate),
+ 'lastsubscriptiondate'=>$db->jdate($obj->lastsubscriptiondate)
);
}
@@ -289,9 +300,9 @@ if ($mode)
if ($label2) print '
'.$label2.'
';
print '
'.$langs->trans("NbOfMembers").'
';
print '
'.$langs->trans("LastMemberDate").'
';
+ print '
'.$langs->trans("LatestSubscriptionDate").'
';
print '
';
- $oldyear=0;
foreach ($data as $val)
{
$year = $val['year'];
@@ -300,8 +311,8 @@ if ($mode)
if ($label2) print '