From 60493d0a4774735616feefe769cfe40a74db7921 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 10:16:17 +0200 Subject: [PATCH 01/14] Several fixes (permission, missing method or class) in REST APIs --- htdocs/api/index.php | 1 + .../comm/propal/class/api_proposals.class.php | 128 +++--- htdocs/commande/class/api_orders.class.php | 20 +- .../facture/class/api_invoices.class.php | 127 ++++-- htdocs/core/lib/functions2.lib.php | 2 +- .../class/api_supplier_invoices.class.php | 126 ++++-- .../fourn/class/api_supplier_orders.class.php | 365 ++++++++++++++++++ 7 files changed, 623 insertions(+), 146 deletions(-) create mode 100644 htdocs/fourn/class/api_supplier_orders.class.php diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 905d560f9c2..9f734c9e24d 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -238,6 +238,7 @@ if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' { $classfile = str_replace('_', '', $module); if ($module == 'supplierinvoices') $classfile = 'supplier_invoices'; + if ($module == 'supplierorders') $classfile = 'supplier_orders'; $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php'); $classname=ucwords($module); diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 2f067f46b18..42dbdbf9d2c 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -24,14 +24,14 @@ require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; /** * API class for orders * - * @access protected + * @access protected * @class DolibarrApiAccess {@requires user,external} */ class Proposals extends DolibarrApi { /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( 'socid' @@ -56,36 +56,36 @@ class Proposals extends DolibarrApi * Get properties of a commercial proposal object * * Return an array with commercial proposal informations - * + * * @param int $id ID of commercial proposal * @return array|mixed data without useless information * * @throws RestException */ function get($id) - { + { if(! DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $this->propal->fetchObjectLinked(); return $this->_cleanObjectDatas($this->propal); } /** * List commercial proposals - * + * * Get a list of commercial proposals - * + * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list @@ -96,12 +96,12 @@ class Proposals extends DolibarrApi */ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '', $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - + // If the internal user must only see his customers, force searching by him $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; @@ -109,7 +109,7 @@ class Proposals extends DolibarrApi $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."propal as t"; - + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ' WHERE t.entity IN ('.getEntity('propal').')'; @@ -122,7 +122,7 @@ class Proposals extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -131,7 +131,7 @@ class Proposals extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -144,7 +144,7 @@ class Proposals extends DolibarrApi } $result = $db->query($sql); - + if ($result) { $num = $db->num_rows($result); @@ -195,7 +195,7 @@ class Proposals extends DolibarrApi if ($this->propal->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors)); } - + return $this->propal->id; } @@ -203,21 +203,21 @@ class Proposals extends DolibarrApi * Get lines of a commercial proposal * * @param int $id Id of commercial proposal - * + * * @url GET {id}/lines - * - * @return int + * + * @return int */ function getLines($id) { if(! DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -233,22 +233,22 @@ class Proposals extends DolibarrApi * Add a line to given commercial proposal * * @param int $id Id of commercial proposal to update - * @param array $request_data Commercial proposal line data - * + * @param array $request_data Commercial proposal line data + * * @url POST {id}/lines - * - * @return int + * + * @return int */ function postLine($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -294,22 +294,22 @@ class Proposals extends DolibarrApi * * @param int $id Id of commercial proposal to update * @param int $lineid Id of line to update - * @param array $request_data Commercial proposal line data - * + * @param array $request_data Commercial proposal line data + * * @url PUT {id}/lines/{lineid} - * - * @return object + * + * @return object */ function putLine($id, $lineid, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -352,21 +352,21 @@ class Proposals extends DolibarrApi * * @param int $id Id of commercial proposal to update * @param int $lineid Id of line to delete - * + * * @url DELETE {id}/lines/{lineid} - * - * @return int + * + * @return int */ function delLine($id, $lineid) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -382,20 +382,20 @@ class Proposals extends DolibarrApi * Update commercial proposal general fields (won't touch lines of commercial proposal) * * @param int $id Id of commercial proposal to update - * @param array $request_data Datas - * - * @return int + * @param array $request_data Datas + * + * @return int */ function put($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -403,18 +403,18 @@ class Proposals extends DolibarrApi if ($field == 'id') continue; $this->propal->$field = $value; } - + if($this->propal->update($id, DolibarrApiAccess::$user,1,'','','update')) return $this->get($id); - + return false; } - + /** * Delete commercial proposal * * @param int $id Commercial proposal ID - * + * * @return array */ function delete($id) @@ -426,32 +426,32 @@ class Proposals extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if( ! $this->propal->delete(DolibarrApiAccess::$user)) { throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error); } - + return array( 'success' => array( 'code' => 200, 'message' => 'Commercial Proposal deleted' ) ); - + } - + /** * Validate a commercial proposal - * + * * @param int $id Commercial proposal ID * @param int $notrigger Use {} - * + * * @url POST {id}/validate - * + * * @return array * FIXME An error 403 is returned if the request has an empty body. * Error message: "Forbidden: Content type `text/plain` is not supported." @@ -469,11 +469,11 @@ class Proposals extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { throw new RestException(500, 'Error nothing done. May be object is already validated'); @@ -481,30 +481,30 @@ class Proposals extends DolibarrApi if ($result < 0) { throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error); } - + return array( 'success' => array( 'code' => 200, - 'message' => 'Commercial Proposal validated' + 'message' => 'Commercial Proposal validated (Ref='.$this->propal->ref.')' ) ); } - + /** * Validate fields before create or update object - * + * * @param array $data Array with data to verify - * @return array + * @return array * @throws RestException */ function _validate($data) { $propal = array(); - foreach (Orders::$FIELDS as $field) { + foreach (Proposals::$FIELDS as $field) { if (!isset($data[$field])) throw new RestException(400, "$field field missing"); $propal[$field] = $data[$field]; - + } return $propal; } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index a1330a7be04..d4b4502d4ed 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -80,8 +80,8 @@ class Orders extends DolibarrApi return $this->_cleanObjectDatas($this->commande); } - - + + /** * List orders * @@ -101,7 +101,7 @@ class Orders extends DolibarrApi global $db, $conf; $obj_ret = array(); - + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; @@ -125,7 +125,7 @@ class Orders extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -134,7 +134,7 @@ class Orders extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -490,7 +490,7 @@ class Orders extends DolibarrApi return array( 'success' => array( 'code' => 200, - 'message' => 'Order validated' + 'message' => 'Order validated (Ref='.$this->commande->ref.')' ) ); } @@ -502,14 +502,14 @@ class Orders extends DolibarrApi * @return array Array of cleaned object properties */ function _cleanObjectDatas($object) { - + $object = parent::_cleanObjectDatas($object); - + unset($object->address); - + return $object; } - + /** * Validate fields before create or update object * diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 55304136ed6..f841fc80050 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -22,14 +22,14 @@ /** * API class for invoices * - * @access protected + * @access protected * @class DolibarrApiAccess {@requires user,external} */ class Invoices extends DolibarrApi { /** * - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( 'socid' @@ -54,23 +54,23 @@ class Invoices extends DolibarrApi * Get properties of a invoice object * * Return an array with invoice informations - * + * * @param int $id ID of invoice * @return array|mixed data without useless information * * @throws RestException */ function get($id) - { + { if(! DolibarrApiAccess::$user->rights->facture->lire) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Invoice not found'); } - + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -80,9 +80,9 @@ class Invoices extends DolibarrApi /** * List invoices - * + * * Get a list of invoices - * + * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list @@ -96,12 +96,12 @@ class Invoices extends DolibarrApi */ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - + // If the internal user must only see his customers, force searching by him $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; @@ -109,7 +109,7 @@ class Invoices extends DolibarrApi $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."facture as t"; - + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ' WHERE t.entity IN ('.getEntity('facture').')'; @@ -117,7 +117,7 @@ class Invoices extends DolibarrApi if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + // Filter by status if ($status == 'draft') $sql.= " AND t.fk_statut IN (0)"; if ($status == 'unpaid') $sql.= " AND t.fk_statut IN (1)"; @@ -129,7 +129,7 @@ class Invoices extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -138,7 +138,7 @@ class Invoices extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -174,10 +174,10 @@ class Invoices extends DolibarrApi } return $obj_ret; } - + /** * Create invoice object - * + * * @param array $request_data Request datas * @return int ID of invoice */ @@ -188,7 +188,7 @@ class Invoices extends DolibarrApi } // Check mandatory fields $result = $this->_validate($request_data); - + foreach($request_data as $field => $value) { $this->invoice->$field = $value; } @@ -203,7 +203,7 @@ class Invoices extends DolibarrApi } $this->invoice->lines = $lines; }*/ - + if ($this->invoice->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors)); } @@ -214,20 +214,20 @@ class Invoices extends DolibarrApi * Update invoice * * @param int $id Id of invoice to update - * @param array $request_data Datas - * @return int + * @param array $request_data Datas + * @return int */ function put($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->facture->creer) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Invoice not found'); } - + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -236,13 +236,13 @@ class Invoices extends DolibarrApi if ($field == 'id') continue; $this->invoice->$field = $value; } - + if($this->invoice->update($id, DolibarrApiAccess::$user)) return $this->get ($id); - + return false; } - + /** * Delete invoice * @@ -258,16 +258,16 @@ class Invoices extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Invoice not found'); } - + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if( $this->invoice->delete($id) < 0) { throw new RestException(500); } - + return array( 'success' => array( 'code' => 200, @@ -275,13 +275,76 @@ class Invoices extends DolibarrApi ) ); } - + + /** + * Validate an order + * + * @param int $id Order ID + * @param int $idwarehouse Warehouse ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "idwarehouse": 0, + * "notrigger": 0 + * } + */ + function validate($id, $idwarehouse=0, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Invoice validated (Ref='.$this->invoice->ref.')' + ) + ); + } + + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) { + + $object = parent::_cleanObjectDatas($object); + + unset($object->address); + + return $object; + } + /** * Validate fields before create or update object - * + * * @param array|null $data Datas to validate * @return array - * + * * @throws RestException */ function _validate($data) @@ -294,5 +357,5 @@ class Invoices extends DolibarrApi } return $invoice; } - + } diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 72f27a16602..181e8a7fe11 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2200,7 +2200,7 @@ function getModuleDirForApiClass($module) elseif ($module == 'stock' || $module == 'stockmovements' || $module == 'warehouses') { $moduledirforclass = 'product/stock'; } - elseif ($module == 'fournisseur' || $module == 'supplierinvoices') { + elseif ($module == 'fournisseur' || $module == 'supplierinvoices' || $module == 'supplierorders') { $moduledirforclass = 'fourn'; } elseif ($module == 'expensereports') { diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 6f3291518ca..26ae936d5a0 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -23,14 +23,14 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; /** * API class for supplier invoices * - * @access protected + * @access protected * @class DolibarrApiAccess {@requires user,external} */ class SupplierInvoices extends DolibarrApi { /** * - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( 'socid' @@ -55,24 +55,24 @@ class SupplierInvoices extends DolibarrApi * Get properties of a supplier invoice object * * Return an array with supplier invoice information - * + * * @param int $id ID of supplier invoice * @return array|mixed data without useless information * * @throws RestException */ function get($id) - { + { if(! DolibarrApiAccess::$user->rights->fournisseur->facture->lire) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Supplier invoice not found'); } - - if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -81,9 +81,9 @@ class SupplierInvoices extends DolibarrApi /** * List invoices - * + * * Get a list of supplier invoices - * + * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list @@ -97,12 +97,12 @@ class SupplierInvoices extends DolibarrApi */ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - + // If the internal user must only see his customers, force searching by him $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; @@ -110,14 +110,14 @@ class SupplierInvoices extends DolibarrApi $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as t"; - + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ' WHERE t.entity IN ('.getEntity('supplier_invoice').')'; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + // Filter by status if ($status == 'draft') $sql.= " AND t.fk_statut IN (0)"; if ($status == 'unpaid') $sql.= " AND t.fk_statut IN (1)"; @@ -129,7 +129,7 @@ class SupplierInvoices extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -138,7 +138,7 @@ class SupplierInvoices extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -174,10 +174,10 @@ class SupplierInvoices extends DolibarrApi } return $obj_ret; } - + /** * Create supplier invoice object - * + * * @param array $request_data Request datas * @return int ID of supplier invoice */ @@ -188,7 +188,7 @@ class SupplierInvoices extends DolibarrApi } // Check mandatory fields $result = $this->_validate($request_data); - + foreach($request_data as $field => $value) { $this->invoice->$field = $value; } @@ -203,7 +203,7 @@ class SupplierInvoices extends DolibarrApi } $this->invoice->lines = $lines; }*/ - + if ($this->invoice->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating order", array_merge(array($this->invoice->error), $this->invoice->errors)); } @@ -214,21 +214,21 @@ class SupplierInvoices extends DolibarrApi * Update supplier invoice * * @param int $id Id of supplier invoice to update - * @param array $request_data Datas - * @return int + * @param array $request_data Datas + * @return int */ function put($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->fournisseur->facture->creer) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Supplier invoice not found'); } - - if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -236,13 +236,13 @@ class SupplierInvoices extends DolibarrApi if ($field == 'id') continue; $this->invoice->$field = $value; } - + if($this->invoice->update($id, DolibarrApiAccess::$user)) return $this->get ($id); - + return false; } - + /** * Delete supplier invoice * @@ -258,16 +258,16 @@ class SupplierInvoices extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Supplier invoice not found'); } - - if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if( $this->invoice->delete(DolibarrApiAccess::$user) < 0) { throw new RestException(500); } - + return array( 'success' => array( 'code' => 200, @@ -275,8 +275,56 @@ class SupplierInvoices extends DolibarrApi ) ); } - - + + + /** + * Validate an order + * + * @param int $id Order ID + * @param int $idwarehouse Warehouse ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "idwarehouse": 0, + * "notrigger": 0 + * } + */ + function validate($id, $idwarehouse=0, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Invoice validated (Ref='.$this->invoice->ref.')' + ) + ); + } + /** * Clean sensible object datas * @@ -284,20 +332,20 @@ class SupplierInvoices extends DolibarrApi * @return array Array of cleaned object properties */ function _cleanObjectDatas($object) { - + $object = parent::_cleanObjectDatas($object); - + unset($object->rowid); - + return $object; } - + /** * Validate fields before create or update object - * + * * @param array $data Datas to validate * @return array - * + * * @throws RestException */ function _validate($data) diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php new file mode 100644 index 00000000000..2695727c3ee --- /dev/null +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -0,0 +1,365 @@ + + * Copyright (C) 2016 Laurent Destailleur + * + * 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 . + */ + +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; + +/** + * API class for supplier orders + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class SupplierOrders extends DolibarrApi +{ + /** + * + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'socid' + ); + + /** + * @var CommandeFournisseur $order {@type CommandeFournisseur} + */ + public $order; + + /** + * Constructor + */ + function __construct() + { + global $db, $conf; + $this->db = $db; + $this->order = new CommandeFournisseur($this->db); + } + + /** + * Get properties of a supplier order object + * + * Return an array with supplier order information + * + * @param int $id ID of supplier order + * @return array|mixed data without useless information + * + * @throws RestException + */ + function get($id) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->lire) { + throw new RestException(401); + } + + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Supplier order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->order); + } + + /** + * List orders + * + * Get a list of supplier orders + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter orders of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i} + * @param string $status Filter by order status : draft | validated | approved | running | received_start | received_end | cancelled | refused + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')" + * @return array Array of order objects + * + * @throws RestException + */ + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') { + global $db, $conf; + + $obj_ret = array(); + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; + + // If the internal user must only see his customers, force searching by him + $search_sale = 0; + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT t.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as t"; + + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + + $sql.= ' WHERE t.entity IN ('.getEntity('supplier_order').')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + + // Filter by status + if ($status == 'draft') $sql.= " AND t.fk_statut IN (0)"; + if ($status == 'validated') $sql.= " AND t.fk_statut IN (1)"; + if ($status == 'approved') $sql.= " AND t.fk_statut IN (2)"; + if ($status == 'running') $sql.= " AND t.fk_statut IN (3)"; + if ($status == 'received_start') $sql.= " AND t.fk_statut IN (4)"; + if ($status == 'received_end') $sql.= " AND t.fk_statut IN (5)"; + if ($status == 'cancelled') $sql.= " AND t.fk_statut IN (6,7)"; + if ($status == 'refused') $sql.= " AND t.fk_statut IN (9)"; + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + if ($result) + { + $i = 0; + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + while ($i < $min) + { + $obj = $db->fetch_object($result); + $order_static = new CommandeFournisseur($db); + if($order_static->fetch($obj->rowid)) { + $obj_ret[] = $this->_cleanObjectDatas($order_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve supplier order list : '.$db->lasterror()); + } + if( ! count($obj_ret)) { + throw new RestException(404, 'No supplier order found'); + } + return $obj_ret; + } + + /** + * Create supplier order object + * + * @param array $request_data Request datas + * @return int ID of supplier order + */ + function post($request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->creer) { + throw new RestException(401, "Insuffisant rights"); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach($request_data as $field => $value) { + $this->order->$field = $value; + } + if(! array_keys($request_data,'date')) { + $this->order->date = dol_now(); + } + /* We keep lines as an array + if (isset($request_data["lines"])) { + $lines = array(); + foreach ($request_data["lines"] as $line) { + array_push($lines, (object) $line); + } + $this->order->lines = $lines; + }*/ + + if ($this->order->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating order", array_merge(array($this->order->error), $this->order->errors)); + } + return $this->order->id; + } + + /** + * Update supplier order + * + * @param int $id Id of supplier order to update + * @param array $request_data Datas + * @return int + */ + function put($id, $request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->creer) { + throw new RestException(401); + } + + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Supplier order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + foreach($request_data as $field => $value) { + if ($field == 'id') continue; + $this->order->$field = $value; + } + + if($this->order->update($id, DolibarrApiAccess::$user)) + return $this->get ($id); + + return false; + } + + /** + * Delete supplier order + * + * @param int $id Supplier order ID + * @return type + */ + function delete($id) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->supprimer) { + throw new RestException(401); + } + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Supplier order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if( $this->order->delete(DolibarrApiAccess::$user) < 0) + { + throw new RestException(500); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Supplier order deleted' + ) + ); + } + + + /** + * Validate an order + * + * @param int $id Order ID + * @param int $idwarehouse Warehouse ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "idwarehouse": 0, + * "notrigger": 0 + * } + */ + function validate($id, $idwarehouse=0, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->creer) { + throw new RestException(401); + } + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->order->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Order: '.$this->order->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Order validated (Ref='.$this->order->ref.')' + ) + ); + } + + /** + * Clean sensible object datas + * + * @param Object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) { + + $object = parent::_cleanObjectDatas($object); + + unset($object->rowid); + + return $object; + } + + /** + * Validate fields before create or update object + * + * @param array $data Datas to validate + * @return array + * + * @throws RestException + */ + function _validate($data) + { + $order = array(); + foreach (SupplierOrders::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $order[$field] = $data[$field]; + } + return $order; + } +} From f9442c10924d5c9c5a63abbfc8333bd748ff8c88 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 11:10:00 +0200 Subject: [PATCH 02/14] Fix box activity --- htdocs/core/boxes/box_activity.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 8d8b2962688..ae3e270101e 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -83,17 +83,17 @@ class box_activity extends ModeleBoxes $cachetime = 3600; $fileid = '-e'.$conf->entity.'-u'.$user->id.'-s'.$user->societe_id.'-r'.($user->rights->societe->client->voir?'1':'0').'.cache'; $now = dol_now(); - $nbofyears=2; + $nbofperiod=3; - if (! empty($conf->global->MAIN_BOX_ACTIVITY_DURATION)) $nbofyears=$conf->global->MAIN_BOX_ACTIVITY_DURATION; - $textHead = $langs->trans("Activity").' - '.$langs->trans("LastXMonthRolling", $nbofyears*12); + if (! empty($conf->global->MAIN_BOX_ACTIVITY_DURATION)) $nbofperiod=$conf->global->MAIN_BOX_ACTIVITY_DURATION; + $textHead = $langs->trans("Activity").' - '.$langs->trans("LastXMonthRolling", $nbofperiod); $this->info_box_head = array( 'text' => $textHead, 'limit'=> dol_strlen($textHead), ); // compute the year limit to show - $tmpdate= dol_time_plus_duree(dol_now(), -1*$nbofyears, "y"); + $tmpdate= dol_time_plus_duree(dol_now(), -1*$nbofperiod, "m"); $cumuldata = array(); @@ -103,6 +103,7 @@ class box_activity extends ModeleBoxes include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $facturestatic=new Facture($db); + // part 1 $cachedir = DOL_DATA_ROOT.'/facture/temp'; $filename = '/boxactivity-invoice'.$fileid; @@ -189,6 +190,7 @@ class box_activity extends ModeleBoxes ); } + // part 2 $cachedir = DOL_DATA_ROOT.'/facture/temp'; $filename = '/boxactivity-invoice2'.$fileid; From bfb904557f8a96b424c1046de8157dcc100bf854 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 12:06:12 +0200 Subject: [PATCH 03/14] Fix include fails --- ChangeLog | 8 +++++--- htdocs/websites/index.php | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2417a7db682..bdc39167310 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,9 +4,11 @@ English Dolibarr ChangeLog ***** ChangeLog for 6.0.0 compared to 5.0.* ***** -NEW: Add experimental BlockeLog module (to log business events in a non reversible log file). NEW: Add a payment module for Stripe. -NEW: Add module "Product variant" (like red, blue for the product shoes) +NEW: Add "Non Reversible Logs" module as experimental (to log business events in a non reversible log file). +NEW: Add module "Product variant" as experimental (like red, blue for the product shoes) +NEW: Add module "Website" as experimental +NEW: Add module "Module Builder" as experimental NEW: Accountancy - Activate multi-journal & Add journal_label to database (FEC) NEW: Add a tracking id into mass emailing. NEW: Tax system more compatible with the new tax roollout in India (IGST / CGST / SGST). @@ -115,7 +117,7 @@ NEW: Add hook "formatNotificationMessage" NEW: Add index and constraints keys on supplier proposal detail table NEW: Add phpunit to check the engine is defined into sql create files. NEW: Add project and Hook to Loan -NEW: Add REST API to push a file. +NEW: Add more REST API (API to push a file, to manage supplier orders, to validate invoices) NEW: Allow extrafields list select to be dependands on other standard list and not only other extrafields list NEW: Architecture to manage search criteria persistance (using save_lastsearch_values=1 on exit links and restore_lastsearch_values=1 in entry links) NEW: data files are now also parsed by phpunit for sql syntax diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 9fbd6e6a4e0..1881ffd95a2 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -568,7 +568,7 @@ if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage $tplcontent =''; $tplcontent.= " Date: Fri, 28 Jul 2017 12:07:05 +0200 Subject: [PATCH 04/14] Revert "Fix include fails" This reverts commit bfb904557f8a96b424c1046de8157dcc100bf854. --- ChangeLog | 8 +++----- htdocs/websites/index.php | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index bdc39167310..2417a7db682 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,11 +4,9 @@ English Dolibarr ChangeLog ***** ChangeLog for 6.0.0 compared to 5.0.* ***** +NEW: Add experimental BlockeLog module (to log business events in a non reversible log file). NEW: Add a payment module for Stripe. -NEW: Add "Non Reversible Logs" module as experimental (to log business events in a non reversible log file). -NEW: Add module "Product variant" as experimental (like red, blue for the product shoes) -NEW: Add module "Website" as experimental -NEW: Add module "Module Builder" as experimental +NEW: Add module "Product variant" (like red, blue for the product shoes) NEW: Accountancy - Activate multi-journal & Add journal_label to database (FEC) NEW: Add a tracking id into mass emailing. NEW: Tax system more compatible with the new tax roollout in India (IGST / CGST / SGST). @@ -117,7 +115,7 @@ NEW: Add hook "formatNotificationMessage" NEW: Add index and constraints keys on supplier proposal detail table NEW: Add phpunit to check the engine is defined into sql create files. NEW: Add project and Hook to Loan -NEW: Add more REST API (API to push a file, to manage supplier orders, to validate invoices) +NEW: Add REST API to push a file. NEW: Allow extrafields list select to be dependands on other standard list and not only other extrafields list NEW: Architecture to manage search criteria persistance (using save_lastsearch_values=1 on exit links and restore_lastsearch_values=1 in entry links) NEW: data files are now also parsed by phpunit for sql syntax diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 1881ffd95a2..9fbd6e6a4e0 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -568,7 +568,7 @@ if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage $tplcontent =''; $tplcontent.= " Date: Fri, 28 Jul 2017 12:37:52 +0200 Subject: [PATCH 05/14] Module website not stable enough --- htdocs/core/modules/modWebsites.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modWebsites.class.php b/htdocs/core/modules/modWebsites.class.php index 57abe371314..f3564c31367 100644 --- a/htdocs/core/modules/modWebsites.class.php +++ b/htdocs/core/modules/modWebsites.class.php @@ -50,7 +50,7 @@ class modWebsites extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "Enable to build and serve public websites with CMS features"; - $this->version = 'experimental'; // 'experimental' or 'dolibarr' or version + $this->version = 'development'; // 'experimental' or 'dolibarr' or version // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) From 25c5ed8f7232d96d020898580bda8c2e050e74f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 18:09:38 +0200 Subject: [PATCH 06/14] Fix for compatibility --- htdocs/core/lib/ajax.lib.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 705bcf6deab..76a1458b913 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -46,6 +46,12 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt { if (empty($minLength)) $minLength=1; + $dataforrenderITem='ui-autocomplete'; + $dataforitem='ui-autocomplete-item'; + // Allow two constant to use other values for backward compatibility + if (defined('JS_QUERY_AUTOCOMPLETE_RENDERITEM')) $dataforrenderITem=constant('JS_QUERY_AUTOCOMPLETE_RENDERITEM'); + if (defined('JS_QUERY_AUTOCOMPLETE_ITEM')) $dataforitem=constant('JS_QUERY_AUTOCOMPLETE_ITEM'); + // Input search_htmlname is original field // Input htmlname is a second input field used when using ajax autocomplete. $script = ''; @@ -185,10 +191,10 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt $("#search_'.$htmlname.'").trigger("change"); // We have changed value of the combo select, we must be sure to trigger all js hook binded on this event. This is required to trigger other javascript change method binded on original field by other code. } ,delay: 500 - }).data("ui-autocomplete")._renderItem = function( ul, item ) { + }).data("'.$dataforrenderITem.'")._renderItem = function( ul, item ) { return $("
  • ") - .data( "ui-autocomplete-item", item ) // jQuery UI > 1.10.0 + .data( "'.$dataforitem.'", item ) // jQuery UI > 1.10.0 .append( \'\' + item.label + "" ) .appendTo(ul); }; From 5e17c2efb90cbdd0d6f3bb90529a15714cb489c6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 23:32:55 +0200 Subject: [PATCH 07/14] Fix into filters of time consumed --- htdocs/core/lib/project.lib.php | 4 +++ htdocs/projet/activity/perday.php | 43 ++++++++++++++++++++++----- htdocs/projet/activity/perweek.php | 47 ++++++++++++++++++++++++------ htdocs/projet/list.php | 4 +-- 4 files changed, 79 insertions(+), 19 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index c3583e72ac8..366413c376f 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -629,9 +629,11 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print ''."\n"; // User + /* print ''; print $fuser->getNomUrl(1, 'withproject', 'time'); print ''; + */ // Ref print ''; @@ -835,9 +837,11 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ print ''."\n"; // User + /* print ''; print $fuser->getNomUrl(1, 'withproject', 'time'); print ''; + */ // Ref print ''; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index a7b243dd338..7b1f50bb50c 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -64,6 +64,7 @@ $day=GETPOST('reday')?GETPOST('reday'):(GETPOST("day","int")?GETPOST("day","int" $day = (int) $day; $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); +$search_categ=GETPOST("search_categ",'alpha'); $search_usertoprocessid=GETPOST('search_usertoprocessid', 'int'); $search_task_ref=GETPOST('search_task_ref', 'alpha'); $search_task_label=GETPOST('search_task_label', 'alpha'); @@ -100,13 +101,14 @@ $object=new Task($db); if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $action = ''; + $search_categ=''; $search_usertoprocessid = ''; $search_task_ref = ''; $search_task_label = ''; $search_project_ref = ''; $search_thirdparty = ''; } -if (GETPOST("button_search_x") || GETPOST("button_search.x") || GETPOST("button_search")) +if (GETPOST("button_search_x",'alpha') || GETPOST("button_search.x",'alpha') || GETPOST("button_search",'alpha')) { $action = ''; } @@ -394,15 +396,41 @@ print ''; print '
    '; +$moreforfilter=''; + +// Filter on categories +/*if (! empty($conf->categorie->enabled)) +{ + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $moreforfilter.='
    '; + $moreforfilter.=$langs->trans('ProjectCategories'). ': '; + $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300'); + $moreforfilter.='
    '; +}*/ + +// If the user can view user other than himself +$moreforfilter.='
    '; +$moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; +$includeonly='hierachyme'; +if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); +$moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:$usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfilter.='
    '; + +if (! empty($moreforfilter)) +{ + print '
    '; + print $moreforfilter; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
    '; +} + + print '
    '; print ''."\n"; print ''; -print ''; print ''; print ''; print ''; @@ -422,7 +450,6 @@ print ''; print "\n"; print ''; -print ''; print ''; print ''; print ''; @@ -454,7 +481,7 @@ if (count($tasksarray) > 0) } else { - print ''; + print ''; } print "
    '; -$usersettoshow='hierarchyme'; -if ($user->rights->projet->all->lire) $usersettoshow=''; -print $form->select_dolusers($usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $usersettoshow, 0, 0, 0, 1, '', 0, '', 'maxwidth150'); -print '
    '.$langs->trans("User").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("ProjectRef").'
    '.$langs->trans("NoTasks").'
    '.$langs->trans("NoTasks").'
    "; print '
    '; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 5f3e9b1aa20..3410ba1d949 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -65,6 +65,7 @@ $day=GETPOST('reday')?GETPOST('reday','int'):(GETPOST("day")?GETPOST("day","int" $day = (int) $day; $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); +$search_categ=GETPOST("search_categ",'alpha'); $search_usertoprocessid=GETPOST('search_usertoprocessid', 'int'); $search_task_ref=GETPOST('search_task_ref', 'alpha'); $search_task_label=GETPOST('search_task_label', 'alpha'); @@ -113,13 +114,14 @@ $object=new Task($db); if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $action = ''; + $search_categ=''; $search_usertoprocessid = ''; $search_task_ref = ''; $search_task_label = ''; $search_project_ref = ''; $search_thirdparty = ''; } -if (GETPOST("button_search_x") || GETPOST("button_search.x") || GETPOST("button_search")) +if (GETPOST("button_search_x",'alpha') || GETPOST("button_search.x",'alpha') || GETPOST("button_search",'alpha')) { $action = ''; } @@ -313,6 +315,7 @@ $morewherefilter=''; if ($search_task_ref) $morewherefilter.=natural_search("t.ref", $search_task_ref); if ($search_task_label) $morewherefilter.=natural_search("t.label", $search_task_label); if ($search_thirdparty) $morewherefilter.=natural_search("s.nom", $search_thirdparty); + $tasksarray=$taskstatic->getTasksArray(0, 0, ($project->id?$project->id:0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter); // We want to see all task of opened project i am allowed to see, not only mine. Later only mine will be editable later. $projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, 0, ($project->id?$project->id:0), 0, $onlyopenedproject); $tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($project->id?$project->id:0), 0, $onlyopenedproject); @@ -387,15 +390,42 @@ print ''; print '
    '; +$moreforfilter=''; + +// Filter on categories +/* +if (! empty($conf->categorie->enabled)) +{ + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $moreforfilter.='
    '; + $moreforfilter.=$langs->trans('ProjectCategories'). ': '; + $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300'); + $moreforfilter.='
    '; +}*/ + +// If the user can view user other than himself +$moreforfilter.='
    '; +$moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; +$includeonly='hierachyme'; +if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); +$moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:$usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfilter.='
    '; + +if (! empty($moreforfilter)) +{ + print '
    '; + print $moreforfilter; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
    '; +} + + print '
    '; print ''."\n"; print ''; -print ''; print ''; print ''; print ''; @@ -416,7 +446,6 @@ print ''; print "\n"; print ''; -print ''; print ''; print ''; print ''; @@ -453,7 +482,7 @@ if (count($tasksarray) > 0) $level=0; projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask); - $colspan=8; + $colspan=7; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) $colspan++; print ' @@ -470,7 +499,7 @@ if (count($tasksarray) > 0) } else { - print ''; + print ''; } print "
    '; -$usersettoshow='hierarchyme'; -if ($user->rights->projet->all->lire) $usersettoshow=''; -print $form->select_dolusers($usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $usersettoshow, 0, 0, 0, 1, '', 0, '', 'maxwidth150'); -print '
    '.$langs->trans("User").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("ProjectRef").'
    '.$langs->trans("NoTasks").'
    '.$langs->trans("NoTasks").'
    "; print '
    '; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 1bf65decd71..9e2971195e3 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -371,6 +371,7 @@ llxHeader("", $title, $help_url); $param=''; if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; +if ($search_all != '') $param.='&search_all='.$search_all; if ($search_sday) $param.='&search_sday='.$search_sday; if ($search_smonth) $param.='&search_smonth='.$search_smonth; if ($search_syear) $param.='&search_syear=' .$search_syear; @@ -378,7 +379,6 @@ if ($search_eday) $param.='&search_eday='.$search_eday; if ($search_emonth) $param.='&search_emonth='.$search_emonth; if ($search_eyear) $param.='&search_eyear=' .$search_eyear; if ($socid) $param.='&socid='.$socid; -if ($search_all != '') $param.='&search_all='.$search_all; if ($search_ref != '') $param.='&search_ref='.$search_ref; if ($search_label != '') $param.='&search_label='.$search_label; if ($search_societe != '') $param.='&search_societe='.$search_societe; @@ -451,7 +451,7 @@ if (! empty($conf->categorie->enabled)) // If the user can view user other than himself $moreforfilter.='
    '; $moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; -$includeonly=''; +$includeonly='hierachyme'; if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); $moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:'', 'search_project_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200'); $moreforfilter.='
    '; From af63dc76c1c4d00f4e115e3f3ae6fd27cbbfefcf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 23:46:11 +0200 Subject: [PATCH 08/14] Fix flex problems --- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 7bd3d913782..cd2c0f95582 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2805,7 +2805,7 @@ div.tabBar .noborder { } .boxstats { padding: 3px; - width: 105px; + width: 103px; } .boxstats130 { width: 160px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b190a3fad67..cf787f09071 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2889,7 +2889,7 @@ div .tdtop { } .boxstats { padding: 3px; - width: 105px; + width: 100px; } .boxstats130 { width: 135px; From 8b82fc3c708ccb03b2fd1303ec5c3444b86646be Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 00:28:41 +0200 Subject: [PATCH 09/14] Fix project edition on loan menu Fix translation on profit view of projects. --- htdocs/loan/card.php | 36 +++++++++++++++++++----------------- htdocs/loan/document.php | 34 ++++++++++++++++++++++++++++++++-- htdocs/loan/info.php | 34 ++++++++++++++++++++++++++++++++-- htdocs/loan/note.php | 34 ++++++++++++++++++++++++++++++++-- htdocs/projet/element.php | 32 ++++++++++++++++---------------- 5 files changed, 131 insertions(+), 39 deletions(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 29cea1eb019..4f61aa833bf 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -41,6 +41,8 @@ $action=GETPOST('action','aZ09'); $confirm=GETPOST('confirm'); $cancel=GETPOST('cancel','alpha'); +$projectid = GETPOST('projectid','int'); + // Security check $socid = GETPOST('socid','int'); if ($user->societe_id) $socid=$user->societe_id; @@ -133,7 +135,7 @@ if (empty($reshook)) $object->rate = $rate; $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); - $object->fk_project = GETPOST('fk_project'); + $object->fk_project = GETPOST('projectid','int'); $accountancy_account_capital = GETPOST('accountancy_account_capital'); $accountancy_account_insurance = GETPOST('accountancy_account_insurance'); @@ -215,7 +217,7 @@ if (empty($reshook)) if ($action == 'classin' && $user->rights->loan->write) { $object->fetch($id); - $result = $object->setProject(GETPOST('projectid')); + $result = $object->setProject($projectid); if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); } @@ -309,7 +311,7 @@ if ($action == 'create') print ''.$langs->trans("Project").''; - $numproject=$formproject->select_projects(-1,GETPOST("fk_project"),'fk_project',16,0,1,1); + $numproject=$formproject->select_projects(-1, $projectid, 'projectid', 16, 0, 1, 1); print ''; } @@ -443,21 +445,21 @@ if ($id > 0) { $langs->load("projects"); $morehtmlref.='
    '.$langs->trans('Project') . ' '; - if ($user->rights->commande->creer) + if ($user->rights->loan->write) { - if ($action != 'classify') - $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
    '; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
    '; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } + if ($action != 'classify') + $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='
    '; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.='
    '; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } } else { if (! empty($object->fk_project)) { $proj = new Project($db); diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php index f4f490a146a..b43261d2b9d 100644 --- a/htdocs/loan/document.php +++ b/htdocs/loan/document.php @@ -89,8 +89,38 @@ if ($object->id) $morehtmlref='
    '; // Ref loan - $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1); + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
    ' . $langs->trans('Project') . ' : '; + if ($user->rights->loan->write) { + //if ($action != 'classify') + // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
    '; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
    '; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } $morehtmlref.='
    '; $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php index 73bb1c1f984..96da6182da6 100644 --- a/htdocs/loan/info.php +++ b/htdocs/loan/info.php @@ -57,8 +57,38 @@ dol_fiche_head($head, 'info', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
    '; // Ref loan -$morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1); -$morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', null, null, '', 1); +$morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1); +$morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1); +// Project +if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
    ' . $langs->trans('Project') . ' : '; + if ($user->rights->loan->write) { + //if ($action != 'classify') + // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
    '; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
    '; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } +} $morehtmlref.='
    '; $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index 4b76cad1d6d..5f435444f32 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -74,8 +74,38 @@ if ($id > 0) $morehtmlref='
    '; // Ref loan - $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1); + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
    ' . $langs->trans('Project') . ' : '; + if ($user->rights->loan->write) { + //if ($action != 'classify') + // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
    '; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
    '; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } $morehtmlref.='
    '; $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 93e15f2fe77..bda8d793840 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -336,7 +336,7 @@ $listofreferent=array( 'table'=>'fichinter', 'datefieldname'=>'date_valid', 'disableamount'=>0, - 'margin'=>'minus', + 'margin'=>'minus', 'urlnew'=>DOL_URL_ROOT.'/fichinter/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid, 'lang'=>'interventions', 'buttonnew'=>'AddIntervention', @@ -417,9 +417,9 @@ $listofreferent=array( 'lang'=>'compta', 'buttonnew'=>'AddSocialContribution', 'testnew'=>$user->rights->tax->charges->lire, - 'test'=>$conf->tax->enabled && $user->rights->tax->charges->lire), + 'test'=>$conf->tax->enabled && $user->rights->tax->charges->lire), 'project_task'=>array( - 'name'=>"TaskTimeValorised", + 'name'=>"TaskTimeSpent", 'title'=>"ListTaskTimeUserProject", 'class'=>'Task', 'margin'=>'minus', @@ -573,7 +573,7 @@ foreach ($listofreferent as $key => $value) if ($tablename != 'expensereport_det' && method_exists($element, 'fetch_thirdparty')) $element->fetch_thirdparty(); if ($tablename == 'don' || $tablename == 'chargesociales') $total_ht_by_line=$element->amount; elseif ($tablename == 'stock_mouvement') $total_ht_by_line=$element->price*abs($element->qty); - else if($tablename == 'fichinter') $total_ht_by_line=$element->getAmount(); + else if($tablename == 'fichinter') $total_ht_by_line=$element->getAmount(); elseif ($tablename == 'projet_task') { if ($idofelementuser) @@ -598,7 +598,7 @@ foreach ($listofreferent as $key => $value) if ($qualifiedfortotal) $total_ht = $total_ht + $total_ht_by_line; if ($tablename == 'don' || $tablename == 'chargesociales') $total_ttc_by_line=$element->amount; - else if($tablename == 'fichinter') $total_ttc_by_line=$element->getAmount(); + else if($tablename == 'fichinter') $total_ttc_by_line=$element->getAmount(); elseif ($tablename == 'stock_mouvement') $total_ttc_by_line=$element->price*abs($element->qty); elseif ($tablename == 'projet_task') { @@ -629,7 +629,7 @@ foreach ($listofreferent as $key => $value) $total_ttc = -$total_ttc; } - switch ($classname) { + /*switch ($classname) { case 'FactureFournisseur': $newclassname = 'SupplierInvoice'; break; @@ -653,12 +653,12 @@ foreach ($listofreferent as $key => $value) break; default: $newclassname = $classname; - } + }*/ $var = ! $var; print ''; // Module - print ''.$langs->trans($newclassname).''; + print ''.$name.''; // Nb print ''.$i.''; // Amount HT @@ -711,7 +711,7 @@ foreach ($listofreferent as $key => $value) $idtofilterthirdparty=0; $array_of_element_linkable_with_different_thirdparty = array('facture_fourn', 'commande_fournisseur'); - if (! in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) + if (! in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) { $idtofilterthirdparty=$object->thirdparty->id; if (! empty($conf->global->PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS)) $idtofilterthirdparty.=','.$conf->global->PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS; @@ -854,7 +854,7 @@ foreach ($listofreferent as $key => $value) print '' . img_picto($langs->trans('Unlink'), 'editdelete') . ''; } print "\n"; - + // Ref print ''; if ($tablename == 'expensereport_det') @@ -922,7 +922,7 @@ foreach ($listofreferent as $key => $value) print dol_print_date($element->datep,'dayhour'); if ($element->datef && $element->datef > $element->datep) print " - ".dol_print_date($element->datef,'dayhour'); } - else if (in_array($tablename, array('projet_task'))) + else if (in_array($tablename, array('projet_task'))) { $tmpprojtime = $element->getSumOfAmount($elementuser, $dates, $datee); // $element is a task. $elementuser may be empty print ''; @@ -1018,7 +1018,7 @@ foreach ($listofreferent as $key => $value) else { $othermessage=$form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled")); - } + } } else { @@ -1074,8 +1074,8 @@ foreach ($listofreferent as $key => $value) $total_ht_by_third += $total_ht_by_line; $total_ttc_by_third += $total_ttc_by_line; - - $total_time = $total_time + $total_time_by_line; + + $total_time = $total_time + $total_time_by_line; } if (canApplySubtotalOn($tablename)) @@ -1115,7 +1115,7 @@ foreach ($listofreferent as $key => $value) //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print ''.$langs->trans("TotalHT").' : '.price($total_ht).''; //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print ''.$langs->trans("Total").' : '.price($total_ht).''; print ''; - if (empty($value['disableamount'])) + if (empty($value['disableamount'])) { if ($tablename != 'projet_task' || ! empty($conf->salaries->enabled)) print ''.$langs->trans("TotalHT").' : '.price($total_ht); } @@ -1123,7 +1123,7 @@ foreach ($listofreferent as $key => $value) //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print ''.$langs->trans("TotalTTC").' : '.price($total_ttc).''; //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print ''; print ''; - if (empty($value['disableamount'])) + if (empty($value['disableamount'])) { if ($tablename != 'projet_task' || ! empty($conf->salaries->enabled)) print $langs->trans("TotalTTC").' : '.price($total_ttc); } From cae21d3937684cb77488a4eda2012e30fcde2529 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 01:59:26 +0200 Subject: [PATCH 10/14] Fix in agenda output per user/type (reduce memory usage) --- htdocs/comm/action/pertype.php | 61 ++++++++++++++----------- htdocs/comm/action/peruser.php | 81 ++++++++++++++++++--------------- htdocs/projet/ganttview.php | 42 ++++++++--------- htdocs/theme/eldy/style.css.php | 9 ++++ htdocs/theme/md/style.css.php | 11 +++++ 5 files changed, 120 insertions(+), 84 deletions(-) diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index cd96a4fa8ad..589a2731f1b 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -38,7 +38,7 @@ if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; -$filter = GETPOST("filter",'',3); +$filter = GETPOST("filter",'alpha',3); $filtert = GETPOST("filtert","int",3); $usergroup = GETPOST("usergroup","int",3); //if (! ($usergroup > 0) && ! ($filtert > 0)) $filtert = $user->id; @@ -82,9 +82,9 @@ $month=GETPOST("month","int")?GETPOST("month","int"):date("m"); $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); $day=GETPOST("day","int")?GETPOST("day","int"):date("d"); $pid=GETPOST("projectid","int",3); -$status=GETPOST("status"); -$type=GETPOST("type"); -$maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$status=GETPOST("status",'alpha'); +$type=GETPOST("type",'alpha'); +$maxprint=((GETPOST("maxprint",'int')!='')?GETPOST("maxprint",'int'):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) if (GETPOST('actioncode','array')) { @@ -97,18 +97,18 @@ else } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); -$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth'), GETPOST('dateselectday'), GETPOST('dateselectyear')); +$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth','int'), GETPOST('dateselectday','int'), GETPOST('dateselectyear','int')); if ($dateselect > 0) { - $day=GETPOST('dateselectday'); - $month=GETPOST('dateselectmonth'); - $year=GETPOST('dateselectyear'); + $day=GETPOST('dateselectday','int'); + $month=GETPOST('dateselectmonth','int'); + $year=GETPOST('dateselectyear','int'); } $tmp=empty($conf->global->MAIN_DEFAULT_WORKING_HOURS)?'9-18':$conf->global->MAIN_DEFAULT_WORKING_HOURS; $tmparray=explode('-',$tmp); -$begin_h = GETPOST('begin_h')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); -$end_h = GETPOST('end_h')?GETPOST('end_h'):($tmparray[1] != '' ? $tmparray[1] : 18); +$begin_h = GETPOST('begin_h','int')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); +$end_h = GETPOST('end_h','int')?GETPOST('end_h','int'):($tmparray[1] != '' ? $tmparray[1] : 18); if ($begin_h < 0 || $begin_h > 23) $begin_h = 9; if ($end_h < 1 || $end_h > 24) $end_h = 18; if ($end_h <= $begin_h) $end_h = $begin_h + 1; @@ -124,13 +124,13 @@ if (empty($action) && ! isset($_GET['action']) && ! isset($_POST['action'])) $ac if (GETPOST('viewcal') && $action != 'show_day' && $action != 'show_week' && $action != 'show_peruser') { $action='show_month'; $day=''; } // View by month -if (GETPOST('viewweek') || $action == 'show_week') { +if (GETPOST('viewweek','alpha') || $action == 'show_week') { $action='show_week'; $week=($week?$week:date("W")); $day=($day?$day:date("d")); } // View by week -if (GETPOST('viewday') || $action == 'show_day') { +if (GETPOST('viewday','alpha') || $action == 'show_day') { $action='show_day'; $day=($day?$day:date("d")); } // View by day -if (GETPOST('viewyear') || $action == 'show_year') { +if (GETPOST('viewyear','alpha') || $action == 'show_year') { $action='show_year'; } // View by year @@ -161,12 +161,12 @@ if ($action =='delete_action') * View */ -$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; -llxHeader('',$langs->trans("Agenda"),$help_url); - $form=new Form($db); $companystatic=new Societe($db); +$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; +llxHeader('',$langs->trans("Agenda"),$help_url); + $now=dol_now(); $nowarray=dol_getdate($now); $nowyear=$nowarray['year']; @@ -456,11 +456,14 @@ if ($resql) continue; } + $datep=$db->jdate($obj->datep); + $datep2=$db->jdate($obj->datep2); + // Create a new object action $event=new ActionComm($db); $event->id=$obj->id; - $event->datep=$db->jdate($obj->datep); // datep and datef are GMT date - $event->datef=$db->jdate($obj->datep2); + $event->datep=$datep; // datep and datef are GMT date + $event->datef=$datep2; $event->type_code=$obj->code; $event->type_color=$obj->color; //$event->libelle=$obj->label; // deprecated @@ -469,7 +472,6 @@ if ($resql) //$event->author->id=$obj->fk_user_author; // user id of creator $event->authorid=$obj->fk_user_author; // user id of creator $event->userownerid=$obj->fk_user_action; // user id of owner - $event->fetch_userassigned(); // This load $event->userassigned $event->priority=$obj->priority; $event->fulldayevent=$obj->fulldayevent; $event->location=$obj->location; @@ -487,15 +489,15 @@ if ($resql) // They are date start and end of action but modified to not be outside calendar view. if ($event->percentage <= 0) { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } else - { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + { + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } // Define ponctual property if ($event->date_start_in_calendar == $event->date_end_in_calendar) @@ -508,10 +510,14 @@ if ($resql) $event->date_start_in_calendar >= $lastdaytoshow) { // This record is out of visible range + unset($event); } else { - if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; + //print $i.' - '.dol_print_date($this->date_start_in_calendar, 'dayhour').' - '.dol_print_date($this->date_end_in_calendar, 'dayhour').'
    '."\n"; + $event->fetch_userassigned(); // This load $event->userassigned + + if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; if ($event->date_end_in_calendar >= $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow - 1); // Add an entry in actionarray for each day @@ -928,6 +934,7 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s } } + // Now output $casesX for ($h = $begin_h; $h < $end_h; $h++) { $color1='';$color2=''; diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 7453b84d477..364e63d8a1b 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -38,7 +38,7 @@ if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; -$filter = GETPOST("filter",'',3); +$filter = GETPOST("filter",'alpha',3); $filtert = GETPOST("filtert","int",3); $usergroup = GETPOST("usergroup","int",3); //if (! ($usergroup > 0) && ! ($filtert > 0)) $filtert = $user->id; @@ -82,9 +82,9 @@ $month=GETPOST("month","int")?GETPOST("month","int"):date("m"); $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); $day=GETPOST("day","int")?GETPOST("day","int"):date("d"); $pid=GETPOST("projectid","int",3); -$status=GETPOST("status"); -$type=GETPOST("type"); -$maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$status=GETPOST("status",'alpha'); +$type=GETPOST("type",'alpha'); +$maxprint=((GETPOST("maxprint",'int')!='')?GETPOST("maxprint",'int'):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) if (GETPOST('actioncode','array')) { @@ -96,26 +96,26 @@ else $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); -$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth'), GETPOST('dateselectday'), GETPOST('dateselectyear')); +$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth','int'), GETPOST('dateselectday','int'), GETPOST('dateselectyear','int')); if ($dateselect > 0) { - $day=GETPOST('dateselectday'); - $month=GETPOST('dateselectmonth'); - $year=GETPOST('dateselectyear'); + $day=GETPOST('dateselectday','int'); + $month=GETPOST('dateselectmonth','int'); + $year=GETPOST('dateselectyear','int'); } $tmp=empty($conf->global->MAIN_DEFAULT_WORKING_HOURS)?'9-18':$conf->global->MAIN_DEFAULT_WORKING_HOURS; $tmparray=explode('-',$tmp); -$begin_h = GETPOST('begin_h')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); -$end_h = GETPOST('end_h')?GETPOST('end_h'):($tmparray[1] != '' ? $tmparray[1] : 18); +$begin_h = GETPOST('begin_h','int')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); +$end_h = GETPOST('end_h','int')?GETPOST('end_h','int'):($tmparray[1] != '' ? $tmparray[1] : 18); if ($begin_h < 0 || $begin_h > 23) $begin_h = 9; if ($end_h < 1 || $end_h > 24) $end_h = 18; if ($end_h <= $begin_h) $end_h = $begin_h + 1; $tmp=empty($conf->global->MAIN_DEFAULT_WORKING_DAYS)?'1-5':$conf->global->MAIN_DEFAULT_WORKING_DAYS; $tmparray=explode('-',$tmp); -$begin_d = GETPOST('begin_d')?GETPOST('begin_d','int'):($tmparray[0] != '' ? $tmparray[0] : 1); -$end_d = GETPOST('end_d')?GETPOST('end_d'):($tmparray[1] != '' ? $tmparray[1] : 5); +$begin_d = GETPOST('begin_d','int')?GETPOST('begin_d','int'):($tmparray[0] != '' ? $tmparray[0] : 1); +$end_d = GETPOST('end_d','int')?GETPOST('end_d','int'):($tmparray[1] != '' ? $tmparray[1] : 5); if ($begin_d < 1 || $begin_d > 7) $begin_d = 1; if ($end_d < 1 || $end_d > 7) $end_d = 7; if ($end_d < $begin_d) $end_d = $begin_d + 1; @@ -123,13 +123,13 @@ if ($end_d < $begin_d) $end_d = $begin_d + 1; if ($status == '' && ! isset($_GET['status']) && ! isset($_POST['status'])) $status=(empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS)?'':$conf->global->AGENDA_DEFAULT_FILTER_STATUS); if (empty($action) && ! isset($_GET['action']) && ! isset($_POST['action'])) $action=(empty($conf->global->AGENDA_DEFAULT_VIEW)?'show_month':$conf->global->AGENDA_DEFAULT_VIEW); -if (GETPOST('viewcal') && $action != 'show_day' && $action != 'show_week' && $action != 'show_peruser') { +if (GETPOST('viewcal','alpha') && $action != 'show_day' && $action != 'show_week' && $action != 'show_peruser') { $action='show_month'; $day=''; } // View by month -if (GETPOST('viewweek') || $action == 'show_week') { +if (GETPOST('viewweek','alpha') || $action == 'show_week') { $action='show_week'; $week=($week?$week:date("W")); $day=($day?$day:date("d")); } // View by week -if (GETPOST('viewday') || $action == 'show_day') { +if (GETPOST('viewday','alpha') || $action == 'show_day') { $action='show_day'; $day=($day?$day:date("d")); } // View by day @@ -160,12 +160,12 @@ if ($action =='delete_action') * View */ -$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; -llxHeader('',$langs->trans("Agenda"),$help_url); - $form=new Form($db); $companystatic=new Societe($db); +$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; +llxHeader('',$langs->trans("Agenda"),$help_url); + $now=dol_now(); $nowarray=dol_getdate($now); $nowyear=$nowarray['year']; @@ -418,14 +418,14 @@ else { // To limit array $sql.= " AND ("; - $sql.= " (a.datep BETWEEN '".$db->idate(dol_mktime(0,0,0,$month,1,$year)-(60*60*24*7))."'"; // Start 7 days before - $sql.= " AND '".$db->idate(dol_mktime(23,59,59,$month,28,$year)+(60*60*24*10))."')"; // End 7 days after + 3 to go from 28 to 31 + $sql.= " (a.datep BETWEEN '".$db->idate($firstdaytoshow-(60*60*24*2))."'"; // Start 2 day before $firstdaytoshow + $sql.= " AND '".$db->idate($lastdaytoshow+(60*60*24*2))."')"; // End 2 day after $lastdaytoshow $sql.= " OR "; - $sql.= " (a.datep2 BETWEEN '".$db->idate(dol_mktime(0,0,0,$month,1,$year)-(60*60*24*7))."'"; - $sql.= " AND '".$db->idate(dol_mktime(23,59,59,$month,28,$year)+(60*60*24*10))."')"; + $sql.= " (a.datep2 BETWEEN '".$db->idate($firstdaytoshow-(60*60*24*2))."'"; + $sql.= " AND '".$db->idate($lastdaytoshow+(60*60*24*2))."')"; $sql.= " OR "; - $sql.= " (a.datep < '".$db->idate(dol_mktime(0,0,0,$month,1,$year)-(60*60*24*7))."'"; - $sql.= " AND a.datep2 > '".$db->idate(dol_mktime(23,59,59,$month,28,$year)+(60*60*24*10))."')"; + $sql.= " (a.datep < '".$db->idate($firstdaytoshow-(60*60*24*2))."'"; + $sql.= " AND a.datep2 > '".$db->idate($lastdaytoshow+(60*60*24*2))."')"; $sql.= ')'; } if ($type) $sql.= " AND ca.id = ".$type; @@ -444,13 +444,14 @@ if ($filtert > 0 || $usergroup > 0) } // Sort on date $sql.= ' ORDER BY fk_user_action, datep'; //fk_user_action -//print $sql; +//print $sql;exit; dol_syslog("comm/action/peruser.php", LOG_DEBUG); $resql=$db->query($sql); if ($resql) { $num = $db->num_rows($resql); + $i=0; while ($i < $num) { @@ -463,11 +464,14 @@ if ($resql) continue; } + $datep=$db->jdate($obj->datep); + $datep2=$db->jdate($obj->datep2); + // Create a new object action $event=new ActionComm($db); $event->id=$obj->id; - $event->datep=$db->jdate($obj->datep); // datep and datef are GMT date - $event->datef=$db->jdate($obj->datep2); + $event->datep=$datep; // datep and datef are GMT date + $event->datef=$datep2; $event->type_code=$obj->code; $event->type_color=$obj->color; //$event->libelle=$obj->label; // deprecated @@ -476,7 +480,6 @@ if ($resql) //$event->author->id=$obj->fk_user_author; // user id of creator $event->authorid=$obj->fk_user_author; // user id of creator $event->userownerid=$obj->fk_user_action; // user id of owner - $event->fetch_userassigned(); // This load $event->userassigned $event->priority=$obj->priority; $event->fulldayevent=$obj->fulldayevent; $event->location=$obj->location; @@ -494,15 +497,15 @@ if ($resql) // They are date start and end of action but modified to not be outside calendar view. if ($event->percentage <= 0) { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } else { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } // Define ponctual property if ($event->date_start_in_calendar == $event->date_end_in_calendar) @@ -515,10 +518,14 @@ if ($resql) $event->date_start_in_calendar >= $lastdaytoshow) { // This record is out of visible range + unset($event); } else { - if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; + //print $i.' - '.dol_print_date($this->date_start_in_calendar, 'dayhour').' - '.dol_print_date($this->date_end_in_calendar, 'dayhour').'
    '."\n"; + $event->fetch_userassigned(); // This load $event->userassigned + + if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; if ($event->date_end_in_calendar >= $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow - 1); // Add an entry in actionarray for each day @@ -548,6 +555,7 @@ if ($resql) $i++; } + $db->free($resql); } else { @@ -869,7 +877,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & $cases1 = array(); // Color first half hour $cases2 = array(); // Color second half hour - $curtime = dol_mktime(0, 0, 0, $month, $day, $year); + $curtime = dol_mktime(0, 0, 0, $month, $day, $year, false, 0); $i=0; $nummytasks=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); $ymd=sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day); @@ -1029,6 +1037,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & } } + // Now output $casesX for ($h = $begin_h; $h < $end_h; $h++) { $color1='';$color2=''; diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 7ec9dcf1a4b..ca3c0ba35e6 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -98,12 +98,12 @@ if ($id > 0 || ! empty($ref)) $param=($mode=='mine'?'&mode=mine':''); - + // Project card - + $linkback = '
    '.$langs->trans("BackToList").''; - + $morehtmlref='
    '; // Title $morehtmlref.=$object->title; @@ -113,29 +113,29 @@ if ($id > 0 || ! empty($ref)) $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'project'); } $morehtmlref.='
    '; - + // Define a complementary filter for search of next/prev ref. if (! $user->rights->projet->all->lire) { $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0); $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")"; } - + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - + + print '
    '; print '
    '; print '
    '; - + print ''; - + // Visibility print ''; - + // Date start - end print ''; - + // Budget print ''; - + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; - + print '
    '.$langs->trans("Visibility").''; if ($object->public) print $langs->trans('SharedProject'); else print $langs->trans('PrivateProject'); print '
    '.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; $start = dol_print_date($object->date_start,'dayhour'); @@ -145,45 +145,45 @@ if ($id > 0 || ! empty($ref)) print ($end?$end:'?'); if ($object->hasDelay()) print img_warning("Late"); print '
    '.$langs->trans("Budget").''; if (strcmp($object->budget_amount, '')) print price($object->budget_amount,'',$langs,1,0,0,$conf->currency); print '
    '; - + print '
    '; print '
    '; print '
    '; print '
    '; - + print ''; - + // Description print ''; - + // Categories if($conf->categorie->enabled) { print '"; } - + print '
    '.$langs->trans("Description").''; print nl2br($object->description); print '
    '.$langs->trans("Categories").''; print $form->showCategories($object->id,'project',1); print "
    '; - + print '
    '; print '
    '; print '
    '; - + print '
    '; - + dol_fiche_end(); } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index cd2c0f95582..801911c0f5f 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3425,6 +3425,15 @@ table.cal_event td.cal_event_right { padding: 4px 4px !important; } cursor:pointer; } +/* ============================================================================== */ +/* Gantt +/* ============================================================================== */ + +td.gtaskname { + overflow: hidden; + text-overflow: ellipsis; +} + /* ============================================================================== */ /* jQuery - jeditable */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index cf787f09071..5768a70bf18 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3508,6 +3508,17 @@ table.cal_event td.cal_event_right { padding: 4px 4px !important; } cursor:pointer; } + +/* ============================================================================== */ +/* Gantt +/* ============================================================================== */ + +td.gtaskname { + overflow: hidden; + text-overflow: ellipsis; +} + + /* ============================================================================== */ /* jQuery - jeditable */ /* ============================================================================== */ From 2a361668398cf44e0cefe49a05d5c30a8511f5d4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 02:11:45 +0200 Subject: [PATCH 11/14] Fix error method on non object --- htdocs/comm/action/card.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 14ab91a2f31..16bb308c966 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -38,11 +38,8 @@ require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; -if (! empty($conf->projet->enabled)) -{ - require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; -} +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $langs->load("companies"); @@ -585,6 +582,8 @@ if ($action == 'mupdate') * View */ +$formproject=new FormProjets($db); + $help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda'; llxHeader('',$langs->trans("Agenda"),$help_url); @@ -786,8 +785,6 @@ if ($action == 'create') // Project if (! empty($conf->projet->enabled)) { - $formproject=new FormProjets($db); - // Projet associe $langs->load("projects"); @@ -1133,8 +1130,6 @@ if ($id > 0) // Project if (! empty($conf->projet->enabled)) { - $formproject=new FormProjets($db); - $langs->load("projects"); print ''.$langs->trans("Project").''; From 837afa0e6560546e9bf92e6ae0820e459a508d24 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 04:07:46 +0200 Subject: [PATCH 12/14] Fix better way to get info for contact/thirdparty on agenda --- htdocs/comm/action/pertype.php | 80 ++++++++++++++++++++++++++----- htdocs/comm/action/peruser.php | 86 ++++++++++++++++++++++++++++------ 2 files changed, 140 insertions(+), 26 deletions(-) diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index 589a2731f1b..b10ab8dc05b 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -30,10 +30,12 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; -if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; @@ -55,7 +57,7 @@ $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page","int"); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $offset = $limit * $page; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="a.datec"; @@ -93,7 +95,7 @@ if (GETPOST('actioncode','array')) } else { - $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); + $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode","alpha")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); @@ -354,7 +356,7 @@ $sql.= ' a.datep2,'; $sql.= ' a.percent,'; $sql.= ' a.fk_user_author,a.fk_user_action,'; $sql.= ' a.transparency, a.priority, a.fulldayevent, a.location,'; -$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype,'; +$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,'; $sql.= ' ca.code, ca.color'; $sql.= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; @@ -477,6 +479,8 @@ if ($resql) $event->location=$obj->location; $event->transparency=$obj->transparency; + $event->fk_project=$obj->fk_project; + $event->socid=$obj->fk_soc; $event->contactid=$obj->fk_contact; //$event->societe->id=$obj->fk_soc; // deprecated @@ -887,11 +891,37 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s } $cases1[$h][$event->id]['string'].=' - '.$event->label; $cases1[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases1[$h][$event->id]['string'].='xxx'; - } $cases1[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases1[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases1[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases1[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } if ($event->date_start_in_calendar < $c && $dateendtouse > $b) { @@ -907,11 +937,37 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s } $cases2[$h][$event->id]['string'].=' - '.$event->label; $cases2[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases2[$h][$event->id]['string'].='xxx'; - } $cases2[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases2[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases2[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases2[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } } else diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 364e63d8a1b..792d4f9760d 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -30,10 +30,12 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; -if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; @@ -55,7 +57,7 @@ $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page","int"); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $offset = $limit * $page; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="a.datec"; @@ -93,9 +95,10 @@ if (GETPOST('actioncode','array')) } else { - $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); + $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode","alpha")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); + $dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth','int'), GETPOST('dateselectday','int'), GETPOST('dateselectyear','int')); if ($dateselect > 0) { @@ -361,7 +364,7 @@ $sql.= ' a.datep2,'; $sql.= ' a.percent,'; $sql.= ' a.fk_user_author,a.fk_user_action,'; $sql.= ' a.transparency, a.priority, a.fulldayevent, a.location,'; -$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype,'; +$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,'; $sql.= ' ca.code, ca.color'; $sql.= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; @@ -485,6 +488,8 @@ if ($resql) $event->location=$obj->location; $event->transparency=$obj->transparency; + $event->fk_project=$obj->fk_project; + $event->socid=$obj->fk_soc; $event->contactid=$obj->fk_contact; //$event->societe->id=$obj->fk_soc; // deprecated @@ -873,6 +878,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & global $theme_datacolor; // Array with a list of different we can use (come from theme) global $cachethirdparties, $cachecontacts, $colorindexused; global $begin_h, $end_h; + global $cache_project, $cache_thirdparty, $cache_contact; $cases1 = array(); // Color first half hour $cases2 = array(); // Color second half hour @@ -988,13 +994,39 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) $cases1[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'hour'); else $cases1[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'dayhour'); } - $cases1[$h][$event->id]['string'].=' - '.$event->label; + if ($event->label) $cases1[$h][$event->id]['string'].=' - '.$event->label; $cases1[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases1[$h][$event->id]['string'].='xxx'; - } $cases1[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases1[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases1[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases1[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } if ($event->date_start_in_calendar < $c && $dateendtouse > $b) { @@ -1008,13 +1040,39 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) $cases2[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'hour'); else $cases2[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'dayhour'); } - $cases2[$h][$event->id]['string'].=' - '.$event->label; + if ($event->label) $cases2[$h][$event->id]['string'].=' - '.$event->label; $cases2[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases2[$h][$event->id]['string'].='xxx'; - } $cases2[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases2[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases2[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases2[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } } else From bb8d4584680282b1f54b27be2c0a4a66d8a57521 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 30 Jul 2017 19:38:12 +0200 Subject: [PATCH 13/14] Fix menu editor --- htdocs/admin/menus/index.php | 11 ++++++----- htdocs/core/lib/treeview.lib.php | 6 +++--- .../template/core/modules/modMyModule.class.php | 6 +++--- htdocs/theme/eldy/style.css.php | 8 +++++++- htdocs/theme/md/style.css.php | 17 +++++++++++++---- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/htdocs/admin/menus/index.php b/htdocs/admin/menus/index.php index 5fb19b0b5ec..c3211fc2d75 100644 --- a/htdocs/admin/menus/index.php +++ b/htdocs/admin/menus/index.php @@ -296,7 +296,7 @@ if ($conf->use_javascript_ajax) //puis tous les elements enfants - $sql = "SELECT m.rowid, m.titre, m.langs, m.mainmenu, m.leftmenu, m.fk_menu, m.fk_mainmenu, m.fk_leftmenu, m.module"; + $sql = "SELECT m.rowid, m.titre, m.langs, m.mainmenu, m.leftmenu, m.fk_menu, m.fk_mainmenu, m.fk_leftmenu, m.position, m.module"; $sql.= " FROM ".MAIN_DB_PREFIX."menu as m"; $sql.= " WHERE menu_handler = '".$db->escape($menu_handler_to_search)."'"; $sql.= " AND entity = ".$conf->entity; @@ -323,6 +323,7 @@ if ($conf->use_javascript_ajax) 'leftmenu'=>$menu['leftmenu'], 'fk_mainmenu'=>$menu['fk_mainmenu'], 'fk_leftmenu'=>$menu['fk_leftmenu'], + 'position'=>$menu['position'], 'entry'=>''; @@ -376,7 +378,6 @@ if ($conf->use_javascript_ajax) print ''; print '
    '. '   '.$titre.''. ''. @@ -344,10 +345,11 @@ if ($conf->use_javascript_ajax) global $tree_recur_alreadyadded; // This var was def into tree_recur - // Appelle de la fonction recursive (ammorce) - // avec recherche depuis la racine. //var_dump($data); - tree_recur($data, $data[0], 0, 'iddivjstree'); // $data[0] is virtual record 'racine' + + // Appelle de la fonction recursive (ammorce) avec recherche depuis la racine. + //tree_recur($data, $data[0], 0, 'iddivjstree', 0, 1); // use this to get info on name and foreign keys of menu entry + tree_recur($data, $data[0], 0, 'iddivjstree', 0, 0); // $data[0] is virtual record 'racine' print '
    '; - foreach($remainingdata as $datar) { $father = array('rowid'=>$datar['rowid'],'title'=>"???",'mainmenu'=>$datar['fk_mainmenu'],'leftmenu'=>$datar['fk_leftmenu'],'fk_mainmenu'=>'','fk_leftmenu'=>''); diff --git a/htdocs/core/lib/treeview.lib.php b/htdocs/core/lib/treeview.lib.php index 944520d04d5..6c66079090a 100644 --- a/htdocs/core/lib/treeview.lib.php +++ b/htdocs/core/lib/treeview.lib.php @@ -182,7 +182,7 @@ function tree_recur($tab, $pere, $rang, $iddivjstree='iddivjstree', $donoresetal //print ' -> A '.$tab[$x]['rowid'].' mainmenu='.$tab[$x]['mainmenu'].' leftmenu='.$tab[$x]['leftmenu'].' fk_mainmenu='.$tab[$x]['fk_mainmenu'].' fk_leftmenu='.$tab[$x]['fk_leftmenu'].'
    '."\n"; $tree_recur_alreadyadded[$tab[$x]['rowid']]=($rang + 1); // And now we search all its sons of lower level - tree_recur($tab,$tab[$x],$rang+1); + tree_recur($tab, $tab[$x], $rang+1, 'iddivjstree', 0, $showfk); print ''; } elseif (! empty($tab[$x]['rowid']) && $tab[$x]['fk_menu'] == -1 && $tab[$x]['fk_mainmenu'] == $pere['mainmenu'] && $tab[$x]['fk_leftmenu'] == $pere['leftmenu']) @@ -206,7 +206,7 @@ function tree_recur($tab, $pere, $rang, $iddivjstree='iddivjstree', $donoresetal print '   '; print $tab[$x]['title']; print ''; - print '  (fk_mainmenu='.$tab[$x]['fk_mainmenu'].' fk_leftmenu='.$tab[$x]['fk_leftmenu'].')'; + print '  (mainmenu='.$tab[$x]['mainmenu'].' leftmenu='.$tab[$x]['leftmenu'].' - fk_mainmenu='.$tab[$x]['fk_mainmenu'].' fk_leftmenu='.$tab[$x]['fk_leftmenu'].')'; print '
    '; print $tab[$x]['buttons']; print '
    '; @@ -219,7 +219,7 @@ function tree_recur($tab, $pere, $rang, $iddivjstree='iddivjstree', $donoresetal $tree_recur_alreadyadded[$tab[$x]['rowid']]=($rang + 1); // And now we search all its sons of lower level //print 'Call tree_recur for x='.$x.' rowid='.$tab[$x]['rowid']." fk_mainmenu pere = ".$tab[$x]['fk_mainmenu']." fk_leftmenu pere = ".$tab[$x]['fk_leftmenu']."
    \n"; - tree_recur($tab,$tab[$x],$rang+1); + tree_recur($tab, $tab[$x], $rang+1, 'iddivjstree', 0, $showfk); print '
  • '; } } diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 3e217618d4a..8f8079b1d46 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -235,7 +235,7 @@ class modMyModule extends DolibarrModules 'leftmenu'=>'', 'url'=>'/mymodule/mymoduleindex.php', 'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'position'=>1000, + 'position'=>1000+$r, 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', @@ -252,7 +252,7 @@ class modMyModule extends DolibarrModules 'leftmenu'=>'mymodule', 'url'=>'/mymodule/myobject_list.php', 'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'position'=>1100, + 'position'=>1000+$r, 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', @@ -264,7 +264,7 @@ class modMyModule extends DolibarrModules 'leftmenu'=>'mymodule', 'url'=>'/mymodule/myobject_page.php?action=create', 'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'position'=>1101, + 'position'=>1000+$r, 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 801911c0f5f..0fa905113ad 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2653,7 +2653,6 @@ div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_se } tr.liste_titre th, tr.liste_titre td, th.liste_titre { -/* border-bottom: 1px solid #; */ border-bottom: 1px solid #888; } tr.liste_titre:first-child th, tr:first-child th.liste_titre { @@ -2779,6 +2778,13 @@ div.tabBar .noborder { border-bottom: 1px solid #ddd; } +ul.noborder li:nth-child(even):not(.liste_titre) { + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; +} /* diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 5768a70bf18..741a08c4ac8 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2623,6 +2623,15 @@ div.pagination li.paginationafterarrows { } */ +ul.noborder li:nth-child(odd):not(.liste_titre) { + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; +} + + /* Set the color for hover lines */ .oddeven:hover, .evenodd:hover, .impair:hover, .pair:hover { @@ -2723,19 +2732,19 @@ tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, tabl { height: 26px !important; } -div.liste_titre, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr +div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr { background: rgb(); font-weight: ; + border-bottom: 1px solid #FDFFFF; color: rgb(); font-family: ; - border-bottom: 1px solid #FDFFFF; text-align: ; } -tr.liste_titre th, tr.liste_titre td, th.liste_titre, form.liste_titre div, div.liste_titre +tr.liste_titre th, tr.liste_titre td, th.liste_titre { - border-bottom: 1px solid #; + border-bottom: 1px solid #aaa; } /* TODO Once title line is moved under title search, make border bottom of all th black and force to whit when it's first tr */ tr:first-child th.liste_titre { From 1897e3cbadf417748970e632b219f6272ccf7181 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 30 Jul 2017 20:43:18 +0200 Subject: [PATCH 14/14] Some fix for better compatibility --- htdocs/main.inc.php | 4 ++-- htdocs/public/test/test_arrays.php | 18 ++++++------------ htdocs/theme/eldy/style.css.php | 5 +++++ htdocs/theme/md/style.css.php | 6 ++++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 090a35d6c83..89b99a61041 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1199,7 +1199,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; if (defined('JS_JQUERY') && constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; - if (! empty($conf->global->MAIN_FEATURES_LEVEL)) + if (! empty($conf->global->MAIN_FEATURES_LEVEL) && ! defined('JS_JQUERY_MIGRATE_DISABLED')) { if (defined('JS_JQUERY_MIGRATE') && constant('JS_JQUERY_MIGRATE')) print ''."\n"; else print ''."\n"; @@ -2002,7 +2002,7 @@ if (! function_exists("llxFooter")) } // Wrapper to manage dropdown - if ($conf->use_javascript_ajax) + if (! empty($conf->use_javascript_ajax) && ! defined('JS_JQUERY_DISABLE_DROPDOWN')) { print "\n\n"; print ' @@ -43,9 +40,6 @@ if (empty($usedolheader)) - - - @@ -74,7 +68,7 @@ else '/includes/pdfmake/vfs_fonts.js' ); */ - + llxHeader('','','','',0,0,$arrayjs,$arraycss); } @@ -92,7 +86,7 @@ This page is a sample of page using tables. It is designed to make test with
    - tablednd
    - +


    Example 0a : Table with div+div+div containg a select that should be overflowed and truncated => Use this to align text or form
    @@ -139,7 +133,7 @@ This page is a sample of page using tables. It is designed to make test with



    Example 1 : Standard table/thead/tbody/tr/th-td (no class pair/impair on td) => Use this if you need the drag and drop for lines or for long result tables
    - + - + - + " id="tablelines3"> @@ -243,7 +237,7 @@ if (! empty($moreforfilter))
    -