From e513ed09f68e61f758b8a01ac88cf15f706faf28 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 14 Nov 2017 14:43:50 +0100 Subject: [PATCH 001/429] Change the way pa_ht is calculated --- htdocs/compta/facture/class/api_invoices.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index eccc537b3b3..d25c4542929 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -452,6 +452,9 @@ class Invoices extends DolibarrApi $request_data->fk_parent_line = 0; } + // calculate pa_ht + $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht); + $updateRes = $this->invoice->addline( $request_data->desc, $request_data->subprice, @@ -475,7 +478,7 @@ class Invoices extends DolibarrApi $id, $request_data->fk_parent_line, $request_data->fk_fournprice, - $request_data->pa_ht, + $marginInfos[0], $request_data->label, $request_data->array_options, $request_data->situation_percent, From 9b2611933d0368fe9ac16bae8eacd1af144d0ce7 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 14 Nov 2017 15:49:09 +0100 Subject: [PATCH 002/429] NEW Create an invoice using an existing order Create an invoice using an existing order using the REST API --- .../facture/class/api_invoices.class.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index d25c4542929..115080811e6 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -217,6 +217,48 @@ class Invoices extends DolibarrApi return $this->invoice->id; } + /** + * Create an invoice using an existing order. + * + * + * @param int $orderid Id of the order + * + * @url POST /createfromorder/{orderid} + * + * @return int + * @throws 400 + * @throws 401 + * @throws 404 + * @throws 405 + */ + function createInvoiceFromOrder($orderid) { + + require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php'; + + if(! DolibarrApiAccess::$user->rights->commande->lire) { + throw new RestException(401); + } + if(! DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + if(empty($orderid)) { + throw new RestException(400, 'Order ID is mandatory'); + } + + $order = new Commande($this->db); + $result = $order->fetch($orderid); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + + $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user); + if( $result < 0) { + throw new RestException(405, $this->invoice->error); + } + $this->invoice->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->invoice); + } + /** * Get lines of an invoice * From 42d1072dee1b3d8a74643ad5139906c82287229e Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Wed, 15 Nov 2017 10:55:39 +0100 Subject: [PATCH 003/429] NEW Tag the order as validated (opened) in the REST API Tag the order as validated (opened) --- htdocs/commande/class/api_orders.class.php | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index e5228185657..eb6e7f82532 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -511,6 +511,45 @@ class Orders extends DolibarrApi return $this->_cleanObjectDatas($this->commande); } + /** + * Tag the order as validated (opened) + * + * Function used when order is reopend after being closed. + * + * @param int $id Id of the order + * + * @url POST {id}/reopen + * + * @return int + * + * @throws 304 + * @throws 400 + * @throws 401 + * @throws 404 + * @throws 405 + */ + function reopen($id) { + + if(! DolibarrApiAccess::$user->rights->commande->creer) { + throw new RestException(401); + } + if(empty($id)) { + throw new RestException(400, 'Order ID is mandatory'); + } + $result = $this->commande->fetch($orderid); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + + $result = $this->commande->set_reopen(DolibarrApiAccess::$user); + if( $result < 0) { + throw new RestException(405, $this->commande->error); + }else if( $result == 0) { + throw new RestException(304); + } + return $result; + } + /** * Close an order (Classify it as "Delivered") * From d97cf63a16f5f9ab7ea8bf1a34de369936b4ea2c Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Wed, 15 Nov 2017 12:14:28 +0100 Subject: [PATCH 004/429] NEW Classify the order as invoiced in the REST API Classify the order as invoiced FIX variable name --- htdocs/commande/class/api_orders.class.php | 38 +++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index eb6e7f82532..3dd19a030a0 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -536,7 +536,7 @@ class Orders extends DolibarrApi if(empty($id)) { throw new RestException(400, 'Order ID is mandatory'); } - $result = $this->commande->fetch($orderid); + $result = $this->commande->fetch($id); if( ! $result ) { throw new RestException(404, 'Order not found'); } @@ -550,6 +550,42 @@ class Orders extends DolibarrApi return $result; } + + /** + * Classify the order as invoiced + * + * @param int $id Id of the order + * @param int $notrigger {@from body} 1=Does not execute triggers, 0= execute triggers {@choice 0,1} + * + * @url POST {id}/setinvoiced + * + * @return int + * + * @throws 400 + * @throws 401 + * @throws 404 + * @throws 405 + */ + function setinvoiced($id,$notrigger=0) { + + if(! DolibarrApiAccess::$user->rights->commande->creer) { + throw new RestException(401); + } + if(empty($id)) { + throw new RestException(400, 'Order ID is mandatory'); + } + $result = $this->commande->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + + $result = $this->commande->classifyBilled(DolibarrApiAccess::$user,$notrigger); + if( $result < 0) { + throw new RestException(400, $this->commande->error); + } + return $result; + } + /** * Close an order (Classify it as "Delivered") * From 8fa7b924d5975f5d69d8571bc31a04dd15acfb5f Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 9 Dec 2017 12:08:50 +0100 Subject: [PATCH 005/429] enhance image using awesome icon --- htdocs/core/lib/functions.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9683517f377..ba842682221 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6245,7 +6245,7 @@ function dol_validElement($element) * Return img flag of country for a language code or country code * * @param string $codelang Language code (en_IN, fr_CA...) or Country code (IN, FR) - * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string HTML img string with flag. */ function picto_from_langcode($codelang, $moreatt = '') @@ -6258,7 +6258,7 @@ function picto_from_langcode($codelang, $moreatt = '') if ($codelang == 'auto') { - return img_picto_common($langs->trans('AutoDetectLang'), 'flags/int.png', $moreatt); + return ''; } $langtocountryflag = array( From ef9468f78a87c77d5365b2d1654c1d9a91ba62f6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Dec 2017 11:48:51 +0100 Subject: [PATCH 006/429] Fix missing field label --- htdocs/webservices/server_supplier_invoice.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/webservices/server_supplier_invoice.php b/htdocs/webservices/server_supplier_invoice.php index ea162ef2a8b..fcfd73270aa 100644 --- a/htdocs/webservices/server_supplier_invoice.php +++ b/htdocs/webservices/server_supplier_invoice.php @@ -139,7 +139,8 @@ $server->wsdl->addComplexType( 'date_modification' => array('name'=>'date_modification','type'=>'xsd:dateTime'), 'date_invoice' => array('name'=>'date_invoice','type'=>'xsd:date'), 'date_term' => array('name'=>'date_modification','type'=>'xsd:date'), - 'type' => array('name'=>'type','type'=>'xsd:int'), + 'label' => array('name'=>'label','type'=>'xsd:date'), + 'type' => array('name'=>'type','type'=>'xsd:int'), 'total_net' => array('name'=>'type','type'=>'xsd:double'), 'total_vat' => array('name'=>'type','type'=>'xsd:double'), 'total' => array('name'=>'type','type'=>'xsd:double'), From 46770178d2320086ade6d5f85620b9e5e3dfb1c0 Mon Sep 17 00:00:00 2001 From: atm-ph Date: Wed, 13 Dec 2017 15:24:09 +0100 Subject: [PATCH 007/429] Fix since jquery 3 we can check all checkbox of credit note options --- htdocs/compta/facture/card.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 04965ddd13d..fd9386672e2 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2534,11 +2534,11 @@ if ($action == 'create') $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3); print $desc; - print '
'; - print '    0 ? 'checked':'').' /> "; - print '
    0 ? 'checked':'').' /> "; - print '
'; - + print '
'; + print '    0 ? 'checked':'').' /> "; + print '
    0 ? 'checked':'').' /> "; + print '
'; + print ''; } } From a2f4afbf88a44b94c236561e04a5d4b10523a92c Mon Sep 17 00:00:00 2001 From: atm-ph Date: Wed, 13 Dec 2017 16:17:22 +0100 Subject: [PATCH 008/429] Fix wrong or missing char for url --- htdocs/compta/facture/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 8563572da7c..4b734a5e7d9 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -552,14 +552,14 @@ if ($resql) if ($search_societe) $param.='&search_societe=' .urlencode($search_societe); if ($search_sale > 0) $param.='&search_sale=' .urlencode($search_sale); if ($search_user > 0) $param.='&search_user=' .urlencode($search_user); - if ($search_product_category > 0) $param.='$search_product_category=' .urlencode($search_product_category); + if ($search_product_category > 0) $param.='&search_product_category=' .urlencode($search_product_category); if ($search_montant_ht != '') $param.='&search_montant_ht='.urlencode($search_montant_ht); if ($search_montant_vat != '') $param.='&search_montant_vat='.urlencode($search_montant_vat); if ($search_montant_localtax1 != '') $param.='&search_montant_localtax1='.urlencode($search_montant_localtax1); if ($search_montant_localtax2 != '') $param.='&search_montant_localtax2='.urlencode($search_montant_localtax2); if ($search_montant_ttc != '') $param.='&search_montant_ttc='.urlencode($search_montant_ttc); if ($search_status != '') $param.='&search_status='.urlencode($search_status); - if ($search_paymentmode > 0) $param.='search_paymentmode='.urlencode($search_paymentmode); + if ($search_paymentmode > 0) $param.='&search_paymentmode='.urlencode($search_paymentmode); if ($show_files) $param.='&show_files=' .$show_files; if ($option) $param.="&option=".$option; if ($optioncss != '') $param.='&optioncss='.$optioncss; From ab558ee5fae5fbbaa92452160e80d8664e83453a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 14 Dec 2017 09:49:55 +0100 Subject: [PATCH 009/429] Update product.php --- htdocs/product/admin/product.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 2757234251d..69355a7f1e8 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -56,7 +56,6 @@ $select_pricing_rules=array( ); if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - $langs->load("admin"); $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY'] = $langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')'; // TODO If this is enabled, price must be hidden when price by qty is enabled, also price for quantity must be used when adding product into order/propal/invoice $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES'] = $langs->trans('MultiPricesAbility') . '+' . $langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')'; } From 24ae3d5879fe81035831894e56cea28f5fb148ab Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 15 Dec 2017 07:04:05 +0100 Subject: [PATCH 010/429] NEW : Add search on date and accounting account in various payment list --- htdocs/compta/bank/various_payment/index.php | 38 +++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/htdocs/compta/bank/various_payment/index.php b/htdocs/compta/bank/various_payment/index.php index 30a8d2d4353..11811d1c6aa 100644 --- a/htdocs/compta/bank/various_payment/index.php +++ b/htdocs/compta/bank/various_payment/index.php @@ -25,6 +25,7 @@ require '../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; @@ -44,6 +45,8 @@ $search_label = GETPOST('search_label','alpha'); $search_amount_deb = GETPOST('search_amount_deb','alpha'); $search_amount_cred = GETPOST('search_amount_cred','alpha'); $search_account = GETPOST('search_account','int'); +$search_date = dol_mktime(0, 0, 0, GETPOST('date_docmonth', 'int'), GETPOST('date_docday', 'int'), GETPOST('date_docyear', 'int')); +$search_accountancy_code = GETPOST("search_accountancy_code"); $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); @@ -80,6 +83,8 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', $search_amount_cred=""; $search_account=''; $typeid=""; + $search_date = ''; + $search_accountancy_code = ''; } /* @@ -89,6 +94,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', llxHeader(); $form = new Form($db); +$formaccounting = new FormAccounting($db); $variousstatic = new PaymentVarious($db); $accountstatic = new Account($db); @@ -102,11 +108,14 @@ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."bank_account as ba ON b.fk_account = ba.row $sql.= " WHERE v.entity IN (".getEntity('payment_various').")"; // Search criteria -if ($search_ref) $sql.=" AND v.rowid=".$search_ref; -if ($search_label) $sql.=natural_search(array('v.label'), $search_label); -if ($search_amount_deb) $sql.=natural_search("v.amount", $search_amount_deb, 1); -if ($search_amount_cred) $sql.=natural_search("v.amount", $search_amount_cred, 1); -if ($search_account > 0) $sql .=" AND b.fk_account=".$search_account; +if ($search_ref) $sql.=" AND v.rowid=".$search_ref; +if ($search_label) $sql.=natural_search(array('v.label'), $search_label); +if ($search_amount_deb) $sql.=natural_search("v.amount", $search_amount_deb, 1); +if ($search_amount_cred) $sql.=natural_search("v.amount", $search_amount_cred, 1); +if ($search_account > 0) $sql.=" AND b.fk_account=".$search_account; +if ($search_date) $sql.=" AND v.datep=".$search_date; +if ($search_accountancy_code) $sql.=" AND v.accountancy_code=".$search_accountancy_code; + if ($filtre) { $filtre=str_replace(":","=",$filtre); $sql .= " AND ".$filtre; @@ -159,7 +168,7 @@ if ($result) print_liste_field_titre("DatePayment",$_SERVER["PHP_SELF"],"v.datep","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre("PaymentMode",$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); if (! empty($conf->banque->enabled)) print_liste_field_titre("BankAccount",$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("AccountAccounting",$_SERVER["PHP_SELF"],"v.accountancy_code","",$param,'align="left"',$sortfield,$sortorder); + if (! empty($conf->accounting->enabled)) print_liste_field_titre("AccountAccounting",$_SERVER["PHP_SELF"],"v.accountancy_code","",$param,'align="left"',$sortfield,$sortorder); print_liste_field_titre("Debit",$_SERVER["PHP_SELF"],"v.amount","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre("Credit",$_SERVER["PHP_SELF"],"v.amount","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); @@ -176,7 +185,11 @@ if ($result) print ''; // Date - print ' '; + print ''; + print '
'; + print $form->select_date($search_date, 'date_doc', 0, 0, 1); + print '
'; + print ''; // Type print ''; @@ -192,7 +205,14 @@ if ($result) } // Accounting account - if (! empty($conf->accounting->enabled)) print ' '; + if (! empty($conf->accounting->enabled)) + { + print ''; + print '
'; + print $formaccounting->select_account($search_accountancy_code, 'search_accountancy_code', 1, array (), 1, 1, 'maxwidth200'); + print '
'; + print ''; + } // Debit print ''; @@ -224,7 +244,7 @@ if ($result) print "".dol_trunc($obj->label,40)."\n"; // Date payment - print ''.dol_print_date($db->jdate($obj->datep),'day')."\n"; + print ''.dol_print_date($db->jdate($obj->datep),'day')."\n"; // Type print ''.$langs->trans("PaymentTypeShort".$obj->payment_code).' '.$obj->num_payment.''; From d35fc67cfcae0b8913462bdc905ffdbc4ba13ee6 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 15 Dec 2017 10:00:50 +0100 Subject: [PATCH 011/429] Unknown --- htdocs/compta/facture/class/api_invoices.class.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 115080811e6..34935c3088a 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -472,6 +472,11 @@ class Invoices extends DolibarrApi * @url POST {id}/lines * * @return int + * + * @throws 200 + * @throws 401 + * @throws 404 + * @throws 400 */ function postLine($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->facture->creer) { @@ -528,11 +533,11 @@ class Invoices extends DolibarrApi $request_data->fk_unit ); - if ($updateRes > 0) { - return $updateRes; - + if ($updateRes < 0) { + throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error); } - throw new RestException(400, 'Unable to insert the new line. Check your inputs.'); + + return $updateRes; } /** From e61d625577e6e9aa80833520cdef2a190503247f Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 15 Dec 2017 10:00:50 +0100 Subject: [PATCH 012/429] FIX error message --- htdocs/compta/facture/class/api_invoices.class.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 115080811e6..34935c3088a 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -472,6 +472,11 @@ class Invoices extends DolibarrApi * @url POST {id}/lines * * @return int + * + * @throws 200 + * @throws 401 + * @throws 404 + * @throws 400 */ function postLine($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->facture->creer) { @@ -528,11 +533,11 @@ class Invoices extends DolibarrApi $request_data->fk_unit ); - if ($updateRes > 0) { - return $updateRes; - + if ($updateRes < 0) { + throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error); } - throw new RestException(400, 'Unable to insert the new line. Check your inputs.'); + + return $updateRes; } /** From 4c852d1b6f638c17c329d7dc29b467b8f8e07cd4 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 15 Dec 2017 16:34:30 +0100 Subject: [PATCH 013/429] NEW Set a proposal to draft Set a proposal to draft --- .../comm/propal/class/api_proposals.class.php | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index adf1140e004..7e02ba3c30c 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -466,6 +466,51 @@ class Proposals extends DolibarrApi } + /** + * Set a proposal to draft + * + * @param int $id Order ID + * + * @url POST {id}/settodraft + * + * @return array + */ + function settodraft($id) + { + 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); + } + + $result = $this->propal->set_draft(DolibarrApiAccess::$user); + if ($result == 0) { + throw new RestException(304, 'Nothing done. May be object is already draft'); + } + if ($result < 0) { + throw new RestException(500, 'Error : '.$this->propal->error); + } + + $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); + } + + $this->propal->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->propal); + } + + /** * Validate a commercial proposal * From 54db0d31b4292ef986fb03a7fbc8e7583e9a958d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Dec 2017 11:32:24 +0100 Subject: [PATCH 014/429] Fix GETPOST for intcomma --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6b563dab8b3..ea71f3e1100 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -516,7 +516,7 @@ function GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NU if (! is_numeric($out)) { $out=''; } break; case 'intcomma': - if (preg_match('/[^0-9,]+/i',$out)) $out=''; + if (preg_match('/[^0-9,-]+/i',$out)) $out=''; break; case 'alpha': if (! is_array($out)) From 8e12551f17b993ae51b82cb51e37b551b55143ef Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Dec 2017 11:55:34 +0100 Subject: [PATCH 015/429] Fix not employee must not appear on page to create salaries --- htdocs/compta/salaries/card.php | 3 ++- htdocs/compta/salaries/index.php | 3 ++- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/user/class/user.class.php | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index a456777f631..608b5a737b0 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -255,7 +255,8 @@ if ($action == 'create') // Employee print ''; print fieldLabel('Employee','fk_user',1).''; - print $form->select_dolusers(GETPOST('fk_user','int'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + $noactive=0; // We keep active and unactive users + print $form->select_dolusers(GETPOST('fk_user','int'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, 'AND employee=1', 0, '', 'maxwidth300', $noactive); print ''; // Label diff --git a/htdocs/compta/salaries/index.php b/htdocs/compta/salaries/index.php index 2fee94c3216..47cafad0f0a 100644 --- a/htdocs/compta/salaries/index.php +++ b/htdocs/compta/salaries/index.php @@ -100,7 +100,7 @@ $salstatic = new PaymentSalary($db); $userstatic = new User($db); $accountstatic = new Account($db); -$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.admin, u.salary as current_salary, u.fk_soc as fk_soc,"; +$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.admin, u.salary as current_salary, u.fk_soc as fk_soc, u.statut as status,"; $sql.= " s.rowid, s.fk_user, s.amount, s.salary, s.label, s.datep as datep, s.datev as datev, s.fk_typepayment as type, s.num_payment, s.fk_bank,"; $sql.= " ba.rowid as bid, ba.ref as bref, ba.number as bnumber, ba.account_number, ba.fk_accountancy_journal, ba.label as blabel,"; $sql.= " pst.code as payment_code"; @@ -222,6 +222,7 @@ if ($result) $userstatic->login=$obj->login; $userstatic->email=$obj->email; $userstatic->societe_id=$obj->fk_soc; + $userstatic->statut=$obj->status; $salstatic->id=$obj->rowid; $salstatic->ref=$obj->rowid; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index b7ac69d0fc8..085b9874aeb 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1442,7 +1442,7 @@ class Form * @param array $exclude Array list of users id to exclude * @param int $disabled If select list must be disabled * @param array|string $include Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me - * @param array $enableonly Array list of users id to be enabled. If defined, it means that other must be disabled + * @param array $enableonly Array list of users id to be enabled. If defined, it means that others will be disabled * @param int $force_entity 0 or Id of environment to force * @param int $maxlength Maximum length of string into list (0=no limit) * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status @@ -1481,7 +1481,7 @@ class Form $out=''; - // On recherche les utilisateurs + // Forge request to select users $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity"; if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) { diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 5a103871058..e7b31400bc0 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -44,6 +44,7 @@ class User extends CommonObject public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $id=0; + public $statut; public $ldap_sid; public $search_sid; public $employee; @@ -56,7 +57,7 @@ class User extends CommonObject public $address; public $zip; public $town; - public $state_id; + public $state_id; // The state/department public $state_code; public $state; public $office_phone; @@ -101,7 +102,6 @@ class User extends CommonObject public $datelastlogin; public $datepreviouslogin; - public $statut; public $photo; public $lang; @@ -2102,6 +2102,7 @@ class User extends CommonObject } $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal")); $label.= '
' . $langs->trans("Type") . ': ' . $type; + $label.= '
' . $langs->trans("Status").': '.$this->getLibStatut(0); $label.=''; // Info Login From 98b82d712a7bec67ea2a8643978bd778ca2487dd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Dec 2017 12:43:03 +0100 Subject: [PATCH 016/429] NEW Revenue stamp can be a percent FIX Revenue stamp not visible on the transfer payment page --- htdocs/admin/dict.php | 17 +++++----- htdocs/compta/facture/card.php | 31 +++++++++++++++++-- htdocs/compta/facture/prelevement.php | 14 ++------- htdocs/core/class/html.formother.class.php | 8 ++--- .../install/mysql/data/llx_c_revenuestamp.sql | 8 ++++- .../install/mysql/migration/6.0.0-7.0.0.sql | 2 ++ .../mysql/tables/llx_c_revenuestamp.sql | 1 + htdocs/langs/en_US/admin.lang | 1 + 8 files changed, 57 insertions(+), 25 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index cf620fae65f..a1fc7c87d68 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -197,7 +197,7 @@ $tabsql[19]= "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREF $tabsql[20]= "SELECT rowid as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_input_method"; $tabsql[21]= "SELECT c.rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_availability AS c"; $tabsql[22]= "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_input_reason"; -$tabsql[23]= "SELECT t.rowid as rowid, t.taux, c.label as country, c.code as country_code, t.fk_pays as country_id, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_revenuestamp as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; +$tabsql[23]= "SELECT t.rowid as rowid, t.taux, t.revenuestamp_type, c.label as country, c.code as country_code, t.fk_pays as country_id, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_revenuestamp as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[24]= "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_type_resource"; //$tabsql[25]= "SELECT rowid as rowid, label, type_template, private, position, topic, content_lines, content, active FROM ".MAIN_DB_PREFIX."c_email_templates WHERE entity IN (".getEntity('email_template').")"; $tabsql[26]= "SELECT rowid as rowid, code, label, short_label, active FROM ".MAIN_DB_PREFIX."c_units"; @@ -275,7 +275,7 @@ $tabfield[19]= "code,libelle"; $tabfield[20]= "code,libelle"; $tabfield[21]= "code,label"; $tabfield[22]= "code,label"; -$tabfield[23]= "country_id,country,taux,accountancy_code_sell,accountancy_code_buy,note"; +$tabfield[23]= "country_id,country,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[24]= "code,label"; //$tabfield[25]= "label,type_template,private,position,topic,content_lines,content"; $tabfield[26]= "code,label,short_label"; @@ -314,7 +314,7 @@ $tabfieldvalue[19]= "code,libelle"; $tabfieldvalue[20]= "code,libelle"; $tabfieldvalue[21]= "code,label"; $tabfieldvalue[22]= "code,label"; -$tabfieldvalue[23]= "country,taux,accountancy_code_sell,accountancy_code_buy,note"; +$tabfieldvalue[23]= "country,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[24]= "code,label"; //$tabfieldvalue[25]= "label,type_template,private,position,topic,content_lines,content"; $tabfieldvalue[26]= "code,label,short_label"; @@ -353,7 +353,7 @@ $tabfieldinsert[19]= "code,libelle"; $tabfieldinsert[20]= "code,libelle"; $tabfieldinsert[21]= "code,label"; $tabfieldinsert[22]= "code,label"; -$tabfieldinsert[23]= "fk_pays,taux,accountancy_code_sell,accountancy_code_buy,note"; +$tabfieldinsert[23]= "fk_pays,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[24]= "code,label"; //$tabfieldinsert[25]= "label,type_template,private,position,topic,content_lines,content,entity"; $tabfieldinsert[26]= "code,label,short_label"; @@ -472,7 +472,7 @@ $tabhelp[19] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[20] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[21] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[22] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[23] = array(); +$tabhelp[23] = array('revenuestamp_type'=>'FixedOfPercent'); $tabhelp[24] = array('code'=>$langs->trans("EnterAnyCode")); //$tabhelp[25] = array('topic'=>$langs->trans('SeeSubstitutionVars'),'content'=>$langs->trans('SeeSubstitutionVars'),'content_lines'=>$langs->trans('SeeSubstitutionVars'),'type_template'=>$langs->trans("TemplateForElement"),'private'=>$langs->trans("TemplateIsVisibleByOwnerOnly"), 'position'=>$langs->trans("PositionIntoComboList")); $tabhelp[26] = array('code'=>$langs->trans("EnterAnyCode")); @@ -651,6 +651,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($fieldnamekey == 'deductible') $fieldnamekey = 'Deductible'; if ($fieldnamekey == 'sortorder') $fieldnamekey = 'SortOrder'; if ($fieldnamekey == 'category_type') $fieldnamekey = 'Calculated'; + if ($fieldnamekey == 'revenuestamp_type') $fieldnamekey = 'TypeOfRevenueStamp'; setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); } @@ -1117,7 +1118,8 @@ if ($id) if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); } if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); } if ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); } - if ($fieldlist[$field]=='fk_c_exp_tax_cat'){ $valuetoshow=$langs->trans("CarCategory"); } + if ($fieldlist[$field]=='fk_c_exp_tax_cat') { $valuetoshow=$langs->trans("CarCategory"); } + if ($fieldlist[$field]=='revenuestamp_type') { $valuetoshow=$langs->trans('TypeOfRevenueStamp'); } if ($id == 2) // Special cas for state page { @@ -1343,7 +1345,8 @@ if ($id) if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); } if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); } if ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); } - if ($fieldlist[$field]=='fk_c_exp_tax_cat'){ $valuetoshow=$langs->trans("CarCategory"); } + if ($fieldlist[$field]=='fk_c_exp_tax_cat') { $valuetoshow=$langs->trans("CarCategory"); } + if ($fieldlist[$field]=='revenuestamp_type') { $valuetoshow=$langs->trans('TypeOfRevenueStamp'); } // Affiche nom du champ if ($showfield) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 50ff7059f91..6def698a916 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3707,10 +3707,37 @@ else if ($id > 0 || ! empty($ref)) print '
'; print ''; print ''; - print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); - // print ''; + print ''; + print $formother->select_revenue_stamp('', 'revenuestamp_type', $mysoc->country_code); + print ' → '; print ' '; print '
'; + print " "; } else { print price($object->revenuestamp, 1, '', 1, - 1, - 1, $conf->currency); } diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index 8daee472e9e..cdeda46b768 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -120,6 +120,8 @@ $form = new Form($db); if ($object->id > 0) { + $selleruserevenustamp = $mysoc->useRevenueStamp(); + $totalpaye = $object->getSommePaiement(); $totalcreditnotes = $object->getSumCreditNotesUsed(); $totaldeposits = $object->getSumDepositsUsed(); @@ -486,17 +488,7 @@ if ($object->id > 0) } print ''; print ''; - if ($action == 'editrevenuestamp') { - print '
'; - print ''; - print ''; - print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); - // print ''; - print ' '; - print '
'; - } else { - print price($object->revenuestamp, 1, '', 1, - 1, - 1, $conf->currency); - } + print price($object->revenuestamp, 1, '', 1, - 1, - 1, $conf->currency); print ''; } diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 565cd4310b4..dfd70a075f0 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -222,7 +222,7 @@ class FormOther $out=''; - $sql = "SELECT r.taux"; + $sql = "SELECT r.taux, r.revenuestamp_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_revenuestamp as r,".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE r.active = 1 AND r.fk_pays = c.rowid"; $sql.= " AND c.code = '".$country_code."'"; @@ -242,14 +242,14 @@ class FormOther $obj = $this->db->fetch_object($resql); if (($selected && $selected == $obj->taux) || $num == 1) { - $out.=''; $i++; } diff --git a/htdocs/install/mysql/data/llx_c_revenuestamp.sql b/htdocs/install/mysql/data/llx_c_revenuestamp.sql index 040a8370485..ee4e9ab7873 100644 --- a/htdocs/install/mysql/data/llx_c_revenuestamp.sql +++ b/htdocs/install/mysql/data/llx_c_revenuestamp.sql @@ -27,4 +27,10 @@ delete from llx_c_revenuestamp; -- TUNISIA (id country=10) -- -insert into llx_c_revenuestamp(rowid,fk_pays,taux,note,active) values (101, 10, 0.4, 'Revenue stamp tunisia', 1); +insert into llx_c_revenuestamp(rowid,fk_pays,taux,revenuestamp_type,note,active) values (101, 10, 0.4, 'fixed', 'Revenue stamp tunisia', 1); + + +-- MEXICO (id country=154) -- +insert into llx_c_revenuestamp(rowid,fk_pays,taux,revenuestamp_type,note,active) values (1541, 154, 1.5, 'percent', 'Revenue stamp mexico', 1); +insert into llx_c_revenuestamp(rowid,fk_pays,taux,revenuestamp_type,note,active) values (1542, 154, 3, 'percent', 'Revenue stamp mexico', 1); + diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index dbff8454417..f042cb83556 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -71,6 +71,8 @@ ALTER TABLE llx_website_page ADD COLUMN type_container varchar(16) NOT NULL DEFA -- For 7.0 +ALTER TABLE llx_c_revenuestamp ADD COLUMN revenuestamp_type varchar(16) DEFAULT 'fixed' NOT NULL; + UPDATE llx_contrat SET ref = rowid WHERE ref IS NULL OR ref = ''; ALTER TABLE llx_contratdet ADD COLUMN vat_src_code varchar(10) DEFAULT ''; diff --git a/htdocs/install/mysql/tables/llx_c_revenuestamp.sql b/htdocs/install/mysql/tables/llx_c_revenuestamp.sql index 0eb5a46216d..9bdff7f0053 100644 --- a/htdocs/install/mysql/tables/llx_c_revenuestamp.sql +++ b/htdocs/install/mysql/tables/llx_c_revenuestamp.sql @@ -21,6 +21,7 @@ create table llx_c_revenuestamp rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, fk_pays integer NOT NULL, taux double NOT NULL, + revenuestamp_type varchar(16) DEFAULT 'fixed' NOT NULL, note varchar(128), active tinyint DEFAULT 1 NOT NULL, accountancy_code_sell varchar(32) DEFAULT NULL, diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 372d1a40aca..a4ece445581 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -904,6 +904,7 @@ SetupSaved=Setup saved SetupNotSaved=Setup not saved BackToModuleList=Back to modules list BackToDictionaryList=Back to dictionaries list +TypeOfRevenueStamp=Type of revenue stamp VATManagement=VAT Management VATIsUsedDesc=By default when creating prospects, invoices, orders etc the VAT rate follows the active standard rule:
If the seller is not subjected to VAT, then VAT defaults to 0. End of rule.
If the (selling country= buying country), then the VAT by default equals the VAT of the product in the selling country. End of rule.
If seller and buyer are both in the European Community and goods are transport products (car, ship, plane), the default VAT is 0 ( The VAT should be paid by the buyer to the customoffice of his country and not to the seller). End of rule.
If seller and buyer are both in the European Community and the buyer is not a company, then the VAT by defaults to the VAT of the product sold. End of rule.
If seller and buyer are both in the European Community and the buyer is a company, then the VAT is 0 by default . End of rule.
In any othe case the proposed default is VAT=0. End of rule. VATIsNotUsedDesc=By default the proposed VAT is 0 which can be used for cases like associations, individuals ou small companies. From d8dac909d6cc9e2bbd85ca8d8604c497781129e9 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Mon, 18 Dec 2017 14:36:41 +0100 Subject: [PATCH 017/429] NEW Add error message Returns the error message when the API can't add a new line in a proposal --- htdocs/comm/propal/class/api_proposals.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 7e02ba3c30c..cb0e94cf88f 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -290,8 +290,9 @@ class Proposals extends DolibarrApi if ($updateRes > 0) { return $updateRes; } - - return false; + else { + throw new RestException(400, $this->propal->error); + } } /** From 1351a43a30c2f34ddab06f77b0575be750c997b1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Dec 2017 15:39:40 +0100 Subject: [PATCH 018/429] FIX Maxi debug of permission for users external or restricted to sales representatives --- htdocs/adherents/document.php | 4 -- htdocs/comm/action/class/actioncomm.class.php | 11 ++- htdocs/comm/propal/class/propal.class.php | 11 ++- htdocs/commande/card.php | 1 - htdocs/commande/class/commande.class.php | 11 ++- htdocs/compta/facture/class/facture.class.php | 11 ++- htdocs/contrat/class/contrat.class.php | 11 ++- htdocs/core/class/commonobject.class.php | 34 ++++++--- htdocs/core/class/html.form.class.php | 6 +- htdocs/core/lib/security.lib.php | 70 +++++++++---------- htdocs/don/card.php | 6 +- .../class/fournisseur.commande.class.php | 11 ++- .../fourn/class/fournisseur.facture.class.php | 11 ++- htdocs/projet/ganttview.php | 4 +- htdocs/societe/class/societe.class.php | 5 ++ .../class/supplier_proposal.class.php | 11 ++- 16 files changed, 156 insertions(+), 62 deletions(-) diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php index 59328f24fd5..54e975c2f8c 100644 --- a/htdocs/adherents/document.php +++ b/htdocs/adherents/document.php @@ -42,10 +42,6 @@ $action=GETPOST('action','alpha'); $confirm=GETPOST('confirm','alpha'); // Security check -if ($user->societe_id > 0) -{ - $id = $user->societe_id; -} $result=restrictedArea($user,'adherent',$id); // Get parameters diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 39e2f0a98f7..985a50df9ec 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -36,8 +36,17 @@ class ActionComm extends CommonObject public $element='action'; public $table_element = 'actioncomm'; public $table_rowid = 'id'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='action'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user, 2=Same than 1 but accept record if fksoc is empty + * @var integer + */ + public $restrictiononfksoc = 2; /** * Id of the event diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 1b6a98dbdb9..84ad5707fe2 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -48,8 +48,17 @@ class Propal extends CommonObject public $table_element='propal'; public $table_element_line='propaldet'; public $fk_element='fk_propal'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='propal'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; /** * {@inheritdoc} diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 9474d54b925..63ca86191d3 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1288,7 +1288,6 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - if (! $error && ! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->commande->creer) { if ($action == 'addcontact') diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 6ebe94c327b..35ead22c32f 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -46,8 +46,17 @@ class Commande extends CommonOrder public $table_element_line = 'commandedet'; public $class_element_line = 'OrderLine'; public $fk_element = 'fk_commande'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto = 'order'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; /** * {@inheritdoc} diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index ac068fb5f6e..0d96236a6ab 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -52,8 +52,17 @@ class Facture extends CommonInvoice public $table_element='facture'; public $table_element_line = 'facturedet'; public $fk_element = 'fk_facture'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='bill'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; /** * {@inheritdoc} diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 48768af5a7a..1b52ac278ec 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -44,8 +44,17 @@ class Contrat extends CommonObject public $table_element='contrat'; public $table_element_line='contratdet'; public $fk_element='fk_contrat'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='contract'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; /** * {@inheritdoc} diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 37f87ca1da2..25d9f67a219 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1414,6 +1414,10 @@ abstract class CommonObject } if ($fieldid == 'none') return 1; + // Security on socid + $socid = 0; + if ($user->societe_id > 0) $socid = $user->societe_id; + // this->ismultientitymanaged contains // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe $alias = 's'; @@ -1422,18 +1426,25 @@ abstract class CommonObject $sql = "SELECT MAX(te.".$fieldid.")"; $sql.= " FROM ".(empty($nodbprefix)?MAIN_DB_PREFIX:'').$this->table_element." as te"; if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; + else if ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid + else if ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid + if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; $sql.= " WHERE te.".$fieldid." < '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id; + if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql.= " AND sc.fk_user = " .$user->id; + if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql.= " AND (sc.fk_user = " .$user->id.' OR te.fk_soc IS NULL)'; if (! empty($filter)) { if (! preg_match('/^\s*AND/i', $filter)) $sql.=" AND "; // For backward compatibility $sql.=$filter; } if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element, 1).')'; + else if ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element).')'; + if ($this->restrictiononfksoc == 1 && $socid && $this->element != 'societe') $sql.= ' AND te.fk_soc = ' . $socid; + if ($this->restrictiononfksoc == 2 && $socid && $this->element != 'societe') $sql.= ' AND (te.fk_soc = ' . $socid.' OR te.fk_soc IS NULL)'; + if ($this->restrictiononfksoc && $socid && $this->element == 'societe') $sql.= ' AND te.rowid = ' . $socid; + //print 'socid='.$socid.' restrictiononfksoc='.$this->restrictiononfksoc.' ismultientitymanaged = '.$this->ismultientitymanaged.' filter = '.$filter.' -> '.$sql."
"; - //print 'filter = '.$filter.' -> '.$sql."
"; $result = $this->db->query($sql); if (! $result) { @@ -1447,19 +1458,26 @@ abstract class CommonObject $sql = "SELECT MIN(te.".$fieldid.")"; $sql.= " FROM ".(empty($nodbprefix)?MAIN_DB_PREFIX:'').$this->table_element." as te"; if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; + else if ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid + else if ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid + if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; $sql.= " WHERE te.".$fieldid." > '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id; + if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql.= " AND sc.fk_user = " .$user->id; + if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql.= " AND (sc.fk_user = " .$user->id.' OR te.fk_soc IS NULL)'; if (! empty($filter)) { if (! preg_match('/^\s*AND/i', $filter)) $sql.=" AND "; // For backward compatibility $sql.=$filter; } if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element, 1).')'; + else if ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element).')'; + if ($this->restrictiononfksoc == 1 && $socid && $this->element != 'societe') $sql.= ' AND te.fk_soc = ' . $socid; + if ($this->restrictiononfksoc == 2 && $socid && $this->element != 'societe') $sql.= ' AND (te.fk_soc = ' . $socid.' OR te.fk_soc IS NULL)'; + if ($this->restrictiononfksoc && $socid && $this->element == 'societe') $sql.= ' AND te.rowid = ' . $socid; + //print 'socid='.$socid.' restrictiononfksoc='.$this->restrictiononfksoc.' ismultientitymanaged = '.$this->ismultientitymanaged.' filter = '.$filter.' -> '.$sql."
"; // Rem: Bug in some mysql version: SELECT MIN(rowid) FROM llx_socpeople WHERE rowid > 1 when one row in database with rowid=1, returns 1 instead of null - //print $sql."
"; $result = $this->db->query($sql); if (! $result) { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 085b9874aeb..e69aa485736 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5281,7 +5281,11 @@ class Form if ($objecttmp->ismultientitymanaged == 2) if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE t.entity IN (".getEntity($objecttmp->table_element).")"; - if ($objecttmp->ismultientitymanaged == 1 && ! empty($user->societe_id)) $sql.= " AND t.fk_soc = ".$user->societe_id; + if ($objecttmp->ismultientitymanaged == 1 && ! empty($user->societe_id)) + { + if ($objecttmp->element == 'societe') $sql.= " AND t.rowid = ".$user->societe_id; + else $sql.= " AND t.fk_soc = ".$user->societe_id; + } if ($searchkey != '') $sql.=natural_search(explode(',',$fieldstoshow), $searchkey); if ($objecttmp->ismultientitymanaged == 2) if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND t.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index cf37b749b5b..fa624a118f8 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -355,14 +355,14 @@ function restrictedArea($user, $features, $objectid=0, $tableandshare='', $featu * Check access by user to object. * This function is also called by restrictedArea * - * @param User $user User to check - * @param array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...) - * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). - * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany modume. Param not used if objectid is null (optional). - * @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'. - * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) - * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) - * @return bool True if user has access, False otherwise + * @param User $user User to check + * @param array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...) + * @param int|string $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). + * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany modume. Param not used if objectid is null (optional). + * @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'. + * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) + * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) + * @return bool True if user has access, False otherwise * @see restrictedArea */ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='', $dbt_select='rowid') @@ -379,16 +379,16 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh $sql=''; // For backward compatibility - if ($feature == 'member') $feature='adherent'; + if ($feature == 'member') $feature='adherent'; if ($feature == 'project') $feature='projet'; - if ($feature == 'task') $feature='projet_task'; + if ($feature == 'task') $feature='projet_task'; $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie'); // Test on entity only (Objects with no link to company) $checksoc = array('societe'); // Test for societe object $checkother = array('contact','agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...). $checkproject = array('projet','project'); // Test for project object $checktask = array('projet_task'); - $nocheck = array('barcode','stock','fournisseur'); // No test + $nocheck = array('barcode','stock','fournisseur','don'); // No test $checkdefault = 'all other not already defined'; // Test on entity and link to third party. Not allowed if link is empty (Ex: invoice, orders...). // If dbtablename not defined, we use same name for table than module name @@ -401,9 +401,9 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh // Check permission for object with entity if (in_array($feature,$check)) { - $sql = "SELECT dbt.".$dbt_select; + $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; if (($feature == 'user' || $feature == 'usergroup') && ! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) { $sql.= " AND dbt.entity IS NOT NULL"; @@ -423,10 +423,10 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh // If internal user: Check permission for internal users that are restricted on their objects else if (! empty($conf->societe->enabled) && ($user->rights->societe->lire && ! $user->rights->societe->client->voir)) { - $sql = "SELECT sc.fk_soc"; + $sql = "SELECT COUNT(sc.fk_soc) as nb"; $sql.= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= ", ".MAIN_DB_PREFIX."societe as s)"; - $sql.= " WHERE sc.fk_soc = ".$objectid; + $sql.= " WHERE sc.fk_soc IN (".$objectid.")"; $sql.= " AND sc.fk_user = ".$user->id; $sql.= " AND sc.fk_soc = s.rowid"; $sql.= " AND s.entity IN (".getEntity($sharedelement, 1).")"; @@ -434,9 +434,9 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh // If multicompany and internal users with all permissions, check user is in correct entity else if (! empty($conf->multicompany->enabled)) { - $sql = "SELECT s.rowid"; + $sql = "SELECT COUNT(s.rowid) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE s.rowid = ".$objectid; + $sql.= " WHERE s.rowid IN (".$objectid.")"; $sql.= " AND s.entity IN (".getEntity($sharedelement, 1).")"; } } @@ -445,27 +445,27 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh // If external user: Check permission for external users if ($user->societe_id > 0) { - $sql = "SELECT dbt.".$dbt_select; + $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; $sql.= " AND dbt.fk_soc = ".$user->societe_id; } // If internal user: Check permission for internal users that are restricted on their objects else if (! empty($conf->societe->enabled) && ($user->rights->societe->lire && ! $user->rights->societe->client->voir)) { - $sql = "SELECT dbt.".$dbt_select; + $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON dbt.fk_soc = sc.fk_soc AND sc.fk_user = '".$user->id."'"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; $sql.= " AND (dbt.fk_soc IS NULL OR sc.fk_soc IS NOT NULL)"; // Contact not linked to a company or to a company of user $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")"; } // If multicompany and internal users with all permissions, check user is in correct entity else if (! empty($conf->multicompany->enabled)) { - $sql = "SELECT dbt.".$dbt_select; + $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")"; } } @@ -481,9 +481,9 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh } else { - $sql = "SELECT dbt.".$dbt_select; + $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")"; } } @@ -502,9 +502,9 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh } else { - $sql = "SELECT dbt.".$dbt_select; + $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")"; } } @@ -514,20 +514,20 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh if ($user->societe_id > 0) { if (empty($dbt_keyfield)) dol_print_error('','Param dbt_keyfield is required but not defined'); - $sql = "SELECT dbt.".$dbt_keyfield; + $sql = "SELECT COUNT(dbt.".$dbt_keyfield.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; - $sql.= " WHERE dbt.rowid = ".$objectid; + $sql.= " WHERE dbt.rowid IN (".$objectid.")"; $sql.= " AND dbt.".$dbt_keyfield." = ".$user->societe_id; } // If internal user: Check permission for internal users that are restricted on their objects else if (! empty($conf->societe->enabled) && ($user->rights->societe->lire && ! $user->rights->societe->client->voir)) { if (empty($dbt_keyfield)) dol_print_error('','Param dbt_keyfield is required but not defined'); - $sql = "SELECT sc.fk_soc"; + $sql = "SELECT COUNT(sc.fk_soc) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; $sql.= " AND sc.fk_soc = dbt.".$dbt_keyfield; $sql.= " AND dbt.".$dbt_keyfield." = s.rowid"; $sql.= " AND s.entity IN (".getEntity($sharedelement, 1).")"; @@ -536,20 +536,20 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh // If multicompany and internal users with all permissions, check user is in correct entity else if (! empty($conf->multicompany->enabled)) { - $sql = "SELECT dbt.".$dbt_select; + $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; - $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")"; $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")"; } } - //print "sql=".$sql."
"; if ($sql) { $resql=$db->query($sql); if ($resql) { - if ($db->num_rows($resql) == 0) return false; + $obj = $db->fetch_object($resql); + if (! $obj || $obj->nb < count(explode(',', $objectid))) return false; } else { diff --git a/htdocs/don/card.php b/htdocs/don/card.php index 539bae26e48..5081e32dd0e 100644 --- a/htdocs/don/card.php +++ b/htdocs/don/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2015-2016 Alexandre Spangaro @@ -630,8 +630,8 @@ if (! empty($id) && $action != 'edit') * Payments */ $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount,"; - $sql.= "c.code as type_code,c.libelle as paiement_type"; - $sql.= " FROM ".MAIN_DB_PREFIX."payment_donation as p LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c AND c.entity IN (".getEntity('c_paiement').")"; + $sql.= " c.code as type_code,c.libelle as paiement_type"; + $sql.= " FROM ".MAIN_DB_PREFIX."payment_donation as p LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON c.entity IN (".getEntity('c_paiement').")"; $sql.= ", ".MAIN_DB_PREFIX."don as d"; $sql.= " WHERE d.rowid = '".$id."'"; $sql.= " AND p.fk_donation = d.rowid"; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 868014ea618..e6e309c2239 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -43,8 +43,17 @@ class CommandeFournisseur extends CommonOrder public $table_element='commande_fournisseur'; public $table_element_line = 'commande_fournisseurdet'; public $fk_element = 'fk_commande'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='order'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; /** * {@inheritdoc} diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 2be366cfc46..995745b4faa 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -44,8 +44,17 @@ class FactureFournisseur extends CommonInvoice public $table_element='facture_fourn'; public $table_element_line='facture_fourn_det'; public $fk_element='fk_facture_fourn'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='bill'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; /** * {@inheritdoc} diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index d63f2d2bb62..77e4709f4b9 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -32,7 +32,7 @@ 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.'/core/class/html.formother.class.php'; -$id=GETPOST('id','int'); +$id=GETPOST('id','intcomma'); $ref=GETPOST('ref','alpha'); $mode = GETPOST('mode', 'alpha'); @@ -46,7 +46,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be inclu // Security check $socid=0; //if ($user->societe_id > 0) $socid = $user->societe_id; // For external user, no check is done on company because readability is managed by public status of project and assignement. -$result = restrictedArea($user, 'projet', $id,'projet&project'); +$result = restrictedArea($user, 'projet', $id, 'projet&project'); $langs->load("users"); $langs->load("projects"); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index f8fe4a80123..4a37699e6c6 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -53,6 +53,11 @@ class Societe extends CommonObject * @var int */ public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; // BEGIN MODULEBUILDER PROPERTIES diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 5b830f6e37c..4fa0c8fad6e 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -48,8 +48,17 @@ class SupplierProposal extends CommonObject public $table_element='supplier_proposal'; public $table_element_line='supplier_proposaldet'; public $fk_element='fk_supplier_proposal'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='propal'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + /** + * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * @var integer + */ + public $restrictiononfksoc = 1; /** * {@inheritdoc} From 081787326710471d8fdad079bdd8ee39f9fad6ca Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Mon, 18 Dec 2017 16:13:54 +0100 Subject: [PATCH 019/429] NEW Create an order using an existing proposal Create an order using an existing proposal. --- htdocs/commande/class/api_orders.class.php | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index b7cd76520c4..0b508b59f31 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -676,6 +676,49 @@ class Orders extends DolibarrApi } + /** + * Create an order using an existing proposal. + * + * + * @param int $proposalid Id of the proposal + * + * @url POST /createfromproposal/{proposalid} + * + * @return int + * @throws 400 + * @throws 401 + * @throws 404 + * @throws 405 + */ + function createOrderFromProposal($proposalid) { + + require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php'; + + if(! DolibarrApiAccess::$user->rights->propal->lire) { + throw new RestException(401); + } + if(! DolibarrApiAccess::$user->rights->commande->creer) { + throw new RestException(401); + } + if(empty($proposalid)) { + throw new RestException(400, 'Proposal ID is mandatory'); + } + + $propal = new Propal($this->db); + $result = $propal->fetch($proposalid); + if( ! $result ) { + throw new RestException(404, 'Proposal not found'); + } + + $result = $this->commande->createFromProposal($propal, DolibarrApiAccess::$user); + if( $result < 0) { + throw new RestException(405, $this->commande->error); + } + $this->commande->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->commande); + } + + /** * Clean sensible object datas * From 2204790602638567c07504d5c6d2bbe46b95e2f9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Dec 2017 19:04:57 +0100 Subject: [PATCH 020/429] Fix filter on project id when id is list with comma --- htdocs/core/actions_fetchobject.inc.php | 27 ++++++++++++++----------- htdocs/core/lib/functions.lib.php | 2 +- htdocs/projet/class/task.class.php | 4 ++-- htdocs/projet/ganttview.php | 13 ++++++------ 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/htdocs/core/actions_fetchobject.inc.php b/htdocs/core/actions_fetchobject.inc.php index b9cefe45306..e42c2e9a83b 100644 --- a/htdocs/core/actions_fetchobject.inc.php +++ b/htdocs/core/actions_fetchobject.inc.php @@ -30,16 +30,19 @@ if (($id > 0 || (! empty($ref) && ! in_array($action, array('create', 'createtask', 'add')))) && (empty($cancel) || $id > 0)) { - $ret = $object->fetch($id, $ref); - if ($ret > 0) - { - $object->fetch_thirdparty(); - $id = $object->id; - } - else - { - if (empty($object->error) && ! count($object->errors)) setEventMessages('Fetch on object return an error without filling $object->error nor $object->errors', null, 'errors'); - else setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } + if (($id > 0 && is_numeric($id)) || ! empty($ref)) // To discard case when id is list of ids like '1,2,3...' + { + $ret = $object->fetch($id, $ref); + if ($ret > 0) + { + $object->fetch_thirdparty(); + $id = $object->id; + } + else + { + if (empty($object->error) && ! count($object->errors)) setEventMessages('Fetch on object return an error without filling $object->error nor $object->errors', null, 'errors'); + else setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } + } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ea71f3e1100..6d0aa119316 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6568,7 +6568,7 @@ function dol_getmypid() /** * Generate natural SQL search string for a criteria (this criteria can be tested on one or several fields) * - * @param string|string[] $fields String or array of strings, filled with the name of all fields in the SQL query we must check (combined with a OR) + * @param string|string[] $fields String or array of strings, filled with the name of all fields in the SQL query we must check (combined with a OR). Example: array("p.field1","p.field2") * @param string $value The value to look for. * If param $mode is 0, can contains several keywords separated with a space or | * like "keyword1 keyword2" = We want record field like keyword1 AND field like keyword2 diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 14f3c7e37d4..2a77de4f552 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -754,8 +754,8 @@ class Task extends CommonObject } if ($socid) $sql.= " AND p.fk_soc = ".$socid; if ($projectid) $sql.= " AND p.rowid in (".$projectid.")"; - if ($filteronproj) $sql.= " AND (p.ref LIKE '%".$this->db->escape($filteronproj)."%' OR p.title LIKE '%".$this->db->escape($filteronproj)."%')"; - if ($filteronprojstatus > -1) $sql.= " AND p.fk_statut = ".$filteronprojstatus; + if ($filteronproj) $sql.= natural_search(array("p.ref", "p.title"), $filteronproj); + if ($filteronprojstatus > -1) $sql.= " AND p.fk_statut IN (".$filteronprojstatus.")"; if ($morewherefilter) $sql.=$morewherefilter; $sql.= " ORDER BY p.ref, t.rang, t.dateo"; diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 77e4709f4b9..c3552d714f2 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -80,12 +80,12 @@ if (! empty($conf->use_javascript_ajax)) ); } -$title=$langs->trans("Project").' - '.$langs->trans("Gantt").' - '.$object->ref.' '.$object->name; -if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->ref.' '.$object->name.' - '.$langs->trans("Gantt"); +$title=$langs->trans("Project").' - '.$langs->trans("Gantt").($object->ref?' - '.$object->ref.' '.$object->name:''); +if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=($object->ref?$object->ref.' '.$object->name.' - ':'').$langs->trans("Gantt"); $help_url="EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; llxHeader("",$title,$help_url,'',0,0,$arrayofjs,$arrayofcss); -if ($id > 0 || ! empty($ref)) +if (($id > 0 && is_numeric($id)) || ! empty($ref)) { // To verify role of users //$userAccess = $object->restrictedProjectArea($user,'read'); @@ -93,7 +93,6 @@ if ($id > 0 || ! empty($ref)) //$userDelete = $object->restrictedProjectArea($user,'delete'); //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; - $tab='gantt'; $head=project_prepare_head($object); @@ -195,7 +194,7 @@ if ($id > 0 || ! empty($ref)) * Buttons actions */ -if ($id > 0) +if ($id > 0 && is_numeric($id)) { print '
'; @@ -229,7 +228,7 @@ else // Get list of tasks in tasksarray and taskarrayfiltered // We need all tasks (even not limited to a user because a task to user // can have a parent that is not affected to him). -$tasksarray=$task->getTasksArray(0, 0, $object->id, $socid, 0); +$tasksarray=$task->getTasksArray(0, 0, ($object->id ? $object->id : $id), $socid, 0); // We load also tasks limited to a particular user //$tasksrole=($_REQUEST["mode"]=='mine' ? $task->getUserRolesForProjectsOrTasks(0,$user,$object->id,0) : ''); //var_dump($tasksarray); From 2e87318b58030c249de13918dbddba3d1dab6741 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Dec 2017 19:15:42 +0100 Subject: [PATCH 021/429] Fix sql error --- htdocs/core/modules/rapport/pdf_paiement.class.php | 2 +- htdocs/fourn/facture/rapport.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index b294d8645eb..2bb784aa578 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -218,7 +218,7 @@ class pdf_paiement if (! empty($conf->banque->enabled)) $sql.= ", ba.ref as bankaccount"; $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p LEFT JOIN ON ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_paiement = c.id AND c.entity IN (".getEntity('c_paiement').")"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_paiement = c.id AND c.entity IN (".getEntity('c_paiement').")"; $sql.= ", ".MAIN_DB_PREFIX."facture_fourn as f,"; $sql.= " ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; if (! empty($conf->banque->enabled)) diff --git a/htdocs/fourn/facture/rapport.php b/htdocs/fourn/facture/rapport.php index d0a0c5f0aea..ee7f5f99769 100644 --- a/htdocs/fourn/facture/rapport.php +++ b/htdocs/fourn/facture/rapport.php @@ -85,9 +85,10 @@ if ($action == 'builddoc') $formother=new FormOther($db); -llxHeader(); - $titre=($year?$langs->trans("PaymentsReportsForYear",$year):$langs->trans("PaymentsReports")); + +llxHeader('', $titre); + print load_fiche_titre($titre,'','title_accountancy.png'); // Formulaire de generation @@ -152,7 +153,7 @@ if ($year) { if (preg_match('/^supplier_payment/i',$file)) { - + $tfile = $dir . '/'.$year.'/'.$file; $relativepath = $year.'/'.$file; print "".''.img_pdf().' '.$file.''; From d4afb8300d26598bdf697f7146d2022d3ebb6a3a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 00:15:22 +0100 Subject: [PATCH 022/429] Fix several pb of duplicate functions in some cases --- htdocs/core/lib/functions.lib.php | 41 ++-- htdocs/core/lib/security2.lib.php | 319 +++++++++++++++--------------- htdocs/core/tpl/login.tpl.php | 1 + htdocs/main.inc.php | 10 +- htdocs/user/logout.php | 2 +- htdocs/user/passwordforgotten.php | 2 + 6 files changed, 196 insertions(+), 179 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6d0aa119316..b0b67b2fb8d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -37,6 +37,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/lib/json.lib.php'; + /** * Function to return value of a static property when class * name is dynamically defined (not hard coded). @@ -595,30 +596,34 @@ function GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NU /** * Return a prefix to use for this Dolibarr instance, for session/cookie names or email id. - * This prefix is unique for instance and avoid conflict between multi-instances, - * even when having two instances with one root dir or two instances in virtual servers. + * This prefix is valid in a web context only and is unique for instance and avoid conflict + * between multi-instances, even when having two instances with one root dir or two instances + * in virtual servers. * - * @param string $mode '' (prefix for session name) or 'email' (prefix for email id) - * @return string A calculated prefix + * @param string $mode '' (prefix for session name) or 'email' (prefix for email id) + * @return string A calculated prefix */ -function dol_getprefix($mode='') +if (! function_exists('dol_getprefix')) { - global $conf; - - // If MAIL_PREFIX_FOR_EMAIL_ID is set and prefix is for email - if ($mode == 'email' && ! empty($conf->global->MAIL_PREFIX_FOR_EMAIL_ID)) + function dol_getprefix($mode='') { - if ($conf->global->MAIL_PREFIX_FOR_EMAIL_ID != 'SERVER_NAME') return $conf->global->MAIL_PREFIX_FOR_EMAIL_ID; - else if (isset($_SERVER["SERVER_NAME"])) return $_SERVER["SERVER_NAME"]; - } + global $conf; - if (isset($_SERVER["SERVER_NAME"]) && isset($_SERVER["DOCUMENT_ROOT"])) - { - return dol_hash($_SERVER["SERVER_NAME"].$_SERVER["DOCUMENT_ROOT"].DOL_DOCUMENT_ROOT.DOL_URL_ROOT); - // Use this for a "clear" cookie name - //return dol_sanitizeFileName($_SERVER["SERVER_NAME"].$_SERVER["DOCUMENT_ROOT"].DOL_DOCUMENT_ROOT.DOL_URL_ROOT); + // If MAIL_PREFIX_FOR_EMAIL_ID is set and prefix is for email + if ($mode == 'email' && ! empty($conf->global->MAIL_PREFIX_FOR_EMAIL_ID)) + { + if ($conf->global->MAIL_PREFIX_FOR_EMAIL_ID != 'SERVER_NAME') return $conf->global->MAIL_PREFIX_FOR_EMAIL_ID; + else if (isset($_SERVER["SERVER_NAME"])) return $_SERVER["SERVER_NAME"]; + } + + if (isset($_SERVER["SERVER_NAME"]) && isset($_SERVER["DOCUMENT_ROOT"])) + { + return dol_hash($_SERVER["SERVER_NAME"].$_SERVER["DOCUMENT_ROOT"].DOL_DOCUMENT_ROOT.DOL_URL_ROOT); + // Use this for a "readable" cookie name + //return dol_sanitizeFileName($_SERVER["SERVER_NAME"].$_SERVER["DOCUMENT_ROOT"].DOL_DOCUMENT_ROOT.DOL_URL_ROOT); + } + else return dol_hash(DOL_DOCUMENT_ROOT.DOL_URL_ROOT); } - else return dol_hash(DOL_DOCUMENT_ROOT.DOL_URL_ROOT); } /** diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index 7d305ded7d4..fab2a15b674 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -126,179 +126,182 @@ function checkLoginPassEntity($usertotest,$passwordtotest,$entitytotest,$authmod * @param Societe $mysoc Company object * @return void */ -function dol_loginfunction($langs,$conf,$mysoc) +if (! function_exists('dol_loginfunction')) { - global $dolibarr_main_demo,$db; - global $smartphone,$hookmanager; - - // Instantiate hooks of thirdparty module only if not already define - $hookmanager->initHooks(array('mainloginpage')); - - $langs->load("main"); - $langs->load("other"); - $langs->load("help"); - $langs->load("admin"); - - $main_authentication=$conf->file->main_authentication; - $session_name=session_name(); - - $dol_url_root = DOL_URL_ROOT; - - // Title - $appli=constant('DOL_APPLICATION_TITLE'); - $title=$appli.' '.constant('DOL_VERSION'); - if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $title=$conf->global->MAIN_APPLICATION_TITLE; - $titletruedolibarrversion=constant('DOL_VERSION'); // $title used by login template after the @ to inform of true Dolibarr version - - // Note: $conf->css looks like '/theme/eldy/style.css.php' - $conf->css = "/theme/".(GETPOST('theme','alpha')?GETPOST('theme','alpha'):$conf->theme)."/style.css.php"; - $themepath=dol_buildpath($conf->css,1); - if (! empty($conf->modules_parts['theme'])) // Using this feature slow down application + function dol_loginfunction($langs,$conf,$mysoc) { - foreach($conf->modules_parts['theme'] as $reldir) + global $dolibarr_main_demo,$db; + global $smartphone,$hookmanager; + + $langs->loadLangs(array("main","other","help","admin")); + + // Instantiate hooks of thirdparty module only if not already define + $hookmanager->initHooks(array('mainloginpage')); + + $main_authentication=$conf->file->main_authentication; + + $session_name=session_name(); // Get current session name + + $dol_url_root = DOL_URL_ROOT; + + // Title + $appli=constant('DOL_APPLICATION_TITLE'); + $title=$appli.' '.constant('DOL_VERSION'); + if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $title=$conf->global->MAIN_APPLICATION_TITLE; + $titletruedolibarrversion=constant('DOL_VERSION'); // $title used by login template after the @ to inform of true Dolibarr version + + // Note: $conf->css looks like '/theme/eldy/style.css.php' + /* + $conf->css = "/theme/".(GETPOST('theme','alpha')?GETPOST('theme','alpha'):$conf->theme)."/style.css.php"; + $themepath=dol_buildpath($conf->css,1); + if (! empty($conf->modules_parts['theme'])) // Using this feature slow down application { - if (file_exists(dol_buildpath($reldir.$conf->css, 0))) + foreach($conf->modules_parts['theme'] as $reldir) { - $themepath=dol_buildpath($reldir.$conf->css, 1); - break; + if (file_exists(dol_buildpath($reldir.$conf->css, 0))) + { + $themepath=dol_buildpath($reldir.$conf->css, 1); + break; + } } } - } - $conf_css = $themepath."?lang=".$langs->defaultlang; + $conf_css = $themepath."?lang=".$langs->defaultlang; + */ - // Select templates dir - if (! empty($conf->modules_parts['tpl'])) // Using this feature slow down application - { - $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl/')); - foreach($dirtpls as $reldir) + // Select templates dir + if (! empty($conf->modules_parts['tpl'])) // Using this feature slow down application { - $tmp=dol_buildpath($reldir.'login.tpl.php'); - if (file_exists($tmp)) { $template_dir=preg_replace('/login\.tpl\.php$/','',$tmp); break; } + $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl/')); + foreach($dirtpls as $reldir) + { + $tmp=dol_buildpath($reldir.'login.tpl.php'); + if (file_exists($tmp)) { $template_dir=preg_replace('/login\.tpl\.php$/','',$tmp); break; } + } } - } - else - { - $template_dir = DOL_DOCUMENT_ROOT."/core/tpl/"; - } - - // Set cookie for timeout management - $prefix=dol_getprefix(); - $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; - if (! empty($conf->global->MAIN_SESSION_TIMEOUT)) setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", null, false, true); - - if (GETPOST('urlfrom','alpha')) $_SESSION["urlfrom"]=GETPOST('urlfrom','alpha'); - else unset($_SESSION["urlfrom"]); - - if (! GETPOST("username",'alpha')) $focus_element='username'; - else $focus_element='password'; - - $demologin=''; - $demopassword=''; - if (! empty($dolibarr_main_demo)) - { - $tab=explode(',',$dolibarr_main_demo); - $demologin=$tab[0]; - $demopassword=$tab[1]; - } - - // Execute hook getLoginPageOptions (for table) - $parameters=array('entity' => GETPOST('entity','int')); - $reshook = $hookmanager->executeHooks('getLoginPageOptions',$parameters); // Note that $action and $object may have been modified by some hooks. - if (is_array($hookmanager->resArray) && ! empty($hookmanager->resArray)) { - $morelogincontent = $hookmanager->resArray; // (deprecated) For compatibility - } else { - $morelogincontent = $hookmanager->resPrint; - } - - // Execute hook getLoginPageExtraOptions (eg for js) - $parameters=array('entity' => GETPOST('entity','int')); - $reshook = $hookmanager->executeHooks('getLoginPageExtraOptions',$parameters); // Note that $action and $object may have been modified by some hooks. - $moreloginextracontent = $hookmanager->resPrint; - - // Login - $login = (! empty($hookmanager->resArray['username']) ? $hookmanager->resArray['username'] : (GETPOST("username","alpha") ? GETPOST("username","alpha") : $demologin)); - $password = $demopassword; - - // Show logo (search in order: small company logo, large company logo, theme logo, common logo) - $width=0; - $urllogo=DOL_URL_ROOT.'/theme/login_logo.png'; - - if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) - { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('thumbs/'.$mysoc->logo_small); - } - elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) - { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode($mysoc->logo); - $width=128; - } - elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png')) - { - $urllogo=DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'; - } - elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png')) - { - $urllogo=DOL_URL_ROOT.'/theme/dolibarr_logo.png'; - } - - // Security graphical code - $captcha=0; - $captcha_refresh=''; - if (function_exists("imagecreatefrompng") && ! empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA)) - { - $captcha=1; - $captcha_refresh=img_picto($langs->trans("Refresh"),'refresh','id="captcha_refresh_img"'); - } - - // Extra link - $forgetpasslink=0; - $helpcenterlink=0; - if (empty($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK) || empty($conf->global->MAIN_HELPCENTER_DISABLELINK)) - { - if (empty($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK)) + else { - $forgetpasslink=1; + $template_dir = DOL_DOCUMENT_ROOT."/core/tpl/"; } - if (empty($conf->global->MAIN_HELPCENTER_DISABLELINK)) + // Set cookie for timeout management + $prefix=dol_getprefix(''); + $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; + if (! empty($conf->global->MAIN_SESSION_TIMEOUT)) setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", null, false, true); + + if (GETPOST('urlfrom','alpha')) $_SESSION["urlfrom"]=GETPOST('urlfrom','alpha'); + else unset($_SESSION["urlfrom"]); + + if (! GETPOST("username",'alpha')) $focus_element='username'; + else $focus_element='password'; + + $demologin=''; + $demopassword=''; + if (! empty($dolibarr_main_demo)) { - $helpcenterlink=1; + $tab=explode(',',$dolibarr_main_demo); + $demologin=$tab[0]; + $demopassword=$tab[1]; } + + // Execute hook getLoginPageOptions (for table) + $parameters=array('entity' => GETPOST('entity','int')); + $reshook = $hookmanager->executeHooks('getLoginPageOptions',$parameters); // Note that $action and $object may have been modified by some hooks. + if (is_array($hookmanager->resArray) && ! empty($hookmanager->resArray)) { + $morelogincontent = $hookmanager->resArray; // (deprecated) For compatibility + } else { + $morelogincontent = $hookmanager->resPrint; + } + + // Execute hook getLoginPageExtraOptions (eg for js) + $parameters=array('entity' => GETPOST('entity','int')); + $reshook = $hookmanager->executeHooks('getLoginPageExtraOptions',$parameters); // Note that $action and $object may have been modified by some hooks. + $moreloginextracontent = $hookmanager->resPrint; + + // Login + $login = (! empty($hookmanager->resArray['username']) ? $hookmanager->resArray['username'] : (GETPOST("username","alpha") ? GETPOST("username","alpha") : $demologin)); + $password = $demopassword; + + // Show logo (search in order: small company logo, large company logo, theme logo, common logo) + $width=0; + $urllogo=DOL_URL_ROOT.'/theme/login_logo.png'; + + if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) + { + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('thumbs/'.$mysoc->logo_small); + } + elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) + { + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode($mysoc->logo); + $width=128; + } + elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png')) + { + $urllogo=DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'; + } + elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png')) + { + $urllogo=DOL_URL_ROOT.'/theme/dolibarr_logo.png'; + } + + // Security graphical code + $captcha=0; + $captcha_refresh=''; + if (function_exists("imagecreatefrompng") && ! empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA)) + { + $captcha=1; + $captcha_refresh=img_picto($langs->trans("Refresh"),'refresh','id="captcha_refresh_img"'); + } + + // Extra link + $forgetpasslink=0; + $helpcenterlink=0; + if (empty($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK) || empty($conf->global->MAIN_HELPCENTER_DISABLELINK)) + { + if (empty($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK)) + { + $forgetpasslink=1; + } + + if (empty($conf->global->MAIN_HELPCENTER_DISABLELINK)) + { + $helpcenterlink=1; + } + } + + // Home message + $main_home=''; + if (! empty($conf->global->MAIN_HOME)) + { + $substitutionarray=getCommonSubstitutionArray($langs); + complete_substitutions_array($substitutionarray, $langs); + $texttoshow = make_substitutions($conf->global->MAIN_HOME, $substitutionarray, $langs); + + $main_home=dol_htmlcleanlastbr($texttoshow); + } + + // Google AD + $main_google_ad_client = ((! empty($conf->global->MAIN_GOOGLE_AD_CLIENT) && ! empty($conf->global->MAIN_GOOGLE_AD_SLOT))?1:0); + + // Set jquery theme + $dol_loginmesg = (! empty($_SESSION["dol_loginmesg"])?$_SESSION["dol_loginmesg"]:''); + $favicon=dol_buildpath('/theme/'.$conf->theme.'/img/favicon.ico',1); + if (! empty($conf->global->MAIN_FAVICON_URL)) $favicon=$conf->global->MAIN_FAVICON_URL; + $jquerytheme = 'smoothness'; + if (! empty($conf->global->MAIN_USE_JQUERY_THEME)) $jquerytheme = $conf->global->MAIN_USE_JQUERY_THEME; + + // Set dol_hide_topmenu, dol_hide_leftmenu, dol_optimize_smallscreen, dol_no_mouse_hover + $dol_hide_topmenu=GETPOST('dol_hide_topmenu','int'); + $dol_hide_leftmenu=GETPOST('dol_hide_leftmenu','int'); + $dol_optimize_smallscreen=GETPOST('dol_optimize_smallscreen','int'); + $dol_no_mouse_hover=GETPOST('dol_no_mouse_hover','int'); + $dol_use_jmobile=GETPOST('dol_use_jmobile','int'); + + // Include login page template + include $template_dir.'login.tpl.php'; + + + $_SESSION["dol_loginmesg"] = ''; } - - // Home message - $main_home=''; - if (! empty($conf->global->MAIN_HOME)) - { - $substitutionarray=getCommonSubstitutionArray($langs); - complete_substitutions_array($substitutionarray, $langs); - $texttoshow = make_substitutions($conf->global->MAIN_HOME, $substitutionarray, $langs); - - $main_home=dol_htmlcleanlastbr($texttoshow); - } - - // Google AD - $main_google_ad_client = ((! empty($conf->global->MAIN_GOOGLE_AD_CLIENT) && ! empty($conf->global->MAIN_GOOGLE_AD_SLOT))?1:0); - - // Set jquery theme - $dol_loginmesg = (! empty($_SESSION["dol_loginmesg"])?$_SESSION["dol_loginmesg"]:''); - $favicon=dol_buildpath('/theme/'.$conf->theme.'/img/favicon.ico',1); - if (! empty($conf->global->MAIN_FAVICON_URL)) $favicon=$conf->global->MAIN_FAVICON_URL; - $jquerytheme = 'smoothness'; - if (! empty($conf->global->MAIN_USE_JQUERY_THEME)) $jquerytheme = $conf->global->MAIN_USE_JQUERY_THEME; - - // Set dol_hide_topmenu, dol_hide_leftmenu, dol_optimize_smallscreen, dol_no_mouse_hover - $dol_hide_topmenu=GETPOST('dol_hide_topmenu','int'); - $dol_hide_leftmenu=GETPOST('dol_hide_leftmenu','int'); - $dol_optimize_smallscreen=GETPOST('dol_optimize_smallscreen','int'); - $dol_no_mouse_hover=GETPOST('dol_no_mouse_hover','int'); - $dol_use_jmobile=GETPOST('dol_use_jmobile','int'); - - // Include login page template - include $template_dir.'login.tpl.php'; - - - $_SESSION["dol_loginmesg"] = ''; } /** diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 62200405c60..35145db8320 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -46,6 +46,7 @@ $disablenofollow=1; if (! preg_match('/'.constant('DOL_APPLICATION_TITLE').'/', $title)) $disablenofollow=0; print top_htmlhead('', $titleofloginpage, 0, 0, $arrayofjs, array(), 0, $disablenofollow); + ?> diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1cf0a18e3a1..e593068826b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -153,7 +153,11 @@ function analyseVarsForSqlAndScriptsInjection(&$var, $type) // Check consistency of NOREQUIREXXX DEFINES -if ((defined('NOREQUIREDB') || defined('NOREQUIRETRAN')) && ! defined('NOREQUIREMENU')) dol_print_error('','If define NOREQUIREDB or NOREQUIRETRAN are set, you must also set NOREQUIREMENU or not use them'); +if ((defined('NOREQUIREDB') || defined('NOREQUIRETRAN')) && ! defined('NOREQUIREMENU')) +{ + print 'If define NOREQUIREDB or NOREQUIRETRAN are set, you must also set NOREQUIREMENU or not set them'; + exit; +} // Sanity check on URL if (! empty($_SERVER["PHP_SELF"])) @@ -204,7 +208,7 @@ if (! empty($_POST["DOL_AUTOSET_COOKIE"])) } // Init session. Name of session is specific to Dolibarr instance. -$prefix=dol_getprefix(); +$prefix=dol_getprefix(''); $sessionname='DOLSESSID_'.$prefix; $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; if (! empty($_COOKIE[$sessiontimeout])) ini_set('session.gc_maxlifetime',$_COOKIE[$sessiontimeout]); @@ -479,6 +483,7 @@ if (! defined('NOLOGIN')) include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php'; $langs=new Translate("",$conf); $langcode=(GETPOST('lang','aZ09',1)?GETPOST('lang','aZ09',1):(empty($conf->global->MAIN_LANG_DEFAULT)?'auto':$conf->global->MAIN_LANG_DEFAULT)); + if (defined('MAIN_LANG_DEFAULT')) $langcode=constant('MAIN_LANG_DEFAULT'); $langs->setDefaultLang($langcode); } @@ -1164,6 +1169,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs } } } + //print 'themepath='.$themepath.' themeparam='.$themeparam;exit; print ''."\n"; if (! empty($conf->global->MAIN_FIX_FLASH_ON_CHROME)) print ''."\n".''."\n"; diff --git a/htdocs/user/logout.php b/htdocs/user/logout.php index 8aac6037f65..5958c71f295 100644 --- a/htdocs/user/logout.php +++ b/htdocs/user/logout.php @@ -63,7 +63,7 @@ if (GETPOST('dol_no_mouse_hover')) $url.=(preg_match('/\?/',$url)?'&':'?') if (GETPOST('dol_use_jmobile')) $url.=(preg_match('/\?/',$url)?'&':'?').'dol_use_jmobile=1'; // Destroy session -$prefix=dol_getprefix(); +$prefix=dol_getprefix(''); $sessionname='DOLSESSID_'.$prefix; $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; if (! empty($_COOKIE[$sessiontimeout])) ini_set('session.gc_maxlifetime',$_COOKIE[$sessiontimeout]); diff --git a/htdocs/user/passwordforgotten.php b/htdocs/user/passwordforgotten.php index 43cb5097bba..4f93a0d2401 100644 --- a/htdocs/user/passwordforgotten.php +++ b/htdocs/user/passwordforgotten.php @@ -169,6 +169,7 @@ else } // Note: $conf->css looks like '/theme/eldy/style.css.php' +/* $conf->css = "/theme/".(GETPOST('theme','alpha')?GETPOST('theme','alpha'):$conf->theme)."/style.css.php"; $themepath=dol_buildpath($conf->css,1); if (! empty($conf->modules_parts['theme'])) // This slow down @@ -183,6 +184,7 @@ if (! empty($conf->modules_parts['theme'])) // This slow down } } $conf_css = $themepath."?lang=".$langs->defaultlang; +*/ $jquerytheme = 'smoothness'; if (! empty($conf->global->MAIN_USE_JQUERY_THEME)) $jquerytheme = $conf->global->MAIN_USE_JQUERY_THEME; From 91932838ef831591054873526d7ced24972f1804 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 00:24:38 +0100 Subject: [PATCH 023/429] Fix constant MAIN_LANG_DEFAULT not used --- htdocs/main.inc.php | 1 - htdocs/master.inc.php | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index e593068826b..6d71c35a4df 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -365,7 +365,6 @@ if (! empty($_SESSION["disablemodules"])) } } - /* * Phase authentication / login */ diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php index ce3080e32e4..52c4c9780c7 100644 --- a/htdocs/master.inc.php +++ b/htdocs/master.inc.php @@ -235,7 +235,8 @@ if (! defined('NOREQUIREDB') && ! defined('NOREQUIRESOC')) if (! defined('NOREQUIRETRAN')) { $langcode=(GETPOST('lang','aZ09')?GETPOST('lang','aZ09',1):(empty($conf->global->MAIN_LANG_DEFAULT)?'auto':$conf->global->MAIN_LANG_DEFAULT)); - $langs->setDefaultLang($langcode); + if (defined('MAIN_LANG_DEFAULT')) $langcode=constant('MAIN_LANG_DEFAULT'); + $langs->setDefaultLang($langcode); } From fcf04c122fa6f8d98380563f3b31b5cc9e0ea7a0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 00:39:01 +0100 Subject: [PATCH 024/429] Fix phpcs --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 6def698a916..3cccffa2518 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3730,7 +3730,7 @@ else if ($id > 0 || ! empty($ref)) else { var revenue_type = parseFloat(valselected); - var amount_net = ".round($object->total_ht , 2)."; + var amount_net = ".round($object->total_ht, 2)."; revenue = revenue_type * amount_net / 100; revenue = revenue.toFixed(2); } From 89a62103cad20316e777feace8dbc359849db2c2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 11:40:29 +0100 Subject: [PATCH 025/429] Debug module website --- htdocs/admin/website.php | 101 ++++---- htdocs/core/lib/website.lib.php | 234 +++++++++++++++++- htdocs/langs/en_US/website.lang | 8 +- htdocs/website/class/website.class.php | 4 +- htdocs/website/index.php | 315 +++++-------------------- 5 files changed, 350 insertions(+), 312 deletions(-) diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index a6dd48f1947..1ddac653748 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -26,6 +26,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; @@ -116,6 +117,11 @@ $tabfieldcheck[1] = array(); $elementList = array(); $sourceList=array(); + +/* + * Actions + */ + // Actions add or modify a website if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha')) { @@ -128,19 +134,20 @@ if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha')) $ok=1; foreach ($listfield as $f => $value) { - if ((! isset($_POST[$value]) || $_POST[$value]=='') - && (! in_array($listfield[$f], array('virtualhost')))) // Fields that are not mandatory - { - $ok=0; - $fieldnamekey=$listfield[$f]; - setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); - } - if ($value == 'ref' && ! preg_match('/^[a-z0-9_\-\.]+$/i', $_POST[$value])) - { + if ($value == 'ref' && (! isset($_POST[$value]) || $_POST[$value]=='')) + { + $ok=0; + $fieldnamekey=$listfield[$f]; + setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); + break; + } + elseif ($value == 'ref' && ! preg_match('/^[a-z0-9_\-\.]+$/i', $_POST[$value])) + { $ok=0; - $fieldnamekey=$listfield[$f]; + $fieldnamekey=$listfield[$f]; setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities($fieldnamekey)), null, 'errors'); - } + break; + } } // Clean parameters @@ -206,29 +213,6 @@ if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha')) $result = $db->query($sql); if ($result) // Add is ok { - global $dolibarr_main_data_root; - $pathofwebsite=$dolibarr_main_data_root.'/website/'.$websitekey; - $filehtmlheader=$pathofwebsite.'/htmlheader.html'; - $filecss=$pathofwebsite.'/styles.css.php'; - $filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php'; - $fileindex=$pathofwebsite.'/index.php'; - - // Css file - $csscontent = ''."\n"; - $csscontent.= ''."\n"; - $csscontent.= '"."\n"; - $csscontent.= ''."\n"; - $csscontent.= 'body { margin: 0; }'."\n"; - - dol_syslog("Save file css into ".$filecss); - - dol_mkdir($pathofwebsite); - $result = file_put_contents($filecss, $csscontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filecss, octdec($conf->global->MAIN_UMASK)); - setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); unset($_POST); // Clean $_POST array, we keep only } @@ -335,21 +319,36 @@ if ($action == 'confirm_delete' && $confirm == 'yes') // delete if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } else { $rowidcol="rowid"; } - $sql = "DELETE from ".MAIN_DB_PREFIX."website_page WHERE fk_website ='".$rowid."'"; - $result = $db->query($sql); + $website = new Website($db); + $website->fetch($rowid); - $sql = "DELETE from ".MAIN_DB_PREFIX."website WHERE rowid ='".$rowid."'"; - $result = $db->query($sql); - if (! $result) + if ($website->id > 0) { - if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') - { - setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); - } - else - { - dol_print_error($db); - } + $sql = "DELETE from ".MAIN_DB_PREFIX."website_page WHERE fk_website ='".$rowid."'"; + $result = $db->query($sql); + + $sql = "DELETE from ".MAIN_DB_PREFIX."website WHERE rowid ='".$rowid."'"; + $result = $db->query($sql); + if (! $result) + { + if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') + { + setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); + } + else + { + dol_print_error($db); + } + } + + if ($website->ref) + { + dol_delete_dir_recursive($conf->website->dir_output.'/'.$website->ref); + } + } + else + { + dol_print_error($db, 'Failed to load website with id '.$rowid); } } @@ -618,7 +617,8 @@ if ($id) } // Can an entry be erased or disabled ? - $iserasable=1;$isdisable=1; // true by default + $iserasable=1; $isdisable=1; // true by default + if ($obj->status) $iserasable=0; // We can't delete a website on. Disable it first. $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):'').'&'; @@ -628,12 +628,11 @@ if ($id) print ""; // Modify link - if ($iserasable) print ''.img_edit().''; - else print ' '; + print ''.img_edit().''; // Delete link if ($iserasable) print ''.img_delete().''; - else print ' '; + else print ''.img_delete($langs->trans("DisableSiteFirst"), 'class="opacitymedium"').''; print "\n"; } diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 9dc1b2c3863..197e050f48a 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -368,6 +368,238 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify $tmp = preg_replace('/'.preg_quote($regs[0][$key],'/').'/i', 'background'.$regs[1][$key].'url("'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file='.$filename.'")', $tmp); } } - } + + +/** + * Save content of a page on disk + * + * @param string $filealias Full path of filename to generate + * @param Website $object Object website + * @param WebsitePage $objectpage Object websitepage + * @return boolean True if OK + */ +function dolSavePageAlias($filealias, $object, $objectpage) +{ + global $conf; + + // Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header) + dol_syslog("We regenerate the alias page filealias=".$filealias); + + $aliascontent = 'id.'.tpl.php\'; '; + $aliascontent.= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n"; + $aliascontent.= '?>'."\n"; + $result = file_put_contents($filealias, $aliascontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filealias, octdec($conf->global->MAIN_UMASK)); + + return ($result?true:false); +} + + +/** + * Save content of a page on disk + * + * @param string $filetpl Full path of filename to generate + * @param Website $object Object website + * @param WebsitePage $objectpage Object websitepage + * @return boolean True if OK + */ +function dolSavePageContent($filetpl, $object, $objectpage) +{ + global $conf; + + // Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header) + dol_syslog("We regenerate the tpl page filetpl=".$filetpl); + + dol_delete_file($filetpl); + + $shortlangcode = ''; + if ($objectpage->lang) $shortlangcode=preg_replace('/[_-].*$/', '', $objectpage->lang); // en_US or en-US -> en + + $tplcontent =''; + $tplcontent.= "\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= 'ref.'/htmlheader.html"); ?>'."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= $objectpage->htmlheader."\n"; + $tplcontent.= ''."\n"; + + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= $objectpage->content."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + + $tplcontent.= '"."\n"; + + //var_dump($filetpl);exit; + $result = file_put_contents($filetpl, $tplcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + + return $result; +} + + +/** + * Save content of a page on disk + * + * @param string $filehtmlheader Full path of filename to generate + * @param string $htmlheadercontent Content of file + * @return boolean True if OK + */ +function dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save html header into ".$filehtmlheader); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filehtmlheader, $htmlheadercontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filehtmlheader, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors'); + return false; + } + + return true; +} + +/** + * Save content of a page on disk + * + * @param string $filecss Full path of filename to generate + * @param string $csscontent Content of file + * @return boolean True if OK + */ +function dolSaveCssFile($filecss, $csscontent) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save css file into ".$filecss); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filecss, $csscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filecss, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + setEventMessages('Failed to write file '.$filecss, null, 'errors'); + return false; + } + + return true; +} + +/** + * Save content of a page on disk + * + * @param string $filejs Full path of filename to generate + * @param string $jscontent Content of file + * @return boolean True if OK + */ +function dolSaveJsFile($filejs, $jscontent) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save js file into ".$filejs); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filejs, $jscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filejs, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + setEventMessages('Failed to write file '.$filejs, null, 'errors'); + return false; + } + + return true; +} + +/** + * Save content of a page on disk + * + * @param string $filerobot Full path of filename to generate + * @param string $robotcontent Content of file + * @return boolean True if OK + */ +function dolSaveRobotFile($filerobot, $robotcontent) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save robot file into ".$filerobot); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filerobot, $robotcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filerobot, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + setEventMessages('Failed to write file '.$filerobot, null, 'errors'); + return false; + } + + return true; +} + +/** + * Save content of a page on disk + * + * @param string $filehtaccess Full path of filename to generate + * @param string $htaccess Content of file + * @return boolean True if OK + */ +function dolSaveHtaccessFile($filehtaccess, $htaccess) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save htaccess file into ".$filehtaccess); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filehtaccess, $htaccess); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filehtaccess, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + setEventMessages('Failed to write file '.$filehtaccess, null, 'errors'); + return false; + } + + return true; +} + + diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 326228b7e45..5b50bcc7ad3 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -5,14 +5,15 @@ DeleteWebsite=Delete website ConfirmDeleteWebsite=Are you sure you want to delete this web site. All its pages and content will also be removed. WEBSITE_TYPE_CONTAINER=Type of page/container WEBSITE_PAGENAME=Page name/alias -HtmlHeaderPage=HTML specific header for page WEBSITE_CSS_URL=URL of external CSS file WEBSITE_CSS_INLINE=CSS file content (common to all pages) WEBSITE_JS_INLINE=Javascript file content (common to all pages) WEBSITE_HTML_HEADER=Addition at bottom of HTML Header (common to all pages) WEBSITE_ROBOT=Robot file (robots.txt) WEBSITE_HTACCESS=Web site .htaccess file -PageNameAliasHelp=Name or alias of the page.
This alias is also used to forge a SEO URL when website is ran from a Virtual host of a Web server (like Apacke, Nginx, ...). Use the button "%s" to edit this alias. +HtmlHeaderPage=HTML header (specific to this page only) +PageNameAliasHelp=Name or alias of the page.
This alias is also used to forge a SEO URL when website is ran from a Virtual host of a Web server (like Apacke, Nginx, ...). Use the button "%s" to edit this alias. +EditTheWebSiteForACommonHeader=Note: If you want to define a personalized header for all pages, edit the header on the site level instead of on the page/container. MediaFiles=Media library EditCss=Edit Style/CSS or HTML header EditMenu=Edit menu @@ -59,4 +60,5 @@ BlogPost=Blog post WebsiteAccount=Web site account WebsiteAccounts=Web site accounts AddWebsiteAccount=Create web site account -BackToListOfThirdParty=Back to list for Third Party \ No newline at end of file +BackToListOfThirdParty=Back to list for Third Party +DisableSiteFirst=Disable website first \ No newline at end of file diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 2a1af0f2a80..1291e54840c 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -107,6 +107,8 @@ class Website extends CommonObject */ public function create(User $user, $notrigger = false) { + global $conf; + dol_syslog(__METHOD__, LOG_DEBUG); $error = 0; @@ -129,7 +131,7 @@ class Website extends CommonObject if (empty($this->date_modification)) $this->date_modification = $now; // Check parameters - // Put here code to add control on parameters values + if (empty($this->entity)) { $this->entity = $conf->entity; } // Insert request $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index d716fd4a9ad..3f50b9e9b4f 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -605,7 +605,7 @@ if ($action == 'addcontainer') if (! dol_is_file($filehtmlheader)) { - $htmlheadercontent = ""; + $htmlheadercontent = "\n\n"; $result=dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent); } @@ -1616,7 +1616,7 @@ $head = array(); /* - * Edit mode + * Edit Site HTML header of CSS */ if ($action == 'editcss') @@ -1624,28 +1624,53 @@ if ($action == 'editcss') print '
'; print '
'; - - $csscontent = @file_get_contents($filecss); - // Clean the php css file to remove php code and get only css part - $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $csscontent); - $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); + if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) + { + $csscontent = @file_get_contents($filecss); + // Clean the php css file to remove php code and get only css part + $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $csscontent); + } + else + { + $csscontent = GETPOST('WEBSITE_CSS_INLINE'); + } if (! trim($csscontent)) $csscontent='/* CSS content (all pages) */'."\n".'body.bodywebsite { margin: 0; }'; - $jscontent = @file_get_contents($filejs); - // Clean the php js file to remove php code and get only js part - $jscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $jscontent); - $jscontent.= GETPOST('WEBSITE_JS_INLINE'); + if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) + { + $jscontent = @file_get_contents($filejs); + // Clean the php js file to remove php code and get only js part + $jscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $jscontent); + } + else + { + $jscontent = GETPOST('WEBSITE_JS_INLINE'); + } if (! trim($jscontent)) $jscontent='/* JS content (all pages) */'."\n"; - $htmlheader = @file_get_contents($filehtmlheader); - // Clean the php htmlheader file to remove php code and get only html part - $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htmlheader); - if (! trim($htmlheader)) $htmlheader=''; + if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) + { + $htmlheader = @file_get_contents($filehtmlheader); + // Clean the php htmlheader file to remove php code and get only html part + $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htmlheader); + } + else + { + $htmlheader = GETPOST('WEBSITE_HTML_HEADER'); + } + if (! trim($htmlheader)) $htmlheader="\n\n"; else $htmlheader=''."\n".trim($htmlheader)."\n".''; - $robotcontent = @file_get_contents($filerobot); - // Clean the php htmlheader file to remove php code and get only html part - $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $robotcontent); + if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) + { + $robotcontent = @file_get_contents($filerobot); + // Clean the php htmlheader file to remove php code and get only html part + $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $robotcontent); + } + else + { + $robotcontent = GETPOST('WEBSITE_ROBOT'); + } if (! trim($robotcontent)) { $robotcontent.="# Robot file. Generated with ".DOL_APPLICATION_TITLE."\n"; @@ -1654,9 +1679,16 @@ if ($action == 'editcss') $robotcontent.="Disallow: /administrator/\n"; } - $htaccesscontent = @file_get_contents($filehtaccess); - // Clean the php htaccesscontent file to remove php code and get only html part - $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htaccesscontent); + if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) + { + $htaccesscontent = @file_get_contents($filehtaccess); + // Clean the php htaccesscontent file to remove php code and get only html part + $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htaccesscontent); + } + else + { + $htaccesscontent = GETPOST('WEBSITE_HTACCESS'); + } if (! trim($htaccesscontent)) { $htaccesscontent.="# Order allow,deny\n"; @@ -1926,7 +1958,12 @@ if ($action == 'editmeta' || $action == 'createcontainer') print ''; print ''; - print $langs->trans('HtmlHeaderPage'); + $htmlhelp=$langs->trans("EditTheWebSiteForACommonHeader").'

'; + $htmlhelp.=$langs->trans("Example").' :
'; + $htmlhelp.='<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous" ></script>
'; + $htmlhelp.='<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" integrity="sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=" crossorigin="anonymous" ></script>
'; + $htmlhelp.='<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
'; + print $form->textwithpicto($langs->trans('HtmlHeaderPage'), $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip'); print ''; $doleditor=new DolEditor('htmlheader', $pagehtmlheader, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'HTML Header', 'html'); @@ -2101,237 +2138,3 @@ if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpa llxFooter(); $db->close(); - - - - -/** - * Save content of a page on disk - * - * @param string $filealias Full path of filename to generate - * @param Website $object Object website - * @param WebsitePage $objectpage Object websitepage - * @return boolean True if OK - */ -function dolSavePageAlias($filealias, $object, $objectpage) -{ - global $conf; - - // Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header) - dol_syslog("We regenerate the alias page filealias=".$filealias); - - $aliascontent = 'id.'.tpl.php\'; '; - $aliascontent.= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n"; - $aliascontent.= '?>'."\n"; - $result = file_put_contents($filealias, $aliascontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filealias, octdec($conf->global->MAIN_UMASK)); - - return ($result?true:false); -} - - -/** - * Save content of a page on disk - * - * @param string $filetpl Full path of filename to generate - * @param Website $object Object website - * @param WebsitePage $objectpage Object websitepage - * @return boolean True if OK - */ -function dolSavePageContent($filetpl, $object, $objectpage) -{ - global $conf; - - // Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header) - dol_syslog("We regenerate the tpl page filetpl=".$filetpl); - - dol_delete_file($filetpl); - - $shortlangcode = ''; - if ($objectpage->lang) $shortlangcode=preg_replace('/[_-].*$/', '', $objectpage->lang); // en_US or en-US -> en - - $tplcontent =''; - $tplcontent.= "\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= 'ref.'/htmlheader.html"); ?>'."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= $objectpage->htmlheader."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= $objectpage->content."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= '"."\n"; - - //var_dump($filetpl);exit; - $result = file_put_contents($filetpl, $tplcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); - - return $result; -} - - -/** - * Save content of a page on disk - * - * @param string $filehtmlheader Full path of filename to generate - * @param string $htmlheadercontent Content of file - * @return boolean True if OK - */ -function dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent) -{ - global $conf, $pathofwebsite; - - dol_syslog("Save html header into ".$filehtmlheader); - - dol_mkdir($pathofwebsite); - $result = file_put_contents($filehtmlheader, $htmlheadercontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filehtmlheader, octdec($conf->global->MAIN_UMASK)); - - if (! $result) - { - setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors'); - return false; - } - - return true; -} - -/** - * Save content of a page on disk - * - * @param string $filecss Full path of filename to generate - * @param string $csscontent Content of file - * @return boolean True if OK - */ -function dolSaveCssFile($filecss, $csscontent) -{ - global $conf, $pathofwebsite; - - dol_syslog("Save html header into ".$filecss); - - dol_mkdir($pathofwebsite); - $result = file_put_contents($filecss, $csscontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filecss, octdec($conf->global->MAIN_UMASK)); - - if (! $result) - { - setEventMessages('Failed to write file '.$filecss, null, 'errors'); - return false; - } - - return true; -} - -/** - * Save content of a page on disk - * - * @param string $filejs Full path of filename to generate - * @param string $jscontent Content of file - * @return boolean True if OK - */ -function dolSaveJsFile($filejs, $jscontent) -{ - global $conf, $pathofwebsite; - - dol_syslog("Save html header into ".$filejs); - - dol_mkdir($pathofwebsite); - $result = file_put_contents($filejs, $jscontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filejs, octdec($conf->global->MAIN_UMASK)); - - if (! $result) - { - setEventMessages('Failed to write file '.$filejs, null, 'errors'); - return false; - } - - return true; -} - -/** - * Save content of a page on disk - * - * @param string $filerobot Full path of filename to generate - * @param string $robotcontent Content of file - * @return boolean True if OK - */ -function dolSaveRobotFile($filerobot, $robotcontent) -{ - global $conf, $pathofwebsite; - - dol_syslog("Save html header into ".$filerobot); - - dol_mkdir($pathofwebsite); - $result = file_put_contents($filerobot, $robotcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filerobot, octdec($conf->global->MAIN_UMASK)); - - if (! $result) - { - setEventMessages('Failed to write file '.$filerobot, null, 'errors'); - return false; - } - - return true; -} - -/** - * Save content of a page on disk - * - * @param string $filehtaccess Full path of filename to generate - * @param string $htaccess Content of file - * @return boolean True if OK - */ -function dolSaveHtaccessFile($filehtaccess, $htaccess) -{ - global $conf, $pathofwebsite; - - dol_syslog("Save html header into ".$filehtaccess); - - dol_mkdir($pathofwebsite); - $result = file_put_contents($filehtaccess, $htaccess); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filehtaccess, octdec($conf->global->MAIN_UMASK)); - - if (! $result) - { - setEventMessages('Failed to write file '.$filehtaccess, null, 'errors'); - return false; - } - - return true; -} - From e90183f4bafd3496fdb50d8be08c636c52e456fa Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 19 Dec 2017 12:37:37 +0100 Subject: [PATCH 026/429] NEW Update end of validity date of proposal using the API Add the ability to update the end of validity date when modifying a proposal --- htdocs/comm/propal/class/api_proposals.class.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index cb0e94cf88f..204d4c12dc4 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -423,6 +423,19 @@ class Proposals extends DolibarrApi $this->propal->$field = $value; } + // update end of validity date + if(!empty($this->propal->duree_validite) && !empty($this->propal->date_creation) ) + { + $this->propal->fin_validite = $this->propal->date_creation + ($this->propal->duree_validite * 24 * 3600); + } + if(!empty($this->propal->fin_validite)) + { + if($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite)<0) + { + throw new RestException(500, $this->propal->error); + } + } + if ($this->propal->update(DolibarrApiAccess::$user) > 0) { return $this->get($id); From feaff433b865dd1e7e1280838dd2009c23266b57 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 12:54:10 +0100 Subject: [PATCH 027/429] Debug module website --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/langs/en_US/website.lang | 4 +++- htdocs/website/index.php | 33 +++++++++++++++++++++---------- htdocs/website/pagetemplate.html | 15 ++++++++++++++ 4 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 htdocs/website/pagetemplate.html diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b0b67b2fb8d..4cb19f6dc7e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5595,7 +5595,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob * Make substition into a text string, replacing keys with vals from $substitutionarray (oldval=>newval). * * @param string $text Source string in which we must do substitution - * @param array $substitutionarray Array with key->val to substitute + * @param array $substitutionarray Array with key->val to substitute. Example: array('__MYKEY__' => 'MyVal') * @param Translate $outputlangs Output language * @return string Output string after substitutions * @see complete_substitutions_array diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 5b50bcc7ad3..a329661a056 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -61,4 +61,6 @@ WebsiteAccount=Web site account WebsiteAccounts=Web site accounts AddWebsiteAccount=Create web site account BackToListOfThirdParty=Back to list for Third Party -DisableSiteFirst=Disable website first \ No newline at end of file +DisableSiteFirst=Disable website first +MyContainerTitle=My web site title +AnotherContainer=Another container diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 3f50b9e9b4f..96120b278c1 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -514,7 +514,9 @@ if ($action == 'addcontainer') $objectpage->lang = GETPOST('WEBSITE_LANG','aZ09'); $objectpage->htmlheader = GETPOST('htmlheader','none'); - $objectpage->content = '

'.$langs->trans("MyContainerTitle").'

'.$langs->trans("MyContainerContent").'


'; + $substitutionarray=array(); + $substitutionarray['__WEBSITE_CREATE_BY__']=$user->getFullName($langs); + $objectpage->content = make_substitutions(file_get_contents(DOL_DOCUMENT_ROOT.'/website/pagetemplate.html'), $substitutionarray); } if (! $error) @@ -605,13 +607,17 @@ if ($action == 'addcontainer') if (! dol_is_file($filehtmlheader)) { - $htmlheadercontent = "\n\n"; + $htmlheadercontent ="\n"; + $htmlheadercontent.=''."\n"; + $htmlheadercontent.=''."\n"; + $htmlheadercontent.=''."\n"; + $htmlheadercontent.=""; $result=dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent); } if (! dol_is_file($filecss)) { - $csscontent = "/* CSS content (all pages) */\nbody.bodywebsite { margin: 0; }"; + $csscontent = "/* CSS content (all pages) */\nbody.bodywebsite { margin: 0; font-family: 'Open Sans', sans-serif; }\n.bodywebsite h1 { margin-top: 0; margin-bottom: 0; padding: 10px;}"; $result=dolSaveCssFile($filecss, $csscontent); } @@ -1634,7 +1640,7 @@ if ($action == 'editcss') { $csscontent = GETPOST('WEBSITE_CSS_INLINE'); } - if (! trim($csscontent)) $csscontent='/* CSS content (all pages) */'."\n".'body.bodywebsite { margin: 0; }'; + if (! trim($csscontent)) $csscontent='/* CSS content (all pages) */'."\n"."body.bodywebsite { margin: 0; font-family: 'Open Sans', sans-serif; }\n.bodywebsite h1 { margin-top: 0; margin-bottom: 0; padding: 10px;}"; if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) { @@ -1650,16 +1656,23 @@ if ($action == 'editcss') if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) { - $htmlheader = @file_get_contents($filehtmlheader); + $htmlheadercontent = @file_get_contents($filehtmlheader); // Clean the php htmlheader file to remove php code and get only html part - $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htmlheader); + $htmlheadercontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htmlheadercontent); } else { - $htmlheader = GETPOST('WEBSITE_HTML_HEADER'); + $htmlheadercontent = GETPOST('WEBSITE_HTML_HEADER'); } - if (! trim($htmlheader)) $htmlheader="\n\n"; - else $htmlheader=''."\n".trim($htmlheader)."\n".''; + if (! trim($htmlheadercontent)) + { + $htmlheadercontent ="\n"; + $htmlheadercontent.=''."\n"; + $htmlheadercontent.=''."\n"; + $htmlheadercontent.=''."\n"; + $htmlheadercontent.=""; + } + else $htmlheadercontent=''."\n".trim($htmlheadercontent)."\n".''; if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) { @@ -1737,7 +1750,7 @@ if ($action == 'editcss') print $form->textwithpicto($langs->trans('WEBSITE_HTML_HEADER'), $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip'); print ''; - $doleditor=new DolEditor('WEBSITE_HTML_HEADER', $htmlheader, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + $doleditor=new DolEditor('WEBSITE_HTML_HEADER', $htmlheadercontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'HTML Header', 'html'); print ''; diff --git a/htdocs/website/pagetemplate.html b/htdocs/website/pagetemplate.html new file mode 100644 index 00000000000..a6e4e64c871 --- /dev/null +++ b/htdocs/website/pagetemplate.html @@ -0,0 +1,15 @@ +
+

__[MAIN_INFO_SOCIETE_NOM]__


+__(MyContainerTitle)__ +
+
+
+
+
__(AnotherContainer)__
+
+
+
+
+
__WEBSITE_CREATE_BY__
+
+
\ No newline at end of file From 7e3a2d75bb186303ad722ab5031a016813c5f866 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 19 Dec 2017 13:06:28 +0100 Subject: [PATCH 028/429] FIX Error when classify the order as invoiced unsing API Remove of notrigger parameter. The notrigger attribute caused a type error when used. --- htdocs/commande/class/api_orders.class.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 0b508b59f31..1b080c4e995 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -559,7 +559,6 @@ class Orders extends DolibarrApi * Classify the order as invoiced * * @param int $id Id of the order - * @param int $notrigger {@from body} 1=Does not execute triggers, 0= execute triggers {@choice 0,1} * * @url POST {id}/setinvoiced * @@ -570,7 +569,7 @@ class Orders extends DolibarrApi * @throws 404 * @throws 405 */ - function setinvoiced($id,$notrigger=0) { + function setinvoiced($id) { if(! DolibarrApiAccess::$user->rights->commande->creer) { throw new RestException(401); @@ -583,7 +582,7 @@ class Orders extends DolibarrApi throw new RestException(404, 'Order not found'); } - $result = $this->commande->classifyBilled(DolibarrApiAccess::$user,$notrigger); + $result = $this->commande->classifyBilled(DolibarrApiAccess::$user); if( $result < 0) { throw new RestException(400, $this->commande->error); } From a3f40667900da18679bd44dacaae88456e6c044b Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 19 Dec 2017 14:14:26 +0100 Subject: [PATCH 029/429] NEW Update bank account when updating an invoice Add the ability to update the bankaccount when updating an invoice --- htdocs/compta/facture/class/api_invoices.class.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 34935c3088a..1e0392bf452 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -422,6 +422,15 @@ class Invoices extends DolibarrApi $this->invoice->$field = $value; } + // update bank account + if(!empty($this->invoice->fk_account)) + { + if($this->invoice->setBankAccount($this->invoice->fk_account) == 0) + { + throw new RestException(400,$this->invoice->error); + } + } + if($this->invoice->update($id, DolibarrApiAccess::$user)) return $this->get ($id); From 171e388f6df562c1d2b2cad538304bee17830840 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 19 Dec 2017 14:16:51 +0100 Subject: [PATCH 030/429] NEW Update bank account when updating an order Add the ability to update the bankaccount when updating an order --- htdocs/commande/class/api_orders.class.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 1b080c4e995..c15befe46e2 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -418,6 +418,15 @@ class Orders extends DolibarrApi if ($this->commande->availability($this->commande->availability_id) < 0) throw new RestException(400, 'Error while updating availability'); } + // update bank account + if(!empty($this->commande->fk_account)) + { + if($this->commande->setBankAccount($this->commande->fk_account) == 0) + { + throw new RestException(400,$this->commande->error); + } + } + if ($this->commande->update(DolibarrApiAccess::$user) > 0) { From f504716501adf9c9cd4ee8fe6a0c827dc8ed837a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 16:16:31 +0100 Subject: [PATCH 031/429] Fix sync contact - external user --- htdocs/contact/class/contact.class.php | 68 +++- htdocs/core/class/commonobject.class.php | 8 +- htdocs/user/card.php | 455 ++++++++++++----------- htdocs/user/class/user.class.php | 64 +++- htdocs/website/index.php | 9 +- 5 files changed, 370 insertions(+), 234 deletions(-) diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 494533fce75..08fe253dffd 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -267,9 +267,10 @@ class Contact extends CommonObject * @param User $user Objet user making change * @param int $notrigger 0=no, 1=yes * @param string $action Current action for hookmanager + * @param int $nosyncuser No sync linked user (external users and contacts are linked) * @return int <0 if KO, >0 if OK */ - function update($id, $user=null, $notrigger=0, $action='update') + function update($id, $user=null, $notrigger=0, $action='update', $nosyncuser=0) { global $conf, $langs, $hookmanager; @@ -353,12 +354,69 @@ class Contact extends CommonObject } else if ($reshook < 0) $error++; + if (! $error && $this->user_id > 0) + { + $tmpobj = new User($this->db); + $tmpobj->fetch($this->user_id); + $usermustbemodified = 0; + if ($tmpobj->office_phone != $this->phone_pro) + { + $tmpobj->office_phone = $this->phone_pro; + $usermustbemodified++; + } + if ($tmpobj->office_fax != $this->fax) + { + $tmpobj->office_fax = $this->fax; + $usermustbemodified++; + } + if ($tmpobj->address != $this->address) + { + $tmpobj->address = $this->address; + $usermustbemodified++; + } + if ($tmpobj->town != $this->town) + { + $tmpobj->town = $this->town; + $usermustbemodified++; + } + if ($tmpobj->zip != $this->zip) + { + $tmpobj->zip = $this->zip; + $usermustbemodified++; + } + if ($tmpobj->zip != $this->zip) + { + $tmpobj->state_id=$this->state_id; + $usermustbemodified++; + } + if ($tmpobj->country_id != $this->country_id) + { + $tmpobj->country_id = $this->country_id; + $usermustbemodified++; + } + if ($tmpobj->email != $this->email) + { + $tmpobj->email = $this->email; + $usermustbemodified++; + } + if ($tmpobj->skype != $this->skype) + { + $tmpobj->skype = $this->skype; + $usermustbemodified++; + } + if ($usermustbemodified) + { + $result=$tmpobj->update($user, 0, 1, 1, 1); + if ($result < 0) { $error++; } + } + } + if (! $error && ! $notrigger) { - // Call trigger - $result=$this->call_trigger('CONTACT_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('CONTACT_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers } if (! $error) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 25d9f67a219..a375593dc2d 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -505,18 +505,18 @@ abstract class CommonObject if (! empty($this->phone_perso)) { $out.=dol_print_phone($this->phone_perso,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePerso")); $outdone++; } - if (! empty($this->fax)) { - $out.=dol_print_phone($this->fax,$this->country_code,$contactid,$thirdpartyid,'AC_FAX',' ','fax',$langs->trans("Fax")); $outdone++; - } if (! empty($this->office_phone)) { $out.=dol_print_phone($this->office_phone,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePro")); $outdone++; } if (! empty($this->user_mobile)) { $out.=dol_print_phone($this->user_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','mobile',$langs->trans("PhoneMobile")); $outdone++; } - if (! empty($this->office_fax)) { + if (! empty($this->fax)) { $out.=dol_print_phone($this->fax,$this->country_code,$contactid,$thirdpartyid,'AC_FAX',' ','fax',$langs->trans("Fax")); $outdone++; } + if (! empty($this->office_fax)) { + $out.=dol_print_phone($this->office_fax,$this->country_code,$contactid,$thirdpartyid,'AC_FAX',' ','fax',$langs->trans("Fax")); $outdone++; + } $out.='
'; $outdone=0; diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 6444faa3958..7b5a9f29be4 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -413,7 +413,7 @@ if (empty($reshook)) { } if (!$error && GETPOSTISSET('contactid')) { - $contactid = GETPOST('contactid', 'int'); + $contactid = GETPOST('contactid', 'int'); if ($contactid > 0) { $contact = new Contact($db); @@ -765,33 +765,6 @@ if ($action == 'create' || $action == 'adduserldap') } print ''; - // Employee - $defaultemployee=1; - print ''; - print ''.$langs->trans('Employee').''; - print $form->selectyesno("employee",(GETPOST('employee')!=''?GETPOST('employee'):$defaultemployee),1); - print ''; - - // Position/Job - print ''.$langs->trans("PostOrFunction").''; - print ''; - print ''; - print ''; - - // Gender - print ''.$langs->trans("Gender").''; - print ''; - $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); - print $form->selectarray('gender', $arraygender, GETPOST('gender'), 1); - print ''; - - // Date employment - print ''.$langs->trans("DateToBirth").''; - print ''; - echo $form->select_date(GETPOST('birth'),'birth',0,0,1,'createuser',1,0,1); - print ''; - print "\n"; - // Login print ''.$langs->trans("Login").''; print ''; @@ -912,8 +885,33 @@ if ($action == 'create' || $action == 'adduserldap') print $form->textwithpicto($langs->trans("Internal"),$langs->trans("InternalExternalDesc"), 1, 'help', '', 0, 2); print ''; + // Gender + print ''.$langs->trans("Gender").''; + print ''; + $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); + print $form->selectarray('gender', $arraygender, GETPOST('gender'), 1); + print ''; + + // Employee + $defaultemployee=1; + print ''; + print ''.$langs->trans('Employee').''; + print $form->selectyesno("employee",(GETPOST('employee')!=''?GETPOST('employee'):$defaultemployee),1); + print ''; + + // Hierarchy + print ''.$langs->trans("HierarchicalResponsible").''; + print ''; + print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $conf->entity, 0, 0, '', 0, '', 'maxwidth300'); + print ''; + print "\n"; + + + print '
'; + + // Address - print ''; + print ''; print ''; @@ -1024,62 +1022,6 @@ if ($action == 'create' || $action == 'adduserldap') print ''; } - // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) - - // Hierarchy - print ''; - print ''; - print "\n"; - - if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) - || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) - { - $langs->load("salaries"); - - // THM - print ''; - print ''; - print "\n"; - - // TJM - print ''; - print ''; - print "\n"; - - // Salary - print ''; - print ''; - print "\n"; - } - - // Weeklyhours - print ''; - print ''; - print "\n"; - - // Date employment - print ''; - print ''; - print "\n"; - // User color if (! empty($conf->agenda->enabled)) { @@ -1143,6 +1085,73 @@ if ($action == 'create' || $action == 'adduserldap') print $doleditor->Create(1); print ''; + + print '
'.fieldLabel('Address','address').'
'.fieldLabel('Address','address').'
'.$langs->trans("HierarchicalResponsible").''; - print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $conf->entity, 0, 0, '', 0, '', 'maxwidth300'); - print '
'; - $text=$langs->trans("THM"); - print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); - print ''; - print ''; - print '
'; - $text=$langs->trans("TJM"); - print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm'); - print ''; - print ''; - print '
'.$langs->trans("Salary").''; - print ''; - print '
'.$langs->trans("WeeklyHours").''; - print ''; - print '
'.$langs->trans("DateEmployment").''; - echo $form->select_date(GETPOST('dateemployment'),'dateemployment',0,0,1,'form'.'dateemployment',1,0,1); - print '

'; + + + // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) + + // Position/Job + print ''; + print ''; + + + if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) + || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) + { + $langs->load("salaries"); + + // THM + print ''; + print ''; + print "\n"; + + // TJM + print ''; + print ''; + print "\n"; + + // Salary + print ''; + print ''; + print "\n"; + } + + // Weeklyhours + print ''; + print ''; + print "\n"; + + // Date employment + print ''; + print ''; + print "\n"; + + // Date birth + print ''; + print ''; + print "\n"; + print "
'.$langs->trans("PostOrFunction").''; + print ''; + print '
'; + $text=$langs->trans("THM"); + print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); + print ''; + print ''; + print '
'; + $text=$langs->trans("TJM"); + print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm'); + print ''; + print ''; + print '
'.$langs->trans("Salary").''; + print ''; + print '
'.$langs->trans("WeeklyHours").''; + print ''; + print '
'.$langs->trans("DateEmployment").''; + echo $form->select_date(GETPOST('dateemployment'),'dateemployment',0,0,1,'form'.'dateemployment',1,0,1); + print '
'.$langs->trans("DateToBirth").''; + echo $form->select_date(GETPOST('birth'),'birth',0,0,1,'createuser',1,0,1); + print '
\n"; dol_fiche_end(); @@ -1337,31 +1346,8 @@ else } print ''."\n"; - // Employee - print ''.$langs->trans("Employee").''; - print yn($object->employee); - print ''."\n"; - - // Position/Job - print ''.$langs->trans("PostOrFunction").''; - print ''.$object->job.''; - print ''."\n"; - - // Gender - print ''.$langs->trans("Gender").''; - print ''; - if ($object->gender) print $langs->trans("Gender".$object->gender); - print ''; - - // Date of birth - print ''.$langs->trans("DateToBirth").''; - print ''; - print dol_print_date($object->birth, 'day'); - print ''; - print "\n"; - // API key - if(! empty($conf->api->enabled) && $user->admin) { + if (! empty($conf->api->enabled) && $user->admin) { print ''.$langs->trans("ApiKey").''; print ''; if (! empty($object->api_key)) print preg_replace('/./','*',$object->api_key); @@ -1403,12 +1389,16 @@ else print ''."\n"; } - // Accountancy code - if ($conf->accounting->enabled) - { - print ''.$langs->trans("AccountancyCode").''; - print ''.$object->accountancy_code.''; - } + // Gender + print ''.$langs->trans("Gender").''; + print ''; + if ($object->gender) print $langs->trans("Gender".$object->gender); + print ''; + + // Employee + print ''.$langs->trans("Employee").''; + print yn($object->employee); + print ''."\n"; // TODO Move this into tab RH, visible when salarie or RH is visible (HierarchicalResponsible must be on both tab) @@ -1424,6 +1414,11 @@ else print ''; print "\n"; + // Position/Job + print ''.$langs->trans("PostOrFunction").''; + print ''.$object->job.''; + print ''."\n"; + //$childids = $user->getAllChildIds(1); if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) @@ -1475,6 +1470,20 @@ else print ''; print "\n"; + // Date of birth + print ''.$langs->trans("DateToBirth").''; + print ''; + print dol_print_date($object->birth, 'day'); + print ''; + print "\n"; + + // Accountancy code + if ($conf->accounting->enabled) + { + print ''.$langs->trans("AccountancyCode").''; + print ''.$object->accountancy_code.''; + } + print ''; print '
'; @@ -1818,7 +1827,7 @@ else // Ref/ID if (! empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) { - print ''.$langs->trans("Ref").''; + print ''.$langs->trans("Ref").''; print ''; print $object->id; print ''; @@ -1827,7 +1836,7 @@ else // Lastname print ""; - print ''.$langs->trans("Lastname").''; + print ''.$langs->trans("Lastname").''; print ''; if ($caneditfield && !$object->ldap_sid) { @@ -1855,40 +1864,6 @@ else } print ''; - // Employee - print ''; - print ''.fieldLabel('Employee','employee',0).''; - print $form->selectyesno("employee",$object->employee,1); - print ''; - - // Position/Job - print ''.$langs->trans("PostOrFunction").''; - print ''; - if ($caneditfield) - { - print ''; - } - else - { - print ''; - print $object->job; - } - print ''; - - // Gender - print ''.$langs->trans("Gender").''; - print ''; - $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); - print $form->selectarray('gender', $arraygender, GETPOST('gender')?GETPOST('gender'):$object->gender, 1); - print ''; - - // Date birth - print ''.$langs->trans("DateToBirth").''; - print ''; - echo $form->select_date(GETPOST('birth')?GETPOST('birth'):$object->birth,'birth',0,0,1,'updateuser',1,0,1); - print ''; - print "\n"; - // Login print "".''.$langs->trans("Login").''; print ''; @@ -2039,8 +2014,42 @@ else } print ''; + // Gender + print ''.$langs->trans("Gender").''; + print ''; + $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); + print $form->selectarray('gender', $arraygender, GETPOST('gender')?GETPOST('gender'):$object->gender, 1); + print ''; + + // Employee + print ''; + print ''.fieldLabel('Employee','employee',0).''; + print $form->selectyesno("employee",$object->employee,1); + print ''; + + // Hierarchy + print ''.$langs->trans("HierarchicalResponsible").''; + print ''; + if ($caneditfield) + { + print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300'); + } + else + { + print ''; + $huser=new User($db); + $huser->fetch($object->fk_user); + print $huser->getNomUrl(1); + } + print ''; + print "\n"; + + + print '
'; + + // Address - print ''; + print ''; print ''; @@ -2159,6 +2168,8 @@ else print ''; } + print '
'.fieldLabel('Address','address').'
'.fieldLabel('Address','address').'

'; + // Accountancy code if ($conf->accounting->enabled) { @@ -2178,72 +2189,6 @@ else print ""; } - // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) - - // Hierarchy - print ''; - print ''; - print "\n"; - - if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) - || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) - { - $langs->load("salaries"); - - // THM - print ''; - print ''; - print "\n"; - - // TJM - print ''; - print ''; - print "\n"; - - // Salary - print ''; - print ''; - print "\n"; - } - - // Weeklyhours - print ''; - print ''; - print "\n"; - - // Date employment - print ''; - print ''; - print "\n"; - // User color if (! empty($conf->agenda->enabled)) { @@ -2372,6 +2317,80 @@ else } print ''; + + print '
'.$langs->trans("HierarchicalResponsible").''; - if ($caneditfield) - { - print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300'); - } - else - { - print ''; - $huser=new User($db); - $huser->fetch($object->fk_user); - print $huser->getNomUrl(1); - } - print '
'; - $text=$langs->trans("THM"); - print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); - print ''; - print ''; - print '
'; - $text=$langs->trans("TJM"); - print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classthm'); - print ''; - print ''; - print '
'.$langs->trans("Salary").''; - print ''; - print '
'.$langs->trans("WeeklyHours").''; - print ''; - print '
'.$langs->trans("DateEmployment").''; - echo $form->select_date(GETPOST('dateemployment')?GETPOST('dateemployment'):$object->dateemployment,'dateemployment',0,0,1,'form'.'dateemployment',1,0,1); - print '

'; + + + // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) + + // Position/Job + print ''; + print ''; + + if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) + || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) + { + $langs->load("salaries"); + + // THM + print ''; + print ''; + print "\n"; + + // TJM + print ''; + print ''; + print "\n"; + + // Salary + print ''; + print ''; + print "\n"; + } + + // Weeklyhours + print ''; + print ''; + print "\n"; + + // Date employment + print ''; + print ''; + print "\n"; + + // Date birth + print ''; + print ''; + print "\n"; + print '
'.$langs->trans("PostOrFunction").''; + if ($caneditfield) + { + print ''; + } + else + { + print ''; + print $object->job; + } + print '
'; + $text=$langs->trans("THM"); + print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); + print ''; + print ''; + print '
'; + $text=$langs->trans("TJM"); + print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classthm'); + print ''; + print ''; + print '
'.$langs->trans("Salary").''; + print ''; + print '
'.$langs->trans("WeeklyHours").''; + print ''; + print '
'.$langs->trans("DateEmployment").''; + echo $form->select_date(GETPOST('dateemployment')?GETPOST('dateemployment'):$object->dateemployment,'dateemployment',0,0,1,'form'.'dateemployment',1,0,1); + print '
'.$langs->trans("DateToBirth").''; + echo $form->select_date(GETPOST('birth')?GETPOST('birth'):$object->birth,'birth',0,0,1,'updateuser',1,0,1); + print '
'; dol_fiche_end(); diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index e7b31400bc0..f8b263b49a4 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1011,7 +1011,7 @@ class User extends CommonObject * @param int $notrigger 1=do not execute triggers, 0 otherwise * @return int <0 if KO, id of created user if OK */ - function create($user,$notrigger=0) + function create($user, $notrigger=0) { global $conf,$langs; global $mysoc; @@ -1337,9 +1337,10 @@ class User extends CommonObject * @param int $notrigger 1 ne declenche pas les triggers, 0 sinon * @param int $nosyncmember 0=Synchronize linked member (standard info), 1=Do not synchronize linked member * @param int $nosyncmemberpass 0=Synchronize linked member (password), 1=Do not synchronize linked member + * @param int $nosynccontact 0=Synchronize linked contact, 1=Do not synchronize linked contact * @return int <0 si KO, >=0 si OK */ - function update($user,$notrigger=0,$nosyncmember=0,$nosyncmemberpass=0) + function update($user, $notrigger=0, $nosyncmember=0, $nosyncmemberpass=0, $nosynccontact=0) { global $conf, $langs; @@ -1474,7 +1475,7 @@ class User extends CommonObject require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; - // This user is linked with a member, so we also update members informations + // This user is linked with a member, so we also update member information // if this is an update. $adh=new Adherent($this->db); $result=$adh->fetch($this->fk_member); @@ -1496,8 +1497,6 @@ class User extends CommonObject $adh->phone=$this->office_phone; $adh->phone_mobile=$this->user_mobile; - $adh->note=$this->note; - $adh->user_id=$this->id; $adh->user_login=$this->login; @@ -1517,6 +1516,61 @@ class User extends CommonObject $error++; } } + + if ($this->contact_id > 0 && ! $nosynccontact) + { + dol_syslog(get_class($this)."::update user is linked with a contact. We try to update contact too.", LOG_DEBUG); + + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + + // This user is linked with a contact, so we also update contact information + // if this is an update. + $tmpobj=new Contact($this->db); + $result=$tmpobj->fetch($this->contact_id); + + if ($result >= 0) + { + $tmpobj->firstname=$this->firstname; + $tmpobj->lastname=$this->lastname; + $tmpobj->login=$this->login; + $tmpobj->gender=$this->gender; + $tmpobj->birth=$this->birth; + + //$tmpobj->pass=$this->pass; + + //$tmpobj->societe=(empty($tmpobj->societe) && $this->societe_id ? $this->societe_id : $tmpobj->societe); + + $tmpobj->email=$this->email; + $tmpobj->skype=$this->skype; + $tmpobj->phone_pro=$this->office_phone; + $tmpobj->phone_mobile=$this->user_mobile; + $tmpobj->fax=$this->office_fax; + + $tmpobj->address=$this->address; + $tmpobj->town=$this->town; + $tmpobj->zip=$this->zip; + $tmpobj->state_id=$this->state_id; + $tmpobj->country_id=$this->country_id; + + $tmpobj->user_id=$this->id; + $tmpobj->user_login=$this->login; + + $result=$tmpobj->update($tmpobj->id, $user, 0, 'update', 1); + if ($result < 0) + { + $this->error=$tmpobj->error; + $this->errors=$tmpobj->errors; + dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR); + $error++; + } + } + else + { + $this->error=$tmpobj->error; + $this->errors=$tmpobj->errors; + $error++; + } + } } $action='update'; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 96120b278c1..505bfdc9a6a 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -1622,7 +1622,7 @@ $head = array(); /* - * Edit Site HTML header of CSS + * Edit Site HTML header and CSS */ if ($action == 'editcss') @@ -1672,7 +1672,12 @@ if ($action == 'editcss') $htmlheadercontent.=''."\n"; $htmlheadercontent.=""; } - else $htmlheadercontent=''."\n".trim($htmlheadercontent)."\n".''; + else + { + $htmlheadercontent = preg_replace('/^\s*/ims', '', $htmlheadercontent); + $htmlheadercontent = preg_replace('/<\/html>\s*$/ims', '', $htmlheadercontent); + $htmlheadercontent=''."\n".trim($htmlheadercontent)."\n".''; + } if (GETPOST('editcss','alpha') || GETPOST('refreshpage','alpha')) { From 01c99b780ef93fc9d5ddde055ca6c3ac1412f709 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 16:22:47 +0100 Subject: [PATCH 032/429] Fix missing index --- htdocs/install/mysql/migration/6.0.0-7.0.0.sql | 2 ++ .../install/mysql/tables/llx_accounting_bookkeeping.key.sql | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index f042cb83556..fea6c1a51e6 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -71,6 +71,8 @@ ALTER TABLE llx_website_page ADD COLUMN type_container varchar(16) NOT NULL DEFA -- For 7.0 +ALTER TABLE llx_accounting_bookkeeping ADD INDEX idx_accounting_bookkeeping_fk_doc (fk_doc); + ALTER TABLE llx_c_revenuestamp ADD COLUMN revenuestamp_type varchar(16) DEFAULT 'fixed' NOT NULL; UPDATE llx_contrat SET ref = rowid WHERE ref IS NULL OR ref = ''; diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.key.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.key.sql index 8e921a9964c..e035a957f5a 100644 --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.key.sql +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.key.sql @@ -17,8 +17,10 @@ -- ============================================================================ ALTER TABLE llx_accounting_bookkeeping ADD INDEX idx_accounting_bookkeeping_doc_date (doc_date); +ALTER TABLE llx_accounting_bookkeeping ADD INDEX idx_accounting_bookkeeping_fk_doc (fk_doc); ALTER TABLE llx_accounting_bookkeeping ADD INDEX idx_accounting_bookkeeping_fk_docdet (fk_docdet); ALTER TABLE llx_accounting_bookkeeping ADD INDEX idx_accounting_bookkeeping_numero_compte (numero_compte); ALTER TABLE llx_accounting_bookkeeping ADD INDEX idx_accounting_bookkeeping_code_journal (code_journal); --- TODO Add a key for unicity \ No newline at end of file +-- Current unicity is tested by the journalize page on couple (fk_doc, doc_type) +-- TODO Add a key for unicity (not so easy as fk_doc, doc_type may have several lines for one piece) From 731cb3f721d46f032a8ea9ed0e097eb35a3db405 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 17:00:40 +0100 Subject: [PATCH 033/429] Fix editor of user signature --- htdocs/user/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 7b5a9f29be4..a8377be7b15 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1081,7 +1081,7 @@ if ($action == 'create' || $action == 'adduserldap') print ''.$langs->trans("Signature").''; print ''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('signature',GETPOST('signature'),'',138,'dolibarr_mailings','In',true,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); + $doleditor=new DolEditor('signature',GETPOST('signature'),'',138,'dolibarr_notes','In',true,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); print $doleditor->Create(1); print ''; @@ -2308,7 +2308,7 @@ else if ($caneditfield) { require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('signature',$object->signature,'',138,'dolibarr_mailings','In',false,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); + $doleditor=new DolEditor('signature',$object->signature,'',138,'dolibarr_notes','In',false,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); print $doleditor->Create(1); } else From 016be9139bfee0304c99c6410aa92a0e76c6353e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 17:09:47 +0100 Subject: [PATCH 034/429] Fix sql request --- htdocs/societe/class/societe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 4a37699e6c6..775d8852b90 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1156,7 +1156,7 @@ class Societe extends CommonObject if ($idprof4) $sql .= " AND s.idprof4 = '".$this->db->escape($idprof4)."'"; if ($idprof5) $sql .= " AND s.idprof5 = '".$this->db->escape($idprof5)."'"; if ($idprof6) $sql .= " AND s.idprof6 = '".$this->db->escape($idprof6)."'"; - if ($email) $sql .= " AND email = '".$this->db->escape($email)."'"; + if ($email) $sql .= " AND s.email = '".$this->db->escape($email)."'"; $resql=$this->db->query($sql); if ($resql) From 3635e883962b7e3c3be33c8d3c88f03accab7680 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 18:01:38 +0100 Subject: [PATCH 035/429] Update api_proposals.class.php --- htdocs/comm/propal/class/api_proposals.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 204d4c12dc4..160f6999c40 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -424,11 +424,11 @@ class Proposals extends DolibarrApi } // update end of validity date - if(!empty($this->propal->duree_validite) && !empty($this->propal->date_creation) ) + if (empty($this->propal->fin_validite) && !empty($this->propal->duree_validite) && !empty($this->propal->date_creation)) { $this->propal->fin_validite = $this->propal->date_creation + ($this->propal->duree_validite * 24 * 3600); } - if(!empty($this->propal->fin_validite)) + if (!empty($this->propal->fin_validite)) { if($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite)<0) { From bffed79132578dfa7950288ffbc44403a7923624 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 18:06:05 +0100 Subject: [PATCH 036/429] Update api_invoices.class.php --- htdocs/compta/facture/class/api_invoices.class.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 1e0392bf452..f41a2ee9ae0 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -508,8 +508,14 @@ class Invoices extends DolibarrApi $request_data->fk_parent_line = 0; } - // calculate pa_ht - $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht); + $pa_ht = $request_data->pa_ht; + + // calculate pa_ht + if ($pa_ht == 'auto') + { + $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht); + $pa_ht = $marginInfos[0]; + } $updateRes = $this->invoice->addline( $request_data->desc, @@ -534,7 +540,7 @@ class Invoices extends DolibarrApi $id, $request_data->fk_parent_line, $request_data->fk_fournprice, - $marginInfos[0], + $pa_ht, $request_data->label, $request_data->array_options, $request_data->situation_percent, From 57603e3df43096e4b9a722150eff613b38e21c4c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 18:16:39 +0100 Subject: [PATCH 037/429] Update api_invoices.class.php --- htdocs/compta/facture/class/api_invoices.class.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index f41a2ee9ae0..e6a2be07184 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -508,15 +508,10 @@ class Invoices extends DolibarrApi $request_data->fk_parent_line = 0; } - $pa_ht = $request_data->pa_ht; - // calculate pa_ht - if ($pa_ht == 'auto') - { - $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht); - $pa_ht = $marginInfos[0]; - } - + $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht); + $pa_ht = $marginInfos[0]; + $updateRes = $this->invoice->addline( $request_data->desc, $request_data->subprice, From 12d91d7444ecca97d8e6526e6f7302b6ea1c52b6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Dec 2017 18:26:27 +0100 Subject: [PATCH 038/429] Fix missing messages in error report. Fix test on non empty array --- dev/setup/codesniffer/ruleset.xml | 2 +- htdocs/core/class/html.formmail.class.php | 2 +- htdocs/core/lib/functions.lib.php | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/dev/setup/codesniffer/ruleset.xml b/dev/setup/codesniffer/ruleset.xml index b8cb751fe9e..e5485b280ae 100644 --- a/dev/setup/codesniffer/ruleset.xml +++ b/dev/setup/codesniffer/ruleset.xml @@ -131,7 +131,7 @@ - + diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index a3a37c86e8c..30719d0da80 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -755,7 +755,7 @@ class FormMail extends Form $defaulttopic=GETPOST('subject','none'); if (! GETPOST('modelselected','alpha') || GETPOST('modelmailselected') != '-1') { - if (count($arraydefaultmessage) > 0 && $arraydefaultmessage['topic']) $defaulttopic=$arraydefaultmessage['topic']; + if (is_array($arraydefaultmessage) && count($arraydefaultmessage) > 0 && $arraydefaultmessage['topic']) $defaulttopic=$arraydefaultmessage['topic']; elseif (! is_numeric($this->withtopic)) $defaulttopic=$this->withtopic; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 4cb19f6dc7e..38da587cef0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3492,9 +3492,10 @@ function dol_print_error($db='',$error='',$errors=null) * * @param string $prefixcode Prefix of public error code * @param string $errormessage Complete error message + * @param array $errormessages Array of error messages * @return void */ -function dol_print_error_email($prefixcode, $errormessage='') +function dol_print_error_email($prefixcode, $errormessage='', $errormessages=array()) { global $langs,$conf; @@ -3503,6 +3504,13 @@ function dol_print_error_email($prefixcode, $errormessage='') print '
'; } From a33411b8bd5842f1f201aaa03475d596b9c5f233 Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Wed, 20 Dec 2017 09:06:11 +0100 Subject: [PATCH 039/429] Create 7.0.0-8.0.0.sql --- .../install/mysql/migration/7.0.0-8.0.0.sql | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 htdocs/install/mysql/migration/7.0.0-8.0.0.sql diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql new file mode 100644 index 00000000000..e9a72ab9360 --- /dev/null +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -0,0 +1,26 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 7.0.0 or higher. +-- +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; +-- To drop an index: -- VMYSQL4.0 DROP INDEX nomindex on llx_table +-- To drop an index: -- VPGSQL8.0 DROP INDEX nomindex +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_c_shipment_mode CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): -- VPGSQL8.2 NOT POSSIBLE. MUST DELETE/CREATE TABLE +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. + +-- For 8.0 +ALTER TABLE llx_societe ADD COLUMN fk_entrepot int DEFAULT 0; From 28214598943d0bbb46013fb661448954e5a584d0 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 20 Dec 2017 11:36:51 +0100 Subject: [PATCH 040/429] Fix: avoid php warning --- htdocs/compta/paiement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index 7a494113090..fc65c6f05c3 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -102,7 +102,7 @@ if (empty($reshook)) $tmpinvoice=new Facture($db); foreach ($_POST as $key => $value) { - if (substr($key,0,7) == 'amount_') + if (substr($key,0,7) == 'amount_' && GETPOST($key) != '') { $cursorfacid = substr($key,7); $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); From 7da1f706e5ffcc84f18f12ff7ccf736d41aa7921 Mon Sep 17 00:00:00 2001 From: fappels Date: Wed, 20 Dec 2017 12:25:30 +0100 Subject: [PATCH 041/429] Error in send_mail trigger is not system error --- htdocs/core/actions_sendmails.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 5a8d32efde5..f7806cdd38a 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -445,7 +445,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO if ($error) { - dol_print_error($db); + // error message event set by trigger interface } else { From b1f98b5903cdc46a83345420963ef0ac6c483835 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Dec 2017 12:45:38 +0100 Subject: [PATCH 042/429] Fix inline edit --- htdocs/core/ajax/saveinplace.php | 19 +++++++++++++++---- htdocs/expedition/card.php | 14 +++++++------- htdocs/theme/eldy/style.css.php | 5 ++++- htdocs/theme/md/style.css.php | 4 +++- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/htdocs/core/ajax/saveinplace.php b/htdocs/core/ajax/saveinplace.php index eb04379a778..4c46ab43e23 100644 --- a/htdocs/core/ajax/saveinplace.php +++ b/htdocs/core/ajax/saveinplace.php @@ -94,10 +94,21 @@ if (! empty($field) && ! empty($element) && ! empty($table_element) && ! empty($ } else $newelement = $element; - if (! empty($user->rights->$newelement->creer) || ! empty($user->rights->$newelement->create) || ! empty($user->rights->$newelement->write) - || (isset($subelement) && (! empty($user->rights->$newelement->$subelement->creer) || ! empty($user->rights->$newelement->$subelement->write))) - || ($element == 'payment' && $user->rights->facture->paiement) - || ($element == 'payment_supplier' && $user->rights->fournisseur->facture->creer)) + $_POST['action']='update'; // Hack so restrictarea can test permission on write too + $feature = $newelement; + $object_id = $fk_element; + if ($feature == 'expedition' || $feature == 'shipping') + { + $feature = 'commande'; + $object_id = 0; + } + if ($feature == 'shipping') $feature = 'commande'; + //var_dump(GETPOST('action','aZ09')); + //var_dump($newelement.'-'.$subelement."-".$feature."-".$object_id); + $check_access = restrictedArea($user, $feature, $object_id, '', $subelement); + //var_dump($user->rights); + + if ($check_access) { // Clean parameters $newvalue = trim($value); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 81b6ed455a7..15caab8a1ee 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -127,7 +127,7 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once - // Set incoterm + // Reopen if ($action == 'reopen' && $user->rights->expedition->creer) { $object->fetch($id); @@ -503,8 +503,8 @@ if (empty($reshook)) } } - // Action update description of emailing - else if ($action == 'settrackingnumber' || $action == 'settrackingurl' + // Action update + else if ($action == 'settracking_number' || $action == 'settracking_url' || $action == 'settrueWeight' || $action == 'settrueWidth' || $action == 'settrueHeight' @@ -513,8 +513,8 @@ if (empty($reshook)) { $error=0; - if ($action == 'settrackingnumber') $object->tracking_number = trim(GETPOST('trackingnumber','alpha')); - if ($action == 'settrackingurl') $object->tracking_url = trim(GETPOST('trackingurl','int')); + if ($action == 'settracking_number') $object->tracking_number = trim(GETPOST('tracking_number','alpha')); + if ($action == 'settracking_url') $object->tracking_url = trim(GETPOST('tracking_url','int')); if ($action == 'settrueWeight') { $object->trueWeight = trim(GETPOST('trueWeight','int')); $object->weight_units = GETPOST('weight_units','int'); @@ -1692,8 +1692,8 @@ else if ($id || $ref) print ''; // Tracking Number - print ''.$form->editfieldkey("TrackingNumber",'trackingnumber',$object->tracking_number,$object,$user->rights->expedition->creer).''; - print $form->editfieldval("TrackingNumber",'trackingnumber',$object->tracking_url,$object,$user->rights->expedition->creer,'string',$object->tracking_number); + print ''.$form->editfieldkey("TrackingNumber",'tracking_number',$object->tracking_number,$object,$user->rights->expedition->creer).''; + print $form->editfieldval("TrackingNumber",'tracking_number',$object->tracking_url,$object,$user->rights->expedition->creer,'string',$object->tracking_number); print ''; // Incoterms diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index e809f800bb5..7f294d78e4e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3472,17 +3472,20 @@ td.gtaskname { /* ============================================================================== */ -/* jQuery - jeditable */ +/* jQuery - jeditable for inline edit */ /* ============================================================================== */ .editkey_textarea, .editkey_ckeditor, .editkey_string, .editkey_email, .editkey_numeric, .editkey_select, .editkey_autocomplete { background: url() right top no-repeat; cursor: pointer; + margin-right: 3px; } .editkey_datepicker { background: url() right center no-repeat; + margin-right: 3px; cursor: pointer; + margin-right: 3px; } .editval_textarea.active:hover, .editval_ckeditor.active:hover, .editval_string.active:hover, .editval_email.active:hover, .editval_numeric.active:hover, .editval_select.active:hover, .editval_autocomplete.active:hover, .editval_datepicker.active:hover { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f4966a105b7..5a56d027b15 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3542,17 +3542,19 @@ td.gtaskname { /* ============================================================================== */ -/* jQuery - jeditable */ +/* jQuery - jeditable for inline edit */ /* ============================================================================== */ .editkey_textarea, .editkey_ckeditor, .editkey_string, .editkey_email, .editkey_numeric, .editkey_select, .editkey_autocomplete { background: url() right top no-repeat; cursor: pointer; + margin-right: 3px; } .editkey_datepicker { background: url() right center no-repeat; cursor: pointer; + margin-right: 3px; } .editval_textarea.active:hover, .editval_ckeditor.active:hover, .editval_string.active:hover, .editval_email.active:hover, .editval_numeric.active:hover, .editval_select.active:hover, .editval_autocomplete.active:hover, .editval_datepicker.active:hover { From ca8ae3c7230aea9f8414e50f6a2b437f01b39bd8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Dec 2017 13:17:21 +0100 Subject: [PATCH 043/429] Fix option MAIN_USE_JQUERY_JEDITABLE --- dev/dolibarr_changes.txt | 10 ++- htdocs/core/ajax/saveinplace.php | 13 ++- htdocs/core/js/editinplace.js | 89 ++++++++++--------- .../plugins/jeditable/jquery.jeditable.js | 4 +- htdocs/main.inc.php | 2 +- 5 files changed, 68 insertions(+), 50 deletions(-) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 0570525cdad..53f58c6790e 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -123,4 +123,12 @@ PARSEDOWN else $len = strlen($line); $shortage = 4 - $len % 4; - + + +JEDITABLE.JS +------------ + +*
'; llxFooter(); diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 6223bf92aad..93cb22ea469 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -343,7 +343,7 @@ if ($step == 1 || ! $datatoimport) dol_fiche_head($head, 'step1', $langs->trans("NewImport"), -1); - print $langs->trans("SelectImportDataSet").'
'; + print '
'.$langs->trans("SelectImportDataSet").'

'; // Affiche les modules d'imports print ''; diff --git a/htdocs/imports/index.php b/htdocs/imports/index.php index 32f08d5bda5..36811acc587 100644 --- a/htdocs/imports/index.php +++ b/htdocs/imports/index.php @@ -44,14 +44,15 @@ llxHeader('',$langs->trans("ImportArea"),'EN:Module_Imports_En|FR:Module_Imports print load_fiche_titre($langs->trans("ImportArea")); print $langs->trans("FormatedImportDesc1").'
'; -print $langs->trans("FormatedImportDesc2").'
'; +//print $langs->trans("FormatedImportDesc2").'
'; print '
'; -print '
'; +//print '
'; // List of import set +/* print '
'; print ''; print ''; @@ -84,6 +85,7 @@ else } print '
'.$langs->trans("Module").'
'; print '
'; +*/ print '
'; if (count($import->array_import_code)) @@ -101,7 +103,7 @@ print '
'; print '
'; -print '
'; +//print '
'; // List of available import format @@ -119,7 +121,7 @@ $liste=$model->liste_modeles($db); foreach($liste as $key) { - + print ''; print ''.img_picto_common($model->getDriverLabelForKey($key),$model->getPictoForKey($key)).''; $text=$model->getDriverDescForKey($key); @@ -132,7 +134,7 @@ foreach($liste as $key) print ''; -print '
'; +//print ''; llxFooter(); From 25390e5f73f5497ced8d451ea1e903255e619f96 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Wed, 3 Jan 2018 17:03:00 +0100 Subject: [PATCH 108/429] fix : linked object (new format of linked_object atribut on 6.0) --- htdocs/fourn/commande/orderstoinvoice.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index b1a8c0c08c1..20f9a3674cf 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -171,16 +171,15 @@ if (($action == 'create' || $action == 'add') && ! $error) { if ($ret < 0) $error++; if ($_POST['origin'] && $_POST['originid']) { - $object->linked_objects = $orders_id; + $linked_orders_ids=array(); + foreach ( $orders_id as $origin => $origin_id ) { + $origin_id = (! empty($origin_id) ? $origin_id : $orders_id[$ii]); + $linked_orders_ids[]=$origin_id; + } + $object->linked_objects = array(GETPOST('origin')=>$linked_orders_ids); $id = $object->create($user); if ($id > 0) { - foreach ( $orders_id as $origin => $origin_id ) { - $origin_id = (! empty($origin_id) ? $origin_id : $orders_id[$ii]); - - $object->add_object_linked(GETPOST('origin'), $origin_id); - } - while ( $ii < $nn ) { $objectsrc = new CommandeFournisseur($db); dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); From 534cbcb941d9f6a97631539f10b5ced131904863 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 3 Jan 2018 20:59:35 +0100 Subject: [PATCH 109/429] Debug translation --- htdocs/accountancy/admin/categories_list.php | 11 ++--------- htdocs/compta/resultat/result.php | 2 +- htdocs/langs/en_US/accountancy.lang | 2 +- htdocs/langs/en_US/admin.lang | 2 +- htdocs/langs/fr_FR/admin.lang | 2 +- 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index ad8b563e477..9833a1c01b1 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -31,14 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -$langs->load("errors"); -$langs->load("admin"); -$langs->load("main"); -$langs->load("companies"); -$langs->load("resource"); -$langs->load("holiday"); -$langs->load("accountancy"); -$langs->load("hrm"); +$langs->loadLangs(array("errors","admin","companies","resource","holiday","accountancy","hrm")); $action=GETPOST('action','alpha')?GETPOST('action','alpha'):'view'; $confirm=GETPOST('confirm','alpha'); @@ -418,7 +411,7 @@ if ($action == 'disable_favorite') $form = new Form($db); $formadmin=new FormAdmin($db); -llxHeader('', $langs->trans('AccountingCategory')); +llxHeader('', $langs->trans('DictionaryAccountancyCategory')); $titre=$langs->trans($tablib[$id]); $linkback=''; diff --git a/htdocs/compta/resultat/result.php b/htdocs/compta/resultat/result.php index 261121b9d7c..a75c70cc80a 100644 --- a/htdocs/compta/resultat/result.php +++ b/htdocs/compta/resultat/result.php @@ -199,7 +199,7 @@ else if ($modecompta=="BOOKKEEPING") $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); $arraylist=array('no'=>$langs->trans("No"), 'yes'=>$langs->trans("AccountWithNonZeroValues"), 'all'=>$langs->trans("All")); $period.='     '.$langs->trans("DetailByAccount").' '. $form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0); - $periodlink = $textprevyear . " " . $langs->trans("Year") . " " . $start_year . " " . $textnextyear ; + $periodlink = $textprevyear . $textnextyear ; $exportlink = ''; $description=$langs->trans("RulesResultBookkeepingPersonalized"). $description.=' ('.$langs->trans("SeePageForSetup", DOL_URL_ROOT.'/accountancy/admin/categories_list.php?search_country_id='.$mysoc->country_id.'&mainmenu=accountancy&leftmenu=accountancy_admin', $langs->transnoentitiesnoconv("Accountancy").' / '.$langs->transnoentitiesnoconv("Setup").' / '.$langs->transnoentitiesnoconv("AccountingCategory")).')'; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index b7e6c30d87c..85c6b6a0e16 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -158,7 +158,7 @@ NumPiece=Piece number TransactionNumShort=Num. transaction AccountingCategory=Personalized groups GroupByAccountAccounting=Group by accounting account -AccountingAccountGroupsDesc=You can define here some groups of accounting account. It will be used in the report %s to show your income/expense with data grouped according to these groups. +AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports. ByAccounts=By accounts ByPredefinedAccountGroups=By predefined groups ByPersonalizedAccountGroups=By personalized groups diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a4ece445581..657b1e477e4 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -890,7 +890,7 @@ DictionaryStaff=Staff DictionaryAvailability=Delivery delay DictionaryOrderMethods=Ordering methods DictionarySource=Origin of proposals/orders -DictionaryAccountancyCategory=Personalized groups +DictionaryAccountancyCategory=Personalized groups for reports DictionaryAccountancysystem=Models for chart of accounts DictionaryAccountancyJournal=Accounting journals DictionaryEMailTemplates=Emails templates diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 021dff351de..a8a82d77d7d 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -890,7 +890,7 @@ DictionaryStaff=Effectifs DictionaryAvailability=Délai de livraison DictionaryOrderMethods=Méthodes de commandes DictionarySource=Origines des propales/commandes -DictionaryAccountancyCategory=Groupes personnalisés +DictionaryAccountancyCategory=Groupes personnalisés pour les rapports DictionaryAccountancysystem=Modèles de plan comptable DictionaryAccountancyJournal=Journaux comptables DictionaryEMailTemplates=Modèles des courriels From f6007045f581f92f17cb6bbf9d111a663cfd333e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Jan 2018 00:23:08 +0100 Subject: [PATCH 110/429] Fix search filters --- htdocs/comm/propal/list.php | 2 +- htdocs/projet/tasks/time.php | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 15f6c0b3513..8796da505cd 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -374,7 +374,7 @@ if ($resql) if ($search_year) $param.='&search_year='.urlencode($search_year); if ($search_ref) $param.='&search_ref='.urlencode($search_ref); if ($search_refcustomer) $param.='&search_refcustomer='.urlencode($search_refcustomer); - if ($search_refprojet) $param.='&search_refprojet='.urlencode($search_refprojet); + if ($search_refprojet) $param.='&search_refprojet='.urlencode($search_refprojet); if ($search_societe) $param.='&search_societe='.urlencode($search_societe); if ($search_user > 0) $param.='&search_user='.urlencode($search_user); if ($search_sale > 0) $param.='&search_sale='.urlencode($search_sale); diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 44fb15869ff..8a4ac65c763 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -41,9 +41,9 @@ $confirm=GETPOST('confirm','alpha'); $withproject=GETPOST('withproject','int'); $project_ref=GETPOST('project_ref','alpha'); -$search_dateday=GETPOST('search_dateday'); -$search_datemonth=GETPOST('search_datemonth'); -$search_dateyear=GETPOST('search_dateyear'); +$search_day=GETPOST('search_day','int'); +$search_month=GETPOST('search_month','int'); +$search_year=GETPOST('search_year','int'); $search_datehour=''; $search_datewithhour=''; $search_note=GETPOST('search_note','alpha'); @@ -98,7 +98,10 @@ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria 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 { - $search_date=''; + $search_day=''; + $search_month=''; + $search_year=''; + $search_date=''; $search_datehour=''; $search_datewithhour=''; $search_note=''; @@ -643,6 +646,20 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) if ($search_task_ref) $sql .= natural_search('pt.ref', $search_task_ref); if ($search_task_label) $sql .= natural_search('pt.label', $search_task_label); if ($search_user > 0) $sql .= natural_search('t.fk_user', $search_user); + if ($search_month > 0) + { + if ($search_year > 0 && empty($search_day)) + $sql.= " AND t.task_datehour BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'"; + else if ($search_year > 0 && ! empty($search_day)) + $sql.= " AND t.task_datehour BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'"; + else + $sql.= " AND date_format(t.task_datehour, '%m') = '".$db->escape($search_month)."'"; + } + else if ($search_year > 0) + { + $sql.= " AND t.task_datehour BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'"; + } + $sql .= $db->order($sortfield, $sortorder); $var=true; @@ -738,14 +755,21 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) // Fields title search print ''; // Date - if (! empty($arrayfields['t.task_date']['checked'])) print ''; + if (! empty($arrayfields['t.task_date']['checked'])) + { + print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; + $formother->select_year($search_year,'search_year',1, 20, 5); + print ''; + } if ((empty($id) && empty($ref)) || ! empty($projectidforalltimes)) // Not a dedicated task { if (! empty($arrayfields['t.task_ref']['checked'])) print ''; if (! empty($arrayfields['t.task_label']['checked'])) print ''; } // Author - if (! empty($arrayfields['author']['checked'])) print ''.$form->select_dolusers($search_user > 0 ? $search_user : -1, 'search_user', 1).''; + if (! empty($arrayfields['author']['checked'])) print ''.$form->select_dolusers(($search_user > 0 ? $search_user : -1), 'search_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200').''; // Note if (! empty($arrayfields['t.note']['checked'])) print ''; // Duration From b3465d441a413c7129eb5322167c49d8f9b50aef Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Jan 2018 10:45:48 +0100 Subject: [PATCH 111/429] Missing ajaxcombobox --- htdocs/core/class/html.formother.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index dfd70a075f0..ae1ec52a788 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -481,12 +481,14 @@ class FormOther $tasksarray=$task->getTasksArray($modetask?$user:0, $modeproject?$user:0, $projectid, 0, $mode); if ($tasksarray) { - print ''; if ($useempty) print ''; $j=0; $level=0; $this->_pLineSelect($j, 0, $tasksarray, $level, $selectedtask, $projectid, $disablechildoftaskid); print ''; + + print ajax_combobox($htmlname); } else { From 58470e0913ad38f4462185295f58379b21005b5a Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 4 Jan 2018 12:01:21 +0100 Subject: [PATCH 112/429] FIX : $oldvatrateclean & $newvatrateclean must be set if preg_match === false --- htdocs/product/admin/product_tools.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/admin/product_tools.php b/htdocs/product/admin/product_tools.php index f19f672a25e..c9323f75823 100644 --- a/htdocs/product/admin/product_tools.php +++ b/htdocs/product/admin/product_tools.php @@ -73,7 +73,7 @@ if ($action == 'convert') { $vat_src_code_old = $reg[1]; $oldvatrateclean = preg_replace('/\s*\(.*\)/', '', $oldvatrate); // Remove code into vatrate. - } + } else $oldvatrateclean=$oldvatrate; // Clean vat code new $vat_src_code_new=''; @@ -81,7 +81,7 @@ if ($action == 'convert') { $vat_src_code_new = $reg[1]; $newvatrateclean = preg_replace('/\s*\(.*\)/', '', $newvatrate); // Remove code into vatrate. - } + } else $newvatrateclean=$newvatrate; // If country to edit is my country, so we change customer prices if ($country_id == $mysoc->country_id) From 04dd0663ff22acb911a7a3316c37650b7d60307b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Jan 2018 12:17:32 +0100 Subject: [PATCH 113/429] Fix translation --- htdocs/langs/en_US/languages.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index 05288a888eb..a062883d667 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -35,6 +35,7 @@ Language_es_PA=Spanish (Panama) Language_es_PY=Spanish (Paraguay) Language_es_PE=Spanish (Peru) Language_es_PR=Spanish (Puerto Rico) +Language_es_UY=Spanish (Uruguay) Language_es_VE=Spanish (Venezuela) Language_et_EE=Estonian Language_eu_ES=Basque From c4eba665d0e99ff428dfdd6c644e922b440e6f67 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Jan 2018 13:52:37 +0100 Subject: [PATCH 114/429] Fix order of task in gantt diagram --- htdocs/projet/class/task.class.php | 27 ++++++++++++++++++++------- htdocs/projet/ganttchart.inc.php | 26 +++++++++++++++++--------- htdocs/projet/ganttview.php | 27 +++++++++++++++++++++++---- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 2a77de4f552..e694b3c7bfd 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -187,11 +187,12 @@ class Task extends CommonObject /** * Load object in memory from database * - * @param int $id Id object - * @param int $ref ref object - * @return int <0 if KO, 0 if not found, >0 if OK + * @param int $id Id object + * @param int $ref ref object + * @param int $loadparentdata Also load parent data + * @return int <0 if KO, 0 if not found, >0 if OK */ - function fetch($id,$ref='') + function fetch($id, $ref='', $loadparentdata=0) { global $langs; @@ -215,7 +216,13 @@ class Task extends CommonObject $sql.= " t.note_private,"; $sql.= " t.note_public,"; $sql.= " t.rang"; + if (! empty($loadparentdata)) + { + $sql.=", t2.ref as task_parent_ref"; + $sql.=", t2.rang as task_parent_position"; + } $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as t"; + if (! empty($loadparentdata)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t2 ON t.fk_task_parent = t2.rowid"; $sql.= " WHERE "; if (!empty($ref)) { $sql.="t.ref = '".$this->db->escape($ref)."'"; @@ -253,14 +260,20 @@ class Task extends CommonObject $this->note_public = $obj->note_public; $this->rang = $obj->rang; - // Retreive all extrafield for thirdparty + if (! empty($loadparentdata)) + { + $this->task_parent_ref = $obj->task_parent_ref; + $this->task_parent_position = $obj->task_parent_position; + } + + // Retreive all extrafield data $this->fetch_optionals(); } $this->db->free($resql); - if ($num_rows) { - $this->fetchComments(); + if ($num_rows) + { return 1; }else { return 0; diff --git a/htdocs/projet/ganttchart.inc.php b/htdocs/projet/ganttchart.inc.php index 58d212db7bd..fc8ab9d7882 100644 --- a/htdocs/projet/ganttchart.inc.php +++ b/htdocs/projet/ganttchart.inc.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2017 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 @@ -109,6 +109,10 @@ if (g.getDivId() != null) g.setLang('getDefaultLang(1);?>'); fetch($t['task_project_id']); $tmpt = array( - 'task_id'=> '-'.$t['task_project_id'], 'task_name'=>$projecttmp->ref.' '.$projecttmp->title, 'task_resources'=>'', 'task_start_date'=>'', 'task_end_date'=>'', - 'task_is_group'=>1, 'task_css'=>'ggroupblack', 'task_milestone'=> 0, 'task_parent'=>0, 'task_notes'=>''); + 'task_id'=> '-'.$t['task_project_id'], 'task_alternate_id'=> '-'.$t['task_project_id'], 'task_name'=>$projecttmp->ref.' '.$projecttmp->title, 'task_resources'=>'', 'task_start_date'=>'', 'task_end_date'=>'', + 'task_is_group'=>1, 'task_position'=>0, 'task_css'=>'ggroupblack', 'task_milestone'=> 0, 'task_parent'=>0, 'task_parent_alternate_id'=>0, 'task_notes'=>'' + ); constructGanttLine($tasks, $tmpt, array(), 0, $t['task_project_id']); $old_project_id = $t['task_project_id']; } @@ -134,6 +139,8 @@ if (g.getDivId() != null) findChildGanttLine($tasks, $t["task_id"], $task_dependencies, $level+1); } } + + echo "\n"; ?> g.Draw(jQuery("#tabs").width()-40); @@ -188,7 +195,8 @@ function constructGanttLine($tarr, $task, $task_dependencies, $level=0, $project } else { - $parent = $task["task_parent"]; + $parent = $task["task_parent_alternate_id"]; + //$parent = $task["task_parent"]; } // Define percent $percent = $task['task_percent_complete']?$task['task_percent_complete']:0; @@ -238,7 +246,7 @@ function constructGanttLine($tarr, $task, $task_dependencies, $level=0, $project //$note=""; - $s = "\n// Add taks id=".$task["task_id"]." level = ".$level."\n"; + $s = "\n// Add task level = ".$level." id=".$task["task_id"]." parent_id=".$task["task_parent"]." aternate_id=".$task["task_alternate_id"]." parent_aternate_id=".$task["task_parent_alternate_id"]."\n"; //$task["task_is_group"]=1; // When task_is_group is 1, content will be autocalculated from sum of all low tasks @@ -251,7 +259,10 @@ function constructGanttLine($tarr, $task, $task_dependencies, $level=0, $project $dependency = ''; //$name = str_repeat("..", $level).$name; - $s.= "g.AddTaskItem(new JSGantt.TaskItem('".$task['task_id']."', '".dol_escape_js(trim($name))."', '".$start_date."', '".$end_date."', '".$css."', '".$link."', ".$task['task_milestone'].", '".dol_escape_js($resources)."', ".($percent >= 0 ? $percent : 0).", ".$line_is_auto_group.", '".$parent."', 1, '".$dependency."', '".(empty($task["task_is_group"]) ? (($percent >= 0 && $percent != '') ? $percent.'%' : '') : '')."', '".dol_escape_js($task['note'])."', g));"; + $taskid = $task["task_alternate_id"]; + //$taskid = $task['task_id']; + + $s.= "g.AddTaskItem(new JSGantt.TaskItem('".$taskid."', '".dol_escape_js(trim($name))."', '".$start_date."', '".$end_date."', '".$css."', '".$link."', ".$task['task_milestone'].", '".dol_escape_js($resources)."', ".($percent >= 0 ? $percent : 0).", ".$line_is_auto_group.", '".$parent."', 1, '".$dependency."', '".(empty($task["task_is_group"]) ? (($percent >= 0 && $percent != '') ? $percent.'%' : '') : '')."', '".dol_escape_js($task['note'])."', g));"; echo $s; @@ -270,9 +281,6 @@ function findChildGanttLine($tarr, $parent, $task_dependencies, $level) { $n=count($tarr); - echo "\n"; - echo "/* g.AddTaskItem(new JSGantt.TaskItem(task_id, 'label', 'start_date', 'end_date', 'css', 'link', milestone, 'Resources', Compl%, Group, Parent, 1, 'Dependency', 'label','note', g)); */\n"; - $old_parent_id = 0; for ($x=0; $x < $n; $x++) { diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index c3552d714f2..119684bf6e6 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -246,15 +246,20 @@ if (count($tasksarray)>0) $tasks=array(); $task_dependencies=array(); $taskcursor=0; - foreach($tasksarray as $key => $val) + foreach($tasksarray as $key => $val) // Task array are sorted by "project, position, dateo" { - $task->fetch($val->id); + $task->fetch($val->id, ''); + + $idparent = ($val->fk_parent ? $val->fk_parent : '-'.$val->fk_project); // If start with -, id is a project id $tasks[$taskcursor]['task_id']=$val->id; + $tasks[$taskcursor]['task_alternate_id']=($taskcursor+1); // An id that has same order than position (requird by ganttchart) $tasks[$taskcursor]['task_project_id']=$val->fk_project; - $tasks[$taskcursor]['task_parent']=($val->fk_parent ? $val->fk_parent : '-'.$val->fk_project); - $tasks[$taskcursor]['task_is_group'] = 0; + $tasks[$taskcursor]['task_parent']=$idparent; + + $tasks[$taskcursor]['task_is_group'] = 0; $tasks[$taskcursor]['task_css'] = 'gtaskblue'; + $tasks[$taskcursor]['task_position'] = $val->rang; if ($val->fk_parent != 0 && $task->hasChildren()> 0){ $tasks[$taskcursor]['task_is_group']=1; @@ -321,6 +326,20 @@ if (count($tasksarray)>0) $taskcursor++; } + // Search parent to set task_parent_alternate_id (requird by ganttchart) + foreach($tasks as $tmpkey => $tmptask) + { + foreach($tasks as $tmptask2) + { + if ($tmptask2['task_id'] == $tmptask['task_parent']) + { + $tasks[$tmpkey]['task_parent_alternate_id']=$tmptask2['task_alternate_id']; + break; + } + } + if (empty($tasks[$tmpkey]['task_parent_alternate_id'])) $tasks[$tmpkey]['task_parent_alternate_id'] = $tasks[$tmpkey]['task_parent']; + } + print "\n"; if (! empty($conf->use_javascript_ajax)) From 300d4e1603447f5c1f6aaa271255f849c3fe4135 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Jan 2018 14:35:02 +0100 Subject: [PATCH 115/429] Fix disable direct debit request for replaced invoices --- htdocs/compta/facture/card.php | 10 +++++++--- htdocs/projet/ganttchart.inc.php | 2 +- htdocs/theme/eldy/style.css.php | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 98c06179368..c769b538d43 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -64,7 +64,7 @@ if (! empty($conf->accounting->enabled)) { require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; } -$langs->loadLangs(array('bills','companies','compta','products','banks','main')); +$langs->loadLangs(array('bills','companies','compta','products','banks','main','withdrawals')); if (! empty($conf->incoterm->enabled)) $langs->load('incoterm'); if (! empty($conf->margin->enabled)) $langs->load('margins'); @@ -4293,8 +4293,12 @@ else if ($id > 0 || ! empty($ref)) { if ($user->rights->prelevement->bons->creer) { - $langs->load("withdrawals"); - print ''.$langs->trans("MakeWithdrawRequest").''; + if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice + { + print ''.$langs->trans("MakeWithdrawRequest").''; + } else { + print '
' . $langs->trans('MakeWithdrawRequest') . '
'; + } } else { diff --git a/htdocs/projet/ganttchart.inc.php b/htdocs/projet/ganttchart.inc.php index fc8ab9d7882..2777b59f032 100644 --- a/htdocs/projet/ganttchart.inc.php +++ b/htdocs/projet/ganttchart.inc.php @@ -111,7 +111,7 @@ if (g.getDivId() != null) Date: Thu, 4 Jan 2018 14:54:04 +0100 Subject: [PATCH 116/429] Fix ui --- htdocs/theme/eldy/style.css.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a64bc369fae..dafa39c9ce1 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3799,7 +3799,8 @@ A.none, A.none:active, A.none:visited, A.none:hover { font-family:; font-size:px; } -.ui-button { margin-left: -2px; browser->name)?'padding-top: 1px;':''); ?> } +/* .ui-button { margin-left: -2px; browser->name)?'padding-top: 1px;':''); ?> } */ +.ui-button { margin-left: -2px; } .ui-button-icon-only .ui-button-text { height: 8px; } .ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: 2px 0px 6px 0px; } .ui-button-text From 7d824b3ef238124f11758b4744a891d92ba15b11 Mon Sep 17 00:00:00 2001 From: KHELIFA Date: Thu, 4 Jan 2018 15:05:11 +0100 Subject: [PATCH 117/429] Fix: Access rights for resource in multi-entities --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index fa624a118f8..71fcdf33bb3 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -383,7 +383,7 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh if ($feature == 'project') $feature='projet'; if ($feature == 'task') $feature='projet_task'; - $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie'); // Test on entity only (Objects with no link to company) + $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie','resource'); // Test on entity only (Objects with no link to company) $checksoc = array('societe'); // Test for societe object $checkother = array('contact','agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...). $checkproject = array('projet','project'); // Test for project object From 59ed23069c87da64ff194826295f067165c87563 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Jan 2018 15:52:07 +0100 Subject: [PATCH 118/429] Fix debug accounting module --- htdocs/accountancy/journal/bankjournal.php | 38 +++++++++---- .../journal/expensereportsjournal.php | 4 +- .../accountancy/journal/purchasesjournal.php | 54 ++++++++++--------- htdocs/accountancy/journal/sellsjournal.php | 6 ++- htdocs/langs/en_US/accountancy.lang | 1 + 5 files changed, 62 insertions(+), 41 deletions(-) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 925628c8fa7..32396a9333c 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -94,7 +94,7 @@ if ($pastmonth == 0) { $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); -if (empty($date_start) || empty($date_end)) // We define date_start and date_end +if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) // We define date_start and date_end, only if we did not submit the form { $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false); $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); @@ -786,7 +786,7 @@ if (empty($action) || $action == 'view') { $description.= $langs->trans("DescJournalOnlyBindedVisible").'
'; $listofchoices=array('already'=>$langs->trans("AlreadyInGeneralLedger"), 'notyet'=>$langs->trans("NotYetInGeneralLedger")); - $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + $period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); $varlink = 'id_journal=' . $id_journal; @@ -932,7 +932,14 @@ if (empty($action) || $action == 'view') { if ($tabtype[$key] == 'unknown') { // We will accept writing, but into a waiting account - print ''.$langs->trans('UnknownAccountForThirdparty', length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE)).''; // We will a waiting account + if (empty($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) || $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE == '-1') + { + print ''.$langs->trans('UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking').''; + } + else + { + print ''.$langs->trans('UnknownAccountForThirdparty', length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE)).''; // We will a waiting account + } } else { @@ -1103,15 +1110,24 @@ function getSourceDocRef($val, $typerecord) $sqlmid .= " WHERE v.rowid=" . $val["paymentvariousid"]; $ref = $langs->trans("VariousPayment"); } - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - while ($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } + // Add warning + if (empty($sqlmid)) + { + dol_syslog("Found a typerecord=".$typerecord." not supported", LOG_WARNING); + } + + if ($sqlmid) + { + dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); + $resultmid = $db->query($sqlmid); + if ($resultmid) { + while ($objmid = $db->fetch_object($resultmid)) + { + $ref.=' '.$objmid->ref; + } + } + else dol_print_error($db); } - else dol_print_error($db); return $ref; } diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index 10755fe2c9c..4a4dafbe2b4 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -77,7 +77,7 @@ if ($pastmonth == 0) { $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); -if (empty($date_start) || empty($date_end)) // We define date_start and date_end +if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) // We define date_start and date_end, only if we did not submit the form { $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false); $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); @@ -528,7 +528,7 @@ if (empty($action) || $action == 'view') { $description.= $langs->trans("DescJournalOnlyBindedVisible").'
'; $listofchoices=array('already'=>$langs->trans("AlreadyInGeneralLedger"), 'notyet'=>$langs->trans("NotYetInGeneralLedger")); - $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + $period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); $varlink = 'id_journal=' . $id_journal; diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 0e82566b22a..f5429dce86e 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -86,7 +86,7 @@ if ($pastmonth == 0) { $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); -if (empty($date_start) || empty($date_end)) // We define date_start and date_end +if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) // We define date_start and date_end, only if we did not submit the form { $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false); $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); @@ -638,7 +638,7 @@ if (empty($action) || $action == 'view') { } $listofchoices=array('already'=>$langs->trans("AlreadyInGeneralLedger"), 'notyet'=>$langs->trans("NotYetInGeneralLedger")); - $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + $period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); $varlink = 'id_journal=' . $id_journal; @@ -811,32 +811,34 @@ if (empty($action) || $action == 'view') { } // VAT counterpart for NPR - foreach ( $tabother[$key] as $k => $mt ) { - print ''; - print ""; - print "" . $date . ""; - print "" . $invoicestatic->getNomUrl(1) . ""; - $companystatic->id = $tabcompany[$key]['id']; - $companystatic->name = $tabcompany[$key]['name']; - $companystatic->supplier_code = $tabcompany[$key]['code_supplier']; - // Account - print ""; - $accountoshow = length_accountg($k); - if (empty($accountoshow) || $accountoshow == 'NotDefined') - { - print ''.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("NPR counterpart").'). Set ACCOUNTING_COUNTERPART_VAT_NPR to the subvention account'.''; + if (is_array($tabother[$key])) + { + foreach ( $tabother[$key] as $k => $mt ) { + print ''; + print ""; + print "" . $date . ""; + print "" . $invoicestatic->getNomUrl(1) . ""; + $companystatic->id = $tabcompany[$key]['id']; + $companystatic->name = $tabcompany[$key]['name']; + $companystatic->supplier_code = $tabcompany[$key]['code_supplier']; + // Account + print ""; + $accountoshow = length_accountg($k); + if (empty($accountoshow) || $accountoshow == 'NotDefined') + { + print ''.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("NPR counterpart").'). Set ACCOUNTING_COUNTERPART_VAT_NPR to the subvention account'.''; + } + else print $accountoshow; + print ''; + // Subledger account + print ""; + print ''; + print "" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT") . " NPR (counterpart)"; + print '' . ($mt < 0 ? - price(- $mt) : '') . ""; + print '' . ($mt >= 0 ? price($mt) : '') . ""; + print ""; } - else print $accountoshow; - print ''; - // Subledger account - print ""; - print ''; - print "" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT") . " NPR (counterpart)"; - print '' . ($mt < 0 ? - price(- $mt) : '') . ""; - print '' . ($mt >= 0 ? price($mt) : '') . ""; - print ""; } - } print ""; diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 4018b570f3d..81dab1a1f06 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -81,7 +81,7 @@ if ($pastmonth == 0) { $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); -if (empty($date_start) || empty($date_end)) // We define date_start and date_end +if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) // We define date_start and date_end, only if we did not submit the form { $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false); $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); @@ -115,10 +115,12 @@ if ($date_start && $date_end) if ($in_bookkeeping == 'already') { $sql .= " AND f.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; + // $sql .= " AND fd.rowid IN (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; // Useless, we save one line for all products with same account } if ($in_bookkeeping == 'notyet') { $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; +// $sql .= " AND fd.rowid NOT IN (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; // Useless, we save one line for all products with same account } $sql .= " ORDER BY f.datef"; @@ -569,7 +571,7 @@ if (empty($action) || $action == 'view') { $description .= $langs->trans("DepositsAreIncluded"); $listofchoices=array('already'=>$langs->trans("AlreadyInGeneralLedger"), 'notyet'=>$langs->trans("NotYetInGeneralLedger")); - $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + $period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); $varlink = 'id_journal=' . $id_journal; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 85c6b6a0e16..949b16109f0 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -191,6 +191,7 @@ DescThirdPartyReport=Consult here the list of the third party customers and supp ListAccounts=List of the accounting accounts UnknownAccountForThirdparty=Unknown third party account. We will use %s UnknownAccountForThirdpartyBlocking=Unknown third party account. Blocking error +UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking=Unknown third party account and waiting account not defined. Blocking error Pcgtype=Group of account Pcgsubtype=Subgroup of account From 41fec45daf7b3821f9039b281ae4ec7507f1c079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 4 Jan 2018 16:23:25 +0100 Subject: [PATCH 119/429] Fix PHP notices adding empty($page) --- htdocs/accountancy/customer/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 18a440f0e25..904c8668b94 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -73,7 +73,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit', 'int'):(empty($conf->global->AC $sortfield = GETPOST('sortfield', 'alpha'); $sortorder = GETPOST('sortorder', 'alpha'); $page = GETPOST('page','int'); -if ($page < 0) { $page = 0; } +if (empty($page) || $page < 0) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -505,4 +505,4 @@ jQuery(document).ready(function() { '; llxFooter(); -$db->close(); \ No newline at end of file +$db->close(); From 777ed43e757fa981fac38a4f1838c1971764db96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 4 Jan 2018 17:31:59 +0100 Subject: [PATCH 120/429] Remove PHP notices adding empty($page) --- htdocs/accountancy/customer/lines.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index ed44277d7bf..673e927fbeb 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -64,7 +64,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit', 'int'):(empty($conf->global->AC $sortfield = GETPOST('sortfield', 'alpha'); $sortorder = GETPOST('sortorder', 'alpha'); $page = GETPOST('page', 'int'); -if ($page < 0) $page = 0; +if (empty($page) || $page < 0) $page = 0; $pageprev = $page - 1; $pagenext = $page + 1; $offset = $limit * $page; From 4ed86c830ad2ac1e41fd69de39f52f003aec2905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Thu, 4 Jan 2018 17:42:23 +0100 Subject: [PATCH 121/429] Fix PHP Warning Warning: A non-numeric value encountered in dolibarr/htdocs/accountancy/bookkeeping/list.php on line 89 --- htdocs/accountancy/bookkeeping/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 9b294e76d38..2f7502455d3 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -85,7 +85,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit', 'int'):(empty($conf->global->AC $sortfield = GETPOST('sortfield', 'alpha'); $sortorder = GETPOST('sortorder', 'alpha'); $page = GETPOST('page','int'); -if ($page < 0) { $page = 0; } +if (empty($page) || $page < 0) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; From 762ab74940603d5491bea80320704dac62bee271 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Thu, 4 Jan 2018 18:09:25 +0100 Subject: [PATCH 122/429] FIX: Cashdesk should not sell to inactive third parties --- htdocs/cashdesk/admin/cashdesk.php | 4 ++-- htdocs/cashdesk/index.php | 4 ++-- htdocs/cashdesk/tpl/menu.tpl.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/cashdesk/admin/cashdesk.php b/htdocs/cashdesk/admin/cashdesk.php index 0d1dbf2de53..79e8c8f83e8 100644 --- a/htdocs/cashdesk/admin/cashdesk.php +++ b/htdocs/cashdesk/admin/cashdesk.php @@ -1,6 +1,6 @@ - * Copyright (C) 2011-2012 Juanjo Menent + * Copyright (C) 2011-2017 Juanjo Menent * * 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 @@ -103,7 +103,7 @@ print "\n"; print ''.$langs->trans("CashDeskThirdPartyForSell").''; print ''; -print $form->select_company($conf->global->CASHDESK_ID_THIRDPARTY,'socid','s.client in (1,3)',1,0,1,array(),0); +print $form->select_company($conf->global->CASHDESK_ID_THIRDPARTY,'socid','s.client in (1,3) AND s.status = 1',1,0,1,array(),0); print ''; if (! empty($conf->banque->enabled)) { diff --git a/htdocs/cashdesk/index.php b/htdocs/cashdesk/index.php index 8f6af8b6d4d..91720885095 100644 --- a/htdocs/cashdesk/index.php +++ b/htdocs/cashdesk/index.php @@ -1,6 +1,6 @@ - * Copyright (C) 2011 Juanjo Menent + * Copyright (C) 2011-2017 Juanjo Menent * Copyright (C) 2011 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify @@ -105,7 +105,7 @@ print ''; $disabled=0; $langs->load("companies"); if (! empty($conf->global->CASHDESK_ID_THIRDPARTY)) $disabled=1; // If a particular third party is defined, we disable choice -print $form->select_company(GETPOST('socid','int')?GETPOST('socid','int'):$conf->global->CASHDESK_ID_THIRDPARTY,'socid','s.client in (1,3)',!$disabled,$disabled,1); +print $form->select_company(GETPOST('socid','int')?GETPOST('socid','int'):$conf->global->CASHDESK_ID_THIRDPARTY,'socid','s.client in (1,3) AND s.status = 1',!$disabled,$disabled,1); //print ''; print ''; print "\n"; diff --git a/htdocs/cashdesk/tpl/menu.tpl.php b/htdocs/cashdesk/tpl/menu.tpl.php index 4197db6b1b0..250aaa18cc2 100644 --- a/htdocs/cashdesk/tpl/menu.tpl.php +++ b/htdocs/cashdesk/tpl/menu.tpl.php @@ -2,7 +2,7 @@ /* Copyright (C) 2007-2008 Jeremie Ollivier * Copyright (C) 2008-2010 Laurent Destailleur * Copyright (C) 2009 Regis Houssin - * Copyright (C) 2011 Juanjo Menent + * Copyright (C) 2017 Juanjo Menent * Copyright (C) 2012 Marcos García * * This program is free software; you can redistribute it and/or modify @@ -79,7 +79,7 @@ print '