diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php index 1d370176613..7d10acfa4cd 100644 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php @@ -3,8 +3,8 @@ * Copyright (C) 2005 Laurent Destailleur * Copyright (C) 2013 Olivier Geffroy * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2018 Alexandre Spangaro - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2013-2019 Alexandre Spangaro + * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,17 +30,19 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; // Load translation files required by the page $langs->loadLangs(array("compta","accountancy")); -$action = GETPOST('action', 'aZ09'); +$action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); $show_files = GETPOST('show_files', 'int'); -$confirm = GETPOST('confirm', 'alpha'); -$toselect = GETPOST('toselect', 'array'); +$confirm = GETPOST('confirm', 'alpha'); +$toselect = GETPOST('toselect', 'array'); +$socid = GETPOST('socid','int')?GETPOST('socid','int'):GETPOST('id','int'); $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -53,26 +55,31 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if ($sortorder == "") - $sortorder = "DESC"; + $sortorder = "ASC"; if ($sortfield == "") $sortfield = "bk.doc_date"; -$search_year = GETPOST("search_year", 'int'); -$search_doc_type = GETPOST("search_doc_type", 'alpha'); +/* +$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); +$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); +//$search_doc_type = GETPOST("search_doc_type", 'alpha'); $search_doc_ref = GETPOST("search_doc_ref", 'alpha'); +*/ $lettering = GETPOST('lettering', 'alpha'); if (! empty($lettering)) { $action = $lettering; } -// Did we click on purge search criteria ? -// All tests are required to be compatible with all browsers -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { - $search_year = ''; - $search_doc_type = ''; +/* +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_start = ''; + $search_date_end = ''; + //$search_doc_type = ''; $search_doc_ref = ''; } +*/ // Security check $socid = GETPOST("socid", 'int'); @@ -102,6 +109,7 @@ if ($action == 'lettering') { } } +/* if ($action == 'autolettrage') { $result = $lettering->letteringThirdparty($socid); @@ -111,9 +119,9 @@ if ($action == 'autolettrage') { $error++; } } +*/ - - /* +/* * View */ @@ -136,19 +144,17 @@ dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'n dol_fiche_end(); -print '
'; - $sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, "; $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, "; $sql .= " bk.credit, bk.montant , bk.sens , bk.code_journal , bk.piece_num, bk.lettering_code "; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk"; $sql .= " WHERE (bk.subledger_account = '" . $object->code_compta . "' AND bk.numero_compte = '" . $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER . "' )"; -if (dol_strlen($search_year)) { - $date_start = dol_mktime(0, 0, 0, 1, 1, $search_year); - $date_end = dol_mktime(23, 59, 59, 12, 31, $search_year); - $sql .= " AND ( bk.doc_date BETWEEN '" . $db->idate($date_start) . "' AND '" . $db->idate($date_end) . "' )"; +/* +if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { + $sql .= " AND ( bk.doc_date BETWEEN '" . $db->idate($search_date_start) . "' AND '" . $db->idate($search_date_end) . "' )"; } +*/ $sql.= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; $sql .= $db->order($sortfield, $sortorder); @@ -181,92 +187,123 @@ if (! $resql) { exit(); } +$param=''; +$param.="&socid=".urlencode($socid); + $num = $db->num_rows($resql); dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG); if ($resql) { $i = 0; + $param="&socid=".$socid; print '
'; print ''; - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); + $letteringbutton = ''; + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); + + print '
'; + print ''."\n"; + + /* + print ''; + //print ''; + + // Date + print ''; + + // Piece + print ''; + + print ''; + print ''; + print ''; + */ - print "
'; + print '
'; + print $langs->trans('From') . ' '; + print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); + print '
'; + print '
'; + print $langs->trans('to') . ' '; + print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); + print '
'; + print '
 '; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
"; print ''; - print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); + //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("", "","",'','',"",$sortfield,$sortorder,'maxwidthsearch center '); print "\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $solde = 0; $tmp = ''; - while ( $obj = $db->fetch_object($resql) ) { + + while ( $obj = $db->fetch_object($resql) ) { if ($tmp != $obj->lettering_code || empty($tmp)) $tmp = $obj->lettering_code; /*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit); print ''; - if (empty($obj->lettering_code)) { - print '' . "\n"; - } else { - print '' . "\n"; - } - - print ''; + //print '' . "\n"; + print ''; print ''; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; - if (empty($obj->lettering_code)) { - print ''; - } else - print ''; + // Journal + $accountingjournal = new AccountingJournal($db); + $result = $accountingjournal->fetch('',$obj->code_journal); + $journaltoshow = (($result > 0)?$accountingjournal->getNomUrl(0,0,0,'',0) : $obj->code_journal); + print ''; + + if (empty($obj->lettering_code)) { + print ''; + print '' . "\n"; + } else { + print ''; + print ''; + } print "\n"; } print ''; - print '' . "\n"; - print ''; - print ''; - print ''; + print '' . "\n"; + print ''; + print ''; + print ''; print "\n"; print ''; - print '' . "\n"; + print '' . "\n"; print ''; - print ''; - print ''; + print ''; + print ''; print "\n"; print "
 '; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
'; - print img_edit(); - print ' ' . $obj->doc_type . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_ref . '' . $obj->label_compte . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $obj->code_journal . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $obj->lettering_code . '' . $journaltoshow . ''; + print img_edit(); + print '' . $obj->lettering_code . '
'.$langs->trans("Total").':' . price($debit) . '' . price($credit) . ''.$langs->trans("Total").':' . price($debit) . '' . price($credit) . '
'.$langs->trans("Balancing").':'.$langs->trans("Balancing").': ' . price($credit - $debit) . '' . price($credit - $debit) . '
"; - print ''; - //print '' . $langs->trans('AccountancyAutoLettering') . ''; + print '
'."\n"; + print $letteringbutton; + print '
'; + print ""; $db->free($resql); } else { diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php index 1d80bda7710..b7902efa3e6 100644 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php @@ -3,8 +3,8 @@ * Copyright (C) 2005 Laurent Destailleur * Copyright (C) 2013 Olivier Geffroy * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2018 Alexandre Spangaro - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2013-2019 Alexandre Spangaro + * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,17 +30,19 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; // Load translation files required by the page $langs->loadLangs(array("compta","accountancy")); -$action = GETPOST('action', 'aZ09'); +$action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); $show_files = GETPOST('show_files', 'int'); -$confirm = GETPOST('confirm', 'alpha'); -$toselect = GETPOST('toselect', 'array'); +$confirm = GETPOST('confirm', 'alpha'); +$toselect = GETPOST('toselect', 'array'); +$socid = GETPOST('socid','int')?GETPOST('socid','int'):GETPOST('id','int'); $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -53,27 +55,31 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if ($sortorder == "") - $sortorder = "DESC"; + $sortorder = "ASC"; if ($sortfield == "") $sortfield = "bk.doc_date"; -$search_year = GETPOST("search_year",'int'); -$search_doc_type = GETPOST("search_doc_type",'alpha'); +/* +$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); +$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); +//$search_doc_type = GETPOST("search_doc_type",'alpha'); $search_doc_ref = GETPOST("search_doc_ref",'alpha'); +*/ $lettering = GETPOST('lettering', 'alpha'); if (!empty($lettering)) { $action=$lettering; } -// Did we click on purge search criteria ? -// All tests are required to be compatible with all browsers -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) +/* +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_year=''; - $search_doc_type=''; + $search_date_start = ''; + $search_date_end = ''; + //$search_doc_type=''; $search_doc_ref=''; } +*/ // Security check @@ -103,6 +109,7 @@ if ($action == 'lettering') { } } +/* if ($action == 'autolettrage') { $result = $lettering->letteringThirdparty($socid); @@ -112,7 +119,7 @@ if ($action == 'autolettrage') { $error++; } } - +*/ /* * View @@ -143,10 +150,8 @@ $sql .= " bk.credit, bk.montant , bk.sens , bk.code_journal , bk.piece_num, bk.l $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk"; $sql .= " WHERE (bk.subledger_account = '" . $object->code_compta_fournisseur . "' AND bk.numero_compte = '" . $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER . "' )"; -if (dol_strlen($search_year)) { - $date_start = dol_mktime(0, 0, 0, 1, 1, $search_year); - $date_end = dol_mktime(23, 59, 59, 12, 31, $search_year); - $sql .= " AND ( bk.doc_date BETWEEN '".$db->idate($date_start)."' AND '".$db->idate($date_end)."' )"; +if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { + $sql .= " AND (bk.doc_date BETWEEN '".$db->idate($search_date_start)."' AND '".$db->idate($search_date_end)."' )"; } $sql.= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; @@ -174,7 +179,7 @@ while ($obj = $db->fetch_object($resql)) { $sql.= $db->plimit($limit+1, $offset); -dol_syslog ( "/accountancy/bookkeeping/thirdparty_lettrage_supplier.php", LOG_DEBUG ); +dol_syslog ( "/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG ); $resql = $db->query($sql); if (! $resql) { @@ -182,43 +187,68 @@ if (! $resql) exit; } +$param=''; +$param.="&socid=".urlencode($socid); + $num = $db->num_rows($resql); -dol_syslog ( "/accountancy/bookkeeping/thirdparty_lettrage_supplier.php", LOG_DEBUG ); +dol_syslog ( "/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG ); $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); $i = 0; + $param="&socid=".$socid; print '
'; print ''; - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); + $letteringbutton = ''; + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); + + print '
'; + print ''."\n"; + + /* + print ''; + //print ''; + + // Date + print ''; + + // Piece + print ''; + + print ''; + print ''; + print ''; + */ - print "
'; + print '
'; + print $langs->trans('From') . ' '; + print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); + print '
'; + print '
'; + print $langs->trans('to') . ' '; + print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); + print '
'; + print '
 '; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
"; print ''; - print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder); + //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("", "","",'','',"",$sortfield,$sortorder,'maxwidthsearch center '); print "\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $solde = 0; $tmp = ''; while ($obj = $db->fetch_object($resql)) { @@ -228,48 +258,53 @@ if ($resql) { print ''; - if (empty($obj->lettering_code)) { - print '' . "\n"; - } else { - print '' . "\n"; - } - - print ''; + //print '' . "\n"; + print ''; print ''; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + + // Journal + $accountingjournal = new AccountingJournal($db); + $result = $accountingjournal->fetch('',$obj->code_journal); + $journaltoshow = (($result > 0)?$accountingjournal->getNomUrl(0,0,0,'',0) : $obj->code_journal); + print ''; if (empty($obj->lettering_code)) { - print ''; - } else - print ''; + print ''; + print '' . "\n"; + } else { + print ''; + print ''; + } print "\n"; } print ''; - print '' . "\n"; - print ''; - print ''; - print ''; + print '' . "\n"; + print ''; + print ''; + print ''; print "\n"; print ''; - print '' . "\n"; + print '' . "\n"; print ''; - print ''; - print ''; + print ''; + print ''; print "\n"; print "
 '; - $searchpicto=$form->showFilterButtons(); - print $searchpicto; - print '
'; - print img_edit(); - print ' ' . $obj->doc_type . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_ref . '' . $obj->label_compte . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $obj->code_journal . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $journaltoshow . '' . $obj->lettering_code . ''; + print img_edit(); + print '' . $obj->lettering_code . '
'.$langs->trans("Total").':' . price($debit) . '' . price($credit) . ''.$langs->trans("Total").':' . price($debit) . '' . price($credit) . '
'.$langs->trans("Balancing").':'.$langs->trans("Balancing").': ' . price($credit - $debit) . '' . price($credit - $debit) . '
"; - print ''; - //print ''.$langs->trans('AccountancyAutoLettering').''; + print '
'."\n"; + print $letteringbutton; + print '
'; + print ""; $db->free($resql); } else { diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php index b0ad8150ad4..174f5fa42f5 100644 --- a/htdocs/accountancy/class/lettering.class.php +++ b/htdocs/accountancy/class/lettering.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2013 Olivier Geffroy - * Copyright (C) 2013-2018 Alexandre Spangaro + * Copyright (C) 2013-2019 Alexandre Spangaro * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -66,13 +66,13 @@ class Lettering extends BookKeeping $sql .= " , bk.sens , bk.code_journal , bk.piece_num, bk.date_lettering, bu.url_id , bu.type "; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu ON(bk.fk_doc = bu.fk_bank AND bu.type IN ('payment', 'payment_supplier') ) "; - $sql .= " WHERE ( "; + $sql .= " WHERE ( "; if (! empty($object->code_compta)) - $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) - $sql .= " OR "; + $sql .= " OR "; if (! empty($object->code_compta_fournisseur)) - $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; $sql .= " ) AND (bk.date_lettering ='' OR bk.date_lettering IS NULL) "; $sql .= " AND (bk.lettering_code != '' OR bk.lettering_code IS NULL) "; @@ -128,15 +128,15 @@ class Lettering extends BookKeeping $sql .= " AND facf.entity = ".$conf->entity; $sql .= " AND ( "; if (! empty($object->code_compta)) { - $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; } if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) { - $sql .= " OR "; + $sql .= " OR "; } if (! empty($object->code_compta_fournisseur)) { - $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; } - $sql .= " ) "; + $sql .= ") "; $resql2 = $this->db->query($sql); if ($resql2) { @@ -253,7 +253,7 @@ class Lettering extends BookKeeping $error++; } - $sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE "; + $sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE "; $sql .= " rowid IN (" . implode(',', $ids) . ") "; $result = $this->db->query($sql); if ($result) { diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php index 553ce2e54e0..e82eec71fec 100644 --- a/htdocs/admin/dolistore/class/dolistore.class.php +++ b/htdocs/admin/dolistore/class/dolistore.class.php @@ -17,7 +17,10 @@ */ include_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -include_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/PSWebServiceLibrary.class.php'; +if (! class_exists('PrestaShopWebservice')) // We keep this because some modules add this lib too into a different path. This is to avoid "Cannot declare class PrestaShopWebservice" errors. +{ + include_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/PSWebServiceLibrary.class.php'; +} /** diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 9843c6a4fb0..0decb3120bd 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -106,9 +106,7 @@ elseif ($action == 'update_currency') { $error = 0; - $submit = GETPOST('submit', 'alpha'); - - if ($submit == $langs->trans('Modify')) + if (GETPOST('updatecurrency', 'alpha')) { $fk_multicurrency = GETPOST('fk_multicurrency', 'int'); $rate = price2num(GETPOST('rate', 'alpha')); @@ -127,7 +125,7 @@ elseif ($action == 'update_currency') } } } - elseif ($submit == $langs->trans('Delete')) + elseif (GETPOST('deletecurrency', 'alpha')) { $fk_multicurrency = GETPOST('fk_multicurrency', 'int'); $currency = new MultiCurrency($db); @@ -334,8 +332,8 @@ foreach ($TCurrency as &$currency) print ''; print '1 '.$conf->currency.' = '; print ' '.$currency->code.' '; - print ' '; - print ''; + print ' '; + print ''; print ''; print ''; } diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 55be556afb9..231699dc636 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -50,7 +50,7 @@ if (! $user->admin) if ($action == 'delete') { - $file=$conf->admin->dir_output.'/'.GETPOST('urlfile'); + $file=$conf->admin->dir_output.'/backup/'.basename(GETPOST('urlfile', 'alpha')); $ret=dol_delete_file($file, 1); if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); diff --git a/htdocs/admin/tools/export.php b/htdocs/admin/tools/export.php index 5bfacc6c4f0..5697e48e07f 100644 --- a/htdocs/admin/tools/export.php +++ b/htdocs/admin/tools/export.php @@ -133,7 +133,8 @@ if ($what == 'mysql') dol_syslog("Command are restricted to ".$dolibarr_main_restrict_os_commands.". We check that one of this command is inside ".$cmddump); foreach($arrayofallowedcommand as $allowedcommand) { - if (preg_match('/'.preg_quote($allowedcommand,'/').'/', $cmddump)) + $basenamecmddump=basename($cmddump); + if (preg_match('/^'.preg_quote($allowedcommand,'/').'$/', $basenamecmddump)) // the provided command $cmddump must be an allowed command { $ok=1; break; diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index a73731699f2..f6b000dd838 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1009,6 +1009,11 @@ if (! empty($hookmanager->resArray['eventarray'])) { } } +// Sort events +foreach($eventarray as $keyDate => &$dateeventarray) +{ + usort($dateeventarray, 'sort_events_by_date'); +} $maxnbofchar=0; @@ -1703,3 +1708,22 @@ function dol_color_minus($color, $minus, $minusunit = 16) } return $newcolor; } + + +/** + * Sort events by date + * + * @param object $a Event A + * @param object $b Event B + * @return int < 0 if event A should be before event B, > 0 otherwise, 0 if they have the exact same time slot + */ +function sort_events_by_date($a, $b) +{ + if($a->datep != $b->datep) + { + return $a->datep - $b->datep; + } + + // If both events have the same start time, longest first + return $b->datef - $a->datef; +} diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 01c28fdcd31..355232a65af 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -759,6 +759,7 @@ if (empty($reshook)) $qty = GETPOST('qty' . $predef); $remise_percent = GETPOST('remise_percent' . $predef); + if (empty($remise_percent)) $remise_percent=0; // Extrafields $extrafieldsline = new ExtraFields($db); diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index e4c8774916f..42717d5ae85 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -2,6 +2,7 @@ /* Copyright (C) 2001-2004 Rodolphe Quiedeville * Copyright (C) 2004-2019 Laurent Destailleur * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2019 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -127,6 +128,8 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $db->begin(); $discount->fk_facture_source=0; // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_facture_source + // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_invoice_supplier_source + $discount->fk_invoice_supplier_source=0; $res=$discount->delete($user); $newid1=$newdiscount1->create($user); $newid2=$newdiscount2->create($user); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index dd9de10b970..82b876666db 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1326,7 +1326,7 @@ if (empty($reshook)) } elseif ($typeamount=='variable') { $descline.= ' ('. $valuedeposit.'%)'; } - + $descline.= ' - '.$srcobject->ref; $result = $object->addline( $descline, @@ -1540,14 +1540,16 @@ if (empty($reshook)) $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); if (empty($datefacture)) { $error++; - $mesg = '
' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '
'; + $mesg = $langs->trans("ErrorFieldRequired", $langs->trans("Date")); + setEventMessages($mesg, null, 'errors'); } $date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']); if (!($_POST['situations'] > 0)) { $error++; - $mesg = '
' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '
'; + $mesg = $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")); + setEventMessages($mesg, null, 'errors'); } if (!$error) { @@ -2275,11 +2277,13 @@ if (empty($reshook)) if (!$object->fetch($id) > 0) dol_print_error($db); if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "") { + $all_progress = GETPOST('all_progress', 'int'); foreach ($object->lines as $line) { $percent = $line->get_prev_progress($object->id); - if (GETPOST('all_progress') < $percent) { - $mesg = '
' . $langs->trans("CantBeLessThanMinPercent") . '
'; + if (floatval($all_progress) < floatval($percent)) { + $mesg = $langs->trans("Line") . ' ' . $i . ' '. $line->ref .' : ' . $langs->trans("CantBeLessThanMinPercent"); + setEventMessages($mesg, null, 'warnings'); $result = -1; } else $object->update_percent($line, $_POST['all_progress']); @@ -2948,7 +2952,7 @@ if ($action == 'create') { // First situation invoice print '
'; - $tmp=' '; + $tmp=' '; $tmp = $tmp.''; $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); print $desc; @@ -3003,7 +3007,23 @@ if ($action == 'create') } else { - print '
'; + print '
'; + $tmp=' '; + $text = ' '; + $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; + $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); + print $desc; + print '
'; + + print '
'; + $tmp=' '; + $text = ' '; + $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; + $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); + print $desc; + print '
'; + + print '
'; $tmp=' '; $text = ' '; $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index f83b024e6ed..e24c0dc23d4 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -354,8 +354,6 @@ $facturestatic=new Facture($db); $formcompany=new FormCompany($db); $thirdpartystatic=new Societe($db); -// llxHeader('',$langs->trans('CustomersInvoices'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); - $sql = 'SELECT'; if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT'; $sql.= ' f.rowid as id, f.facnumber as ref, f.ref_client, f.type, f.note_private, f.note_public, f.increment, f.fk_mode_reglement, f.total as total_ht, f.tva as total_vat, f.total_ttc,'; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 0059609d071..f21e7c06b65 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2108,7 +2108,7 @@ class Contrat extends CommonObject $this->from.= ", ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$user->societe_id) $this->from.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - if ($mode == 'inactives') + if ($mode == 'inactive') { $sql = "SELECT cd.rowid, cd.date_ouverture_prevue as datefin"; $sql.= $this->from; @@ -2123,25 +2123,43 @@ class Contrat extends CommonObject $sql.= " WHERE c.statut = 1"; $sql.= " AND c.rowid = cd.fk_contrat"; $sql.= " AND cd.statut = 4"; - $sql.= " AND cd.date_fin_validite < '".$this->db->idate(time())."'"; + $sql.= " AND cd.date_fin_validite < '".$this->db->idate(dol_now())."'"; + } + elseif ($mode == 'active') + { + $sql = "SELECT cd.rowid, cd.date_fin_validite as datefin"; + $sql.= $this->from; + $sql.= " WHERE c.statut = 1"; + $sql.= " AND c.rowid = cd.fk_contrat"; + $sql.= " AND cd.statut = 4"; + //$datetouse = dol_now(); + //$sql.= " AND cd.date_fin_validite < '".$this->db->idate($datetouse)."'"; } $sql.= " AND c.fk_soc = s.rowid"; $sql.= " AND c.entity = ".$conf->entity; if ($user->societe_id) $sql.=" AND c.fk_soc = ".$user->societe_id; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + $resql=$this->db->query($sql); if ($resql) { $langs->load("contracts"); $now=dol_now(); - if ($mode == 'inactives') { + if ($mode == 'inactive') { $warning_delay = $conf->contrat->services->inactifs->warning_delay; $label = $langs->trans("BoardNotActivatedServices"); - $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=0'; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=0&sortfield=cd.date_fin_validite&sortorder=asc'; + } + elseif ($mode == 'expired') { + $warning_delay = $conf->contrat->services->expires->warning_delay; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired&sortfield=cd.date_fin_validite&sortorder=asc'; + $label = $langs->trans("BoardExpiredServices"); } else { $warning_delay = $conf->contrat->services->expires->warning_delay; - $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired'; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&sortfield=cd.date_fin_validite&sortorder=asc'; + //$url.= '&op2day='.$arraydatetouse['mday'].'&op2month='.$arraydatetouse['mon'].'&op2year='.$arraydatetouse['year']; + //if ($warning_delay >= 0) $url.='&filter=expired'; $label = $langs->trans("BoardRunningServices"); } diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index da852b8a46d..381adbff567 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -344,6 +344,7 @@ if (! $error && $massaction == 'confirm_presend') if ($objectclass == 'Supplier_Proposal') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO)); if ($objectclass == 'CommandeFournisseur') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO)); if ($objectclass == 'FactureFournisseur') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO)); + if ($objectclass == 'Project') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO)); // $listofqualifiedobj is array with key = object id and value is instance of qualified objects, for the current thirdparty (but thirdparty property is not loaded yet) // $looparray will be an array with number of email to send for the current thirdparty (so 1 or n if n object for same thirdparty) @@ -364,8 +365,8 @@ if (! $error && $massaction == 'confirm_presend') $looparray[0]=$objectforloop; } //var_dump($looparray);exit; - dol_syslog("We have set an array of ".count($looparray)." emails to send"); - + dol_syslog("We have set an array of ".count($looparray)." emails to send. oneemailperrecipient=".$oneemailperrecipient); + //var_dump($oneemailperrecipient); var_dump($listofqualifiedobj); var_dump($listofqualifiedref); foreach ($looparray as $objectid => $objecttmp) // $objecttmp is a real object or an empty object if we choose to send one email per thirdparty instead of one per object { // Make substitution in email content @@ -386,8 +387,8 @@ if (! $error && $massaction == 'confirm_presend') complete_substitutions_array($substitutionarray, $langs, $objecttmp, $parameters); - $subject=make_substitutions($subject, $substitutionarray); - $message=make_substitutions($message, $substitutionarray); + $subjectreplaced=make_substitutions($subject, $substitutionarray); + $messagereplaced=make_substitutions($message, $substitutionarray); $filepath = $attachedfiles['paths']; $filename = $attachedfiles['names']; @@ -415,10 +416,11 @@ if (! $error && $massaction == 'confirm_presend') } //var_dump($filepath); //var_dump($trackid);exit; + //var_dump($subjectreplaced); // Send mail (substitutionarray must be done just before this) require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1,'','',$trackid); + $mailfile = new CMailFile($subjectreplaced, $sendto, $from, $messagereplaced, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1, '', '', $trackid); if ($mailfile->error) { $resaction.='
'.$mailfile->error.'
'; @@ -450,9 +452,9 @@ if (! $error && $massaction == 'confirm_presend') if ($message) { if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); - $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subjectreplaced); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); - $actionmsg = dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $messagereplaced); } $actionmsg2=''; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9b2db295296..de6bdcceef6 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1192,7 +1192,7 @@ abstract class CommonObject $sql.= " AND ec.fk_c_type_contact = tc.rowid"; $sql.= " AND tc.element = '".$element."'"; $sql.= " AND tc.source = '".$source."'"; - $sql.= " AND tc.code = '".$code."'"; + if ($code) $sql.= " AND tc.code = '".$code."'"; $sql.= " AND tc.active = 1"; if ($status) $sql.= " AND ec.statut = ".$status; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 47a9d7a28ae..fe8a812a8a2 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -235,9 +235,9 @@ class Form } else if (preg_match('/^ckeditor/',$typeofdata)) { - $tmp=explode(':',$typeofdata); // Example: ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols + $tmp=explode(':',$typeofdata); // Example: ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols:uselocalbrowser require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor($htmlname, ($editvalue?$editvalue:$value), ($tmp[2]?$tmp[2]:''), ($tmp[3]?$tmp[3]:'100'), ($tmp[1]?$tmp[1]:'dolibarr_notes'), 'In', ($tmp[5]?$tmp[5]:0), true, true, ($tmp[6]?$tmp[6]:'20'), ($tmp[7]?$tmp[7]:'100')); + $doleditor=new DolEditor($htmlname, ($editvalue?$editvalue:$value), ($tmp[2]?$tmp[2]:''), ($tmp[3]?$tmp[3]:'100'), ($tmp[1]?$tmp[1]:'dolibarr_notes'), 'In', ($tmp[5]?$tmp[5]:0), (isset($tmp[8])?($tmp[8]?true:false):true), true, ($tmp[6]?$tmp[6]:'20'), ($tmp[7]?$tmp[7]:'100')); $ret.=$doleditor->Create(1); } if (empty($notabletag)) $ret.=''; diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index c42acac2549..d455d1058fc 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -711,7 +711,7 @@ class FormMail extends Form } else { - $out.= 'withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />'; + $out.= 'withtocc) && ! is_numeric($this->withtocc)) ? $this->withtocc : '')).'" />'; if (! empty($this->withtocc) && is_array($this->withtocc)) { $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; @@ -762,7 +762,7 @@ class FormMail extends Form } else { - $out.= 'withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />'; + $out.= 'withtoccc) && ! is_numeric($this->withtoccc)) ? $this->withtoccc : '')).'" />'; if (! empty($this->withtoccc) && is_array($this->withtoccc)) { $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; @@ -779,9 +779,12 @@ class FormMail extends Form $showinfobcc=''; if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO; - if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO; if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO; if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO) && ! empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) && ! empty($this->param['models']) && $this->param['models'] == 'invoice_supplier_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO) && ! empty($this->param['models']) && $this->param['models'] == 'project') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO; if ($showinfobcc) $out.=' + '.$showinfobcc; $out.= "\n"; } diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index a8d22b61257..c48c1ed6bac 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -466,7 +466,9 @@ class Translate if (! $found && ! empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) { // Overwrite translation with database read - $sql="SELECT transkey, transvalue FROM ".MAIN_DB_PREFIX."overwrite_trans where lang='".$db->escape($this->defaultlang)."'"; + $sql ="SELECT transkey, transvalue FROM ".MAIN_DB_PREFIX."overwrite_trans where lang='".$db->escape($this->defaultlang)."' OR lang IS NULL"; + $sql.=" AND entity IN (0, ".getEntity('overwrite_trans').")"; + $sql.=$db->order("lang", "DESC"); $resql=$db->query($sql); if ($resql) diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 8c051c85b33..3d43a319e51 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -239,36 +239,37 @@ class Utils dol_mkdir($conf->admin->dir_output.'/backup'); // Parameteres execution - $command=$cmddump; - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command + $command = $cmddump; + $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. + if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host; $param.=" -u ".$dolibarr_main_db_user; if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port; - if (! GETPOST("use_transaction")) $param.=" -l --single-transaction"; - if (GETPOST("disable_fk") || $usedefault) $param.=" -K"; - if (GETPOST("sql_compat") && GETPOST("sql_compat") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat","alpha")); - if (GETPOST("drop_database")) $param.=" --add-drop-database"; - if (GETPOST("sql_structure") || $usedefault) + if (! GETPOST("use_transaction", "alpha")) $param.=" -l --single-transaction"; + if (GETPOST("disable_fk", "alpha") || $usedefault) $param.=" -K"; + if (GETPOST("sql_compat", "alpha") && GETPOST("sql_compat", "alpha") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat", "alpha")); + if (GETPOST("drop_database", "alpha")) $param.=" --add-drop-database"; + if (GETPOST("sql_structure", "alpha") || $usedefault) { - if (GETPOST("drop") || $usedefault) $param.=" --add-drop-table=TRUE"; - else $param.=" --add-drop-table=FALSE"; + if (GETPOST("drop", "alpha") || $usedefault) $param.=" --add-drop-table=TRUE"; + else $param.=" --add-drop-table=FALSE"; } else { $param.=" -t"; } - if (GETPOST("disable-add-locks")) $param.=" --add-locks=FALSE"; - if (GETPOST("sql_data") || $usedefault) + if (GETPOST("disable-add-locks", "alpha")) $param.=" --add-locks=FALSE"; + if (GETPOST("sql_data", "alpha") || $usedefault) { $param.=" --tables"; - if (GETPOST("showcolumns") || $usedefault) $param.=" -c"; - if (GETPOST("extended_ins") || $usedefault) $param.=" -e"; + if (GETPOST("showcolumns", "alpha") || $usedefault) $param.=" -c"; + if (GETPOST("extended_ins", "alpha") || $usedefault) $param.=" -e"; else $param.=" --skip-extended-insert"; - if (GETPOST("delayed")) $param.=" --delayed-insert"; - if (GETPOST("sql_ignore")) $param.=" --insert-ignore"; - if (GETPOST("hexforbinary") || $usedefault) $param.=" --hex-blob"; + if (GETPOST("delayed", "alpha")) $param.=" --delayed-insert"; + if (GETPOST("sql_ignore", "alpha")) $param.=" --insert-ignore"; + if (GETPOST("hexforbinary", "alpha") || $usedefault) $param.=" --hex-blob"; } else { @@ -436,8 +437,9 @@ class Utils dol_mkdir($conf->admin->dir_output.'/backup'); // Parameteres execution - $command=$cmddump; - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command + $command = $cmddump; + $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. + if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); //$param="-F c"; diff --git a/htdocs/core/js/timesheet.js b/htdocs/core/js/timesheet.js index 3bd93555d76..0a4aa9989ff 100644 --- a/htdocs/core/js/timesheet.js +++ b/htdocs/core/js/timesheet.js @@ -90,24 +90,20 @@ function pad(n) { /* function from http://www.timlabonne.com/2013/07/parsing-a-time-string-with-javascript/ */ +/* timeStr must be a duration with format XX:YY (AM/PM not supported) */ function parseTime(timeStr, dt) { if (!dt) { dt = new Date(); } - var time = timeStr.match(/(\d+)(?::(\d\d))?\s*(p?)/i); + //var time = timeStr.match(/(\d+)(?::(\d\d))?\s*(p?)/i); + var time = timeStr.match(/(\d+)(?::(\d\d))?/i); if (!time) { return -1; } var hours = parseInt(time[1], 10); - if (hours == 12 && !time[3]) { - hours = 0; - } - else { - hours += (hours < 12 && time[3]) ? 12 : 0; - } - + dt.setHours(hours); dt.setMinutes(parseInt(time[2], 10) || 0); dt.setSeconds(0, 0); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8c3393dd08e..570d00ef2bd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -349,7 +349,7 @@ function GETPOST($paramname, $check='none', $method=0, $filter=null, $options=nu } if (! empty($conf->global->MAIN_ENABLE_DEFAULT_VALUES)) { - if (! empty($_GET['action']) && $_GET['action'] == 'create' && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname])) + if (! empty($_GET['action']) && (preg_match('/^create/', $_GET['action']) || preg_match('/^presend/', $_GET['action'])) && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname])) { // Now search in setup to overwrite default values if (! empty($user->default_values)) // $user->default_values defined from menu 'Setup - Default values' diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 8b6ca6a5ca3..8922b1675dd 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -461,7 +461,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } // Ref of task - print ''; + print ''; if ($showlineingray) { print ''.img_object('','projecttask').' '.$lines[$i]->ref.''; diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php index 1cafb6dc3d4..6dc78611c26 100644 --- a/htdocs/core/lib/sendings.lib.php +++ b/htdocs/core/lib/sendings.lib.php @@ -51,7 +51,7 @@ function shipping_prepare_head($object) { // delivery link $object->fetchObjectLinked($object->id,$object->element); - if (count($object->linkedObjectsIds['delivery']) > 0) // If there is a delivery + if (is_array($object->linkedObjectsIds['delivery']) && count($object->linkedObjectsIds['delivery']) > 0) // If there is a delivery { // Take first one element of array $tmp = reset($object->linkedObjectsIds['delivery']); diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 6f1057936d8..090a0f908dd 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -31,7 +31,7 @@ * @param string $content Content to replace * @param int $removephppart 0=Replace PHP sections with a PHP badge. 1=Remove completely PHP sections. * @return boolean True if OK - * @see dolWebsiteOutput for function used to replace content in a web server context + * @see dolWebsiteOutput() for function used to replace content in a web server context */ function dolWebsiteReplacementOfLinks($website, $content, $removephppart=0) { @@ -101,6 +101,7 @@ function dolWebsiteReplacementOfLinks($website, $content, $removephppart=0) * @param string $str String to clean * @param string $replacewith String to use as replacement * @return string Result string without php code + * @see dolKeepOnlyPhpCode() */ function dolStripPhpCode($str, $replacewith='') { @@ -133,6 +134,44 @@ function dolStripPhpCode($str, $replacewith='') return $newstr; } +/** + * Keep only PHP code part from a HTML string page. + * + * @param string $str String to clean + * @return string Result string with php code only + * @see dolStripPhpCode() + */ +function dolKeepOnlyPhpCode($str) +{ + $newstr = ''; + + //split on each opening tag + $parts = explode('', $part, 2); + if (!empty($partlings)) + { + $newstr .= $partlings[0].'?>'; + } + else + { + $newstr .= $part.'?>'; + } + } + } + return $newstr; +} /** * Render a string of an HTML content and output it. @@ -140,7 +179,7 @@ function dolStripPhpCode($str, $replacewith='') * * @param string $content Content string * @return void - * @see dolWebsiteReplacementOfLinks for function used to replace content in the backoffice context when USEDOLIBARREDITOR is not on + * @see dolWebsiteReplacementOfLinks() for function used to replace content in the backoffice context when USEDOLIBARREDITOR is not on */ function dolWebsiteOutput($content) { diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index b725ef878a3..94e3d56cb12 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -201,6 +201,11 @@ class modProduct extends DolibarrModules if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cp.fk_categorie = cat.rowid'; @@ -218,7 +223,7 @@ class modProduct extends DolibarrModules $this->export_label[$r]="ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("produit","export")); $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", 'pr.tva_tx'=>'PriceLevelVATRate', @@ -240,7 +245,39 @@ class modProduct extends DolibarrModules $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity - $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile + } + + if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + // Exports product multiprice + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]="ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r]=array(array("produit","export")); + $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", + 's.nom'=>'ThirdParty', + 'pr.price_base_type'=>"PriceBase", + 'pr.price'=>"PriceUnitPriceHT",'pr.price_ttc'=>"PriceUnitPriceTTC", + 'pr.price_min'=>"MinPriceUnitPriceHT",'pr.price_min_ttc'=>"MinPriceUnitPriceTTC", + 'pr.tva_tx'=>'PriceVATRate', + 'pr.default_vat_code'=>'PriceVATCode', + 'pr.datec'=>'DateCreation'); + if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR'; + $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product", + 's.nom'=>'company', + 'pr.price_base_type'=>"product",'pr.price'=>"product", + 'pr.price_ttc'=>"product", + 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product", + 'pr.tva_tx'=>'product', + 'pr.default_vat_code'=>'product', + 'pr.recuperableonly'=>'product', + 'pr.datec'=>"product"); + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile } if (! empty($conf->global->PRODUIT_SOUSPRODUITS)) @@ -287,7 +324,7 @@ class modProduct extends DolibarrModules $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,'; $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2'; - $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile $this->export_sql_end[$r] .=' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils'; } @@ -362,7 +399,7 @@ class modProduct extends DolibarrModules 'sp.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty'), 'sp.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') ); - $this->import_examplevalues_array[$r]=array('sp.fk_product'=>"PREF123456", + $this->import_examplevalues_array[$r]=array('sp.fk_product'=>"PRODUCT_REF or id:123456", 'sp.fk_soc'=>"My Supplier",'sp.ref_fourn'=>"SupplierRef", 'sp.quantity'=>"1", 'sp.tva_tx'=>'21', 'sp.price'=>"50", 'sp.unitprice'=>'50', @@ -381,16 +418,19 @@ class modProduct extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('pr'=>MAIN_DB_PREFIX.'product_price'); $this->import_tables_creator_array[$r]=array('pr'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductRowid*", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductOrService*", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", - 'pr.tva_tx'=>'PriceLevelVATRate', 'pr.date_price'=>'DateCreation*'); + if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) $this->import_fields_array[$r]['pr.tva_tx']='VATRate'; if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('pr.recuperableonly'=>'NPR')); $this->import_regex_array[$r]=array('pr.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','pr.recuperableonly'=>'^[0|1]$'); - $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"1", - 'pr.price_base_type'=>"HT",'pr.price_level'=>"1", + $this->import_convertvalue_array[$r]=array( + 'pr.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') + ); + $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"PRODUCT_REF or id:123456", + 'pr.price_base_type'=>"HT (for excl tax) or TTC (for inc tax)",'pr.price_level'=>"1", 'pr.price'=>"100",'pr.price_ttc'=>"110", 'pr.price_min'=>"100",'pr.price_min_ttc'=>"110", 'pr.tva_tx'=>'20', @@ -407,13 +447,13 @@ class modProduct extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('l'=>MAIN_DB_PREFIX.'product_lang'); // multiline translation, one line per translation - $this->import_fields_array[$r]=array('l.fk_product'=>'Ref', 'l.lang'=>'Language', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); + $this->import_fields_array[$r]=array('l.fk_product'=>'ProductOrService*', 'l.lang'=>'Language*', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); //$this->import_fields_array[$r]['l.note']='TranslatedNote'; $this->import_convertvalue_array[$r]=array( 'l.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') ); - $this->import_examplevalues_array[$r]=array('l.fk_product'=>'MyProductRef','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); - $this->import_updatekeys_array[$r]=array('l.fk_product'=>'Ref','l.lang'=>'Language'); + $this->import_examplevalues_array[$r]=array('l.fk_product'=>'PRODUCT_REF or id:123456','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); + $this->import_updatekeys_array[$r]=array('l.fk_product'=>'ProductOrService','l.lang'=>'Language'); } } diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 6e5f5562a77..9ff04f3fd71 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -145,60 +145,43 @@ class modService extends DolibarrModules $this->export_code[$r]=$this->rights_class.'_'.$r; $this->export_label[$r]="Services"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("service","export")); - $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification'); - if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock')); + $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification'); + if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly']='NPR'; + if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.barcode'=>'BarCode')); + if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.cost_price'=>'CostPrice')); + $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('group_concat(cat.label)'=>'Categories')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit'; - //$this->export_TypeFields_array[$r]=array('p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",'p.note'=>"Text",'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date'); - $this->export_TypeFields_array[$r]=array('p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",'p.note'=>"Text",'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date'); + $this->export_TypeFields_array[$r]=array('p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",'p.note'=>"Text",'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date'); if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.stock'=>'Numeric')); if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.barcode'=>'Text')); - $this->export_entities_array[$r]=array('p.rowid'=>"service",'p.ref'=>"service",'p.label'=>"service",'p.description'=>"service",'p.accountancy_code_sell'=>'service','p.note'=>"service",'p.price_base_type'=>"service",'p.price'=>"service",'p.price_ttc'=>"service",'p.tva_tx'=>"service",'p.tosell'=>"service",'p.tobuy'=>"service",'p.duration'=>"service",'p.datec'=>"service",'p.tms'=>"service"); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'service')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'service')); - // Add extra fields - $sql="SELECT name, label, type FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product'"; - $resql=$this->db->query($sql); - if ($resql) // This can fail when class is used on old database (during migration for example) - { - while ($obj=$this->db->fetch_object($resql)) - { - $fieldname='extra.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) - { - case 'int': - case 'double': - case 'price': - $typeFilter="Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter="Date"; - break; - case 'boolean': - $typeFilter="Boolean"; - break; - case 'sellist': - $tmp=''; - $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options'])); - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; - break; - } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='product'; - } - } - // End add extra fields - + if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array("group_concat(cat.label)"=>'Text')); + $this->export_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array("group_concat(cat.label)"=>'category')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object'; + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cp.fk_categorie = cat.rowid'; + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_lang as l ON l.fk_product = p.rowid'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object'; if (! empty($conf->fournisseur->enabled)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price as pf ON pf.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'societe s ON s.rowid = pf.fk_soc'; $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 1 AND p.entity IN ('.getEntity('product').')'; - + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_order[$r] =' GROUP BY p.rowid'; // FIXME The group by used a generic value to say "all fields in select except function fields" if (empty($conf->product->enabled)) // We enable next import templates only if module product not already enabled (to avoid duplicate entries) { @@ -210,11 +193,12 @@ class modService extends DolibarrModules $this->export_label[$r]="ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("produit","export")); $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", 'pr.tva_tx'=>'PriceLevelVATRate', 'pr.date_price'=>'DateCreation'); + if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR'; //$this->export_TypeFields_array[$r]=array( // 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text", // 'p.note'=>"Text",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.weight'=>"Numeric",'p.customcode'=>'Text', @@ -226,15 +210,95 @@ class modService extends DolibarrModules 'pr.price_ttc'=>"product", 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product", 'pr.tva_tx'=>'product', - 'pr.date_price'=>"product"); + 'pr.recuperableonly'=>'product', + 'pr.date_price'=>"product"); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product'; - $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; + } + + if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + // Exports product multiprice + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]="ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r]=array(array("produit","export")); + $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", + 's.nom'=>'ThirdParty', + 'pr.price_base_type'=>"PriceBase", + 'pr.price'=>"PriceUnitPriceHT",'pr.price_ttc'=>"PriceUnitPriceTTC", + 'pr.price_min'=>"MinPriceUnitPriceHT",'pr.price_min_ttc'=>"MinPriceUnitPriceTTC", + 'pr.tva_tx'=>'PriceVATRate', + 'pr.default_vat_code'=>'PriceVATCode', + 'pr.datec'=>'DateCreation'); + if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR'; + $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product", + 's.nom'=>'company', + 'pr.price_base_type'=>"product",'pr.price'=>"product", + 'pr.price_ttc'=>"product", + 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product", + 'pr.tva_tx'=>'product', + 'pr.default_vat_code'=>'product', + 'pr.recuperableonly'=>'product', + 'pr.datec'=>"product"); + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; + } + + if (! empty($conf->global->PRODUIT_SOUSPRODUITS)) + { + // Exports virtual products + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]="AssociatedProducts"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r]=array(array("produit","export")); + $this->export_fields_array[$r]=array( + 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl", + 'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note", + 'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.customcode'=>'CustomCode', + 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell", + 'p.tobuy'=>"OnBuy",'p.datec'=>'DateCreation','p.tms'=>'DateModification' + ); + if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.barcode'=>'BarCode')); + $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock')); + $this->export_TypeFields_array[$r]=array( + 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text", + 'p.note'=>"Text",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.weight'=>"Numeric",'p.customcode'=>'Text', + 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", + 'p.datec'=>'Date','p.tms'=>'Date' + ); + if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric')); + if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.barcode'=>'Text')); + $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('pa.qty'=>'Numeric')); + $this->export_entities_array[$r]=array( + 'p.rowid'=>"virtualproduct",'p.ref'=>"virtualproduct",'p.label'=>"virtualproduct",'p.description'=>"virtualproduct",'p.url'=>"virtualproduct", + 'p.accountancy_code_sell'=>'virtualproduct','p.accountancy_code_buy'=>'virtualproduct','p.note'=>"virtualproduct",'p.length'=>"virtualproduct", + 'p.surface'=>"virtualproduct",'p.volume'=>"virtualproduct",'p.weight'=>"virtualproduct",'p.customcode'=>'virtualproduct', + 'p.price_base_type'=>"virtualproduct",'p.price'=>"virtualproduct",'p.price_ttc'=>"virtualproduct",'p.tva_tx'=>"virtualproduct", + 'p.tosell'=>"virtualproduct",'p.tobuy'=>"virtualproduct",'p.datec'=>"virtualproduct",'p.tms'=>"virtualproduct" + ); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'virtualproduct','p.seuil_stock_alerte'=>'virtualproduct','p.desiredstock'=>'virtualproduct','p.pmp'=>'virtualproduct')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'virtualproduct')); + $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('pa.qty'=>"subproduct",'pa.incdec'=>'subproduct')); + $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p2.rowid'=>"Id",'p2.ref'=>"Ref",'p2.label'=>"Label",'p2.description'=>"Description")); + $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p2.rowid'=>"subproduct",'p2.ref'=>"subproduct",'p2.label'=>"subproduct",'p2.description'=>"subproduct")); + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,'; + $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils'; } } - // Imports //-------- $r=0; @@ -250,11 +314,17 @@ class modService extends DolibarrModules 'p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume", 'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC", - 'p.tva_tx'=>'VAT','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation' + 'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation' ); - if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.barcode'=>'BarCode')); + //if (! empty($conf->stock->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.cost_price'=>'CostPrice')); + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); + if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.barcode'=>'BarCode')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->import_fields_array[$r]['p.fk_unit'] = 'Unit'; // Add extra fields + $import_extrafield_sample=array(); $sql="SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product' AND entity IN (0,".$conf->entity.")"; $resql=$this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) @@ -264,13 +334,15 @@ class modService extends DolibarrModules $fieldname='extra.'.$obj->name; $fieldlabel=ucfirst($obj->label); $this->import_fields_array[$r][$fieldname]=$fieldlabel.($obj->fieldrequired?'*':''); + $import_extrafield_sample[$fieldname]=$fieldlabel; } } // End add extra fields $this->import_fieldshidden_array[$r]=array('extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'product'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) - $this->import_regex_array[$r]=array('p.ref'=>'[^ ]','p.tosell'=>'^[0|1]$','p.tobuy'=>'^[0|1]$','p.fk_product_type'=>'^[0|1]$','p.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'); - $this->import_examplevalues_array[$r]=array('p.ref'=>"PREF123456",'p.label'=>"My product",'p.description'=>"This is a description example for record",'p.note'=>"Some note",'p.price'=>"100",'p.price_ttc'=>"110",'p.tva_tx'=>'10','p.tosell'=>"0 or 1",'p.tobuy'=>"0 or 1",'p.fk_product_type'=>"0 for product/1 for service",'p.finished'=>'','p.duration'=>"1y",'p.datec'=>'2008-12-31'); - + $this->import_regex_array[$r]=array('p.ref'=>'[^ ]','p.tosell'=>'^[0|1]$','p.tobuy'=>'^[0|1]$','p.fk_product_type'=>'^[0|1]$','p.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','p.recuperableonly'=>'^[0|1]$'); + $import_sample=array('p.ref'=>"PREF123456",'p.label'=>"My product",'p.description'=>"This is a description example for record",'p.note'=>"Some note",'p.price'=>"100",'p.price_ttc'=>"110",'p.tva_tx'=>'10','p.tosell'=>"0 or 1",'p.tobuy'=>"0 or 1",'p.fk_product_type'=>"0 for product/1 for service",'p.finished'=>'','p.duration'=>"1y",'p.datec'=>'2008-12-31','p.recuperableonly'=>'0 or 1'); + $this->import_examplevalues_array[$r]=array_merge($import_sample,$import_extrafield_sample); + $this->import_updatekeys_array[$r]=array('p.ref'=>'Ref','p.barcode'=>'BarCode'); if (empty($conf->product->enabled)) // We enable next import templates only if module product not already enabled (to avoid duplicate entries) { @@ -301,12 +373,13 @@ class modService extends DolibarrModules 'sp.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty'), 'sp.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') ); - $this->import_examplevalues_array[$r]=array('sp.fk_product'=>"PREF123456", + $this->import_examplevalues_array[$r]=array('sp.fk_product'=>"SERVICE_REF or id:123456", 'sp.fk_soc'=>"My Supplier",'sp.ref_fourn'=>"SupplierRef", 'sp.quantity'=>"1", 'sp.tva_tx'=>'21', 'sp.price'=>"50", 'sp.unitprice'=>'50', 'sp.remise_percent'=>'0' ); + $this->import_updatekeys_array[$r]=array('sp.fk_product'=>'ProductOrService','sp.ref_fourn'=>'SupplierRef','sp.fk_soc'=>'Supplier'); } if (! empty($conf->global->PRODUIT_MULTIPRICES)) @@ -319,18 +392,23 @@ class modService extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('pr'=>MAIN_DB_PREFIX.'product_price'); $this->import_tables_creator_array[$r]=array('pr'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductRowid*", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductOrService*", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", - 'pr.tva_tx'=>'PriceLevelVATRate', 'pr.date_price'=>'DateCreation*'); - $this->import_regex_array[$r]=array('pr.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'); - $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"1", - 'pr.price_base_type'=>"HT",'pr.price_level'=>"1", + if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) $this->import_fields_array[$r]['pr.tva_tx']='VATRate'; + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('pr.recuperableonly'=>'NPR')); + $this->import_regex_array[$r]=array('pr.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','pr.recuperableonly'=>'^[0|1]$'); + $this->import_convertvalue_array[$r]=array( + 'pr.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') + ); + $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"SERVICE_REF or id:123456", + 'pr.price_base_type'=>"HT (for excl tax) or TTC (for inc tax)",'pr.price_level'=>"1", 'pr.price'=>"100",'pr.price_ttc'=>"110", 'pr.price_min'=>"100",'pr.price_min_ttc'=>"110", - 'pr.tva_tx'=>'19.6', + 'pr.tva_tx'=>'20', + 'pr.recuperableonly'=>'0', 'pr.date_price'=>'2013-04-10'); } @@ -343,13 +421,13 @@ class modService extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('l'=>MAIN_DB_PREFIX.'product_lang'); // multiline translation, one line per translation - $this->import_fields_array[$r]=array('l.fk_product'=>'Ref', 'l.lang'=>'Language', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); + $this->import_fields_array[$r]=array('l.fk_product'=>'ProductOrService*', 'l.lang'=>'Language*', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); //$this->import_fields_array[$r]['l.note']='TranslatedNote'; $this->import_convertvalue_array[$r]=array( 'l.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') ); - $this->import_examplevalues_array[$r]=array('l.fk_product'=>'MyProductRef','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); - $this->import_updatekeys_array[$r]=array('l.fk_product'=>'Ref','l.lang'=>'Language'); + $this->import_examplevalues_array[$r]=array('l.fk_product'=>'SERVICE_REF or id:123456','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); + $this->import_updatekeys_array[$r]=array('l.fk_product'=>'ProductOrService','l.lang'=>'Language'); } } } diff --git a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php index 06cf28daaed..e0546fd61aa 100644 --- a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php @@ -110,7 +110,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders /** * Issuer - * @var Company object that emits + * @var Societe object that emits */ public $emetteur; @@ -1306,9 +1306,9 @@ class pdf_muscadet extends ModelePDFSuppliersOrders - // If BILLING contact defined on order, we use it + // If CUSTOMER contact defined on order, we use it. Note: Even if this is a supplier object, the code for external contat that follow object is 'CUSTOMER' $usecontact=false; - $arrayidcontact=$object->getIdContact('external','BILLING'); + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); if (count($arrayidcontact) > 0) { $usecontact=true; diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index 58758daab09..54464488f0b 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -171,7 +171,7 @@ if ($action == 'presend') $listeuser=array(); $fuserdest = new User($db); - $result= $fuserdest->fetchAll('ASC', 't.lastname', 0, 0, array('customsql'=>'t.statut=1 AND t.employee=1 AND t.email IS NOT NULL AND t.email<>\'\'')); + $result= $fuserdest->fetchAll('ASC', 't.lastname', 0, 0, array('customsql'=>'t.statut=1 AND t.employee=1 AND t.email IS NOT NULL AND t.email<>\'\''), 'AND', true); if ($result>0 && is_array($fuserdest->users) && count($fuserdest->users)>0) { foreach($fuserdest->users as $uuserdest) { $listeuser[$uuserdest->id] = $uuserdest->user_get_property($uuserdest->id,'email'); diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index 9c586f82e9e..a5d7883f3e5 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -112,7 +112,8 @@ if ($massaction == 'presend') $formmail->withtoreadonly = 1; } - $formmail->withoptiononeemailperrecipient = (count($listofselectedref) == 1 || empty($liste))? 0 : ((GETPOST('oneemailperrecipient')=='on')?1:-1); + $formmail->withoptiononeemailperrecipient = ((count($listofselectedref) == 1 && count(reset($listofselectedref)) == 1) || empty($liste)) ? 0 : ((GETPOST('oneemailperrecipient')=='on')?1:-1); + $formmail->withto = empty($liste)?(GETPOST('sendto','alpha')?GETPOST('sendto','alpha'):array()):$liste; $formmail->withtofree = empty($liste)?1:0; $formmail->withtocc = 1; diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index 39e5c545f1b..1dc9f55a80b 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -71,7 +71,7 @@ elseif ($module == 'shipping') { $permission=$user->rights->expedition->cr elseif ($module == 'product') { $permission=$user->rights->produit->creer;} //else dol_print_error('','Bad value '.$module.' for param module'); -if (! empty($conf->fckeditor->enabled) && ! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:95%'; // Rem: This var is for all notes, not only thirdparties note. +if (! empty($conf->fckeditor->enabled) && ! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:95%:0'; // Rem: This var is for all notes, not only thirdparties note. else $typeofdata='textarea:12:95%'; print ''."\n"; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index c949d73c060..26eb1504c42 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -316,7 +316,7 @@ else { if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; $toolbarname='dolibarr_details'; if (! empty($conf->global->FCKEDITOR_ENABLE_DETAILS_FULL)) $toolbarname='dolibarr_notes'; - $doleditor=new DolEditor('dp_desc',GETPOST('dp_desc'),'',100,$toolbarname,'',false,true,$enabled,$nbrows,'98%'); + $doleditor=new DolEditor('dp_desc', GETPOST('dp_desc'), '', (empty($conf->global->MAIN_DOLEDITOR_HEIGHT)?100:$conf->global->MAIN_DOLEDITOR_HEIGHT), $toolbarname, '', false, true, $enabled, $nbrows, '98%'); $doleditor->Create(); // Show autofill date for recuring invoices diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 05bfc3b106d..6ef1332fc72 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -113,7 +113,7 @@ $coldisplay=-1; // We remove first td $enable=(isset($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0); $toolbarname='dolibarr_details'; if (! empty($conf->global->FCKEDITOR_ENABLE_DETAILS_FULL)) $toolbarname='dolibarr_notes'; - $doleditor=new DolEditor('product_desc',$line->description,'',164,$toolbarname,'',false,true,$enable,$nbrows,'98%'); + $doleditor=new DolEditor('product_desc', $line->description, '', (empty($conf->global->MAIN_DOLEDITOR_HEIGHT)?164:$conf->global->MAIN_DOLEDITOR_HEIGHT), $toolbarname, '', false, true, $enable, $nbrows, '98%'); $doleditor->Create(); } else { print ''; diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index 157088d24db..9aa20f8854e 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -307,7 +307,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers $diff_array=array_diff_assoc($qtyordred,$qtyshipped); if (count($diff_array)==0) { //No diff => mean everythings is shipped - $ret=$object->setStatut(Commande::STATUS_CLOSED, $object->origin_id, $object->origin); + $ret=$object->setStatut(Commande::STATUS_CLOSED, $object->origin_id, $object->origin, 'ORDER_CLOSE'); if ($ret<0) { $this->error=$object->error; $this->errors=$object->errors; return $ret; diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php index 1338104de0b..4a2b267fe3a 100644 --- a/htdocs/core/website.inc.php +++ b/htdocs/core/website.inc.php @@ -25,6 +25,8 @@ // Load website class include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; +include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; + // Define $website if (! is_object($website)) { @@ -40,11 +42,14 @@ if (! is_object($weblangs)) if (! $pageid && ! empty($websitepagefile)) { $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile)); + if ($pageid == 'index.php') $pageid = $website->fk_default_home; +} +if (! is_object($websitepage)) +{ + $websitepage=new WebsitePage($db); } if ($pageid > 0) { - include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; - $websitepage=new WebsitePage($db); $websitepage->fetch($pageid); } diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index b2d45e11a6f..9cf79ba3f18 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -442,7 +442,7 @@ if (empty($reshook)) if ($result < 0) { $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); + setEventMessages($langs->trans($object->error), $object->errors, 'errors'); } else { diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index e68eecbca81..3e9175c95e3 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -757,7 +757,7 @@ class Expedition extends CommonObject $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref)); if ($result < 0) { $error++; - $this->errors[]=$mouvS->error; + $this->error = $mouvS->error; $this->errors = array_merge($this->errors, $mouvS->errors); break; } @@ -771,7 +771,7 @@ class Expedition extends CommonObject $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); if ($result < 0) { $error++; - $this->errors[]=$mouvS->error; + $this->error = $mouvS->error; $this->errors = array_merge($this->errors, $mouvS->errors); break; } @@ -851,11 +851,6 @@ class Expedition extends CommonObject } else { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::valid ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } $this->db->rollback(); return -1*$error; } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 67acd23b633..a9c8df670b5 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2388,14 +2388,11 @@ elseif (! empty($object->id)) } // Create bill - if (! empty($conf->facture->enabled)) + if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->statut != 7 && $object->billed != 1)) // statut 2 means approved, 7 means canceled { - if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->statut != 7 && $object->billed != 1)) // statut 2 means approved, 7 means canceled + if ($user->rights->fournisseur->facture->creer) { - if ($user->rights->fournisseur->facture->creer) - { - print ''.$langs->trans("CreateBill").''; - } + print ''.$langs->trans("CreateBill").''; } } @@ -2764,6 +2761,7 @@ elseif (! empty($object->id)) $modelmail='order_supplier_send'; $defaulttopic='SendOrderRef'; $diroutput = $conf->fournisseur->commande->dir_output; + $autocopy='MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO'; $trackid = 'sor'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index 9c32c39c2b4..b770ed5a7db 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -216,7 +216,7 @@ if (($action == 'create' || $action == 'add') && ! $error) { $fk_parent_line = 0; } // FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example. - $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->qty, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, 'HT', $product_type, -1, false, 0, $lines[$i]->fk_unit); + $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->qty, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, 'HT', $product_type, -1, false, 0, $lines[$i]->fk_unit, $line[$i]->id); if ($result > 0) { $lineid = $result; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index a7b6fe32fb1..3956684d9b2 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -3206,6 +3206,7 @@ else $modelmail='invoice_supplier_send'; $defaulttopic='SendBillRef'; $diroutput = $conf->fournisseur->facture->dir_output; + $autocopy='MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO'; $trackid = 'sin'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; diff --git a/htdocs/index.php b/htdocs/index.php index 1ef48ea9bae..81503139d88 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -432,9 +432,9 @@ if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire) { include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $board=new Contrat($db); - $dashboardlines[] = $board->load_board($user,"inactives"); + $dashboardlines[] = $board->load_board($user, "inactive"); // Number of active services (expired) - $dashboardlines[] = $board->load_board($user,"expired"); + $dashboardlines[] = $board->load_board($user, "active"); } // Number of invoices customers (has paid) if (! empty($conf->facture->enabled) && $user->rights->facture->lire) @@ -553,7 +553,7 @@ $nbworkboardempty=0; if (! empty($valid_dashboardlines)) { $boxwork.='
'; - + foreach($valid_dashboardlines as $board) { if (empty($board->nbtodo)) $nbworkboardempty++; @@ -593,7 +593,7 @@ if (! empty($valid_dashboardlines)) $boxwork .='
'; $boxwork .='
'; $boxwork .='
'; - + $boxwork .='
'; $boxwork .=''; } 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 index cee3a17e061..380c64c28fc 100644 --- a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -560,3 +560,5 @@ UPDATE llx_advtargetemailing SET fk_element = fk_mailing, type_element='mailing' ALTER TABLE llx_advtargetemailing DROP COLUMN fk_mailing; DROP TABLE llx_ticket_logs; + +ALTER TABLE llx_actioncomm MODIFY COLUMN code varchar(50); diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql index 2d45d94aafd..8bc8d691bbd 100644 --- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql @@ -52,6 +52,9 @@ ALTER TABLE llx_actioncomm ADD COLUMN email_subject varchar(255) after email_msg ALTER TABLE llx_actioncomm ADD COLUMN email_tocc varchar(255) after email_to; ALTER TABLE llx_actioncomm ADD COLUMN email_tobcc varchar(255) after email_tocc; +ALTER TABLE llx_actioncomm MODIFY COLUMN code varchar(50); + + -- For 9.0 ALTER TABLE llx_extrafields ADD COLUMN help text NULL; ALTER TABLE llx_extrafields ADD COLUMN totalizable boolean DEFAULT FALSE after list; diff --git a/htdocs/install/mysql/tables/llx_actioncomm.sql b/htdocs/install/mysql/tables/llx_actioncomm.sql index 8aa7fe47f3e..5a41b5a4c15 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.sql @@ -29,7 +29,7 @@ create table llx_actioncomm datep2 datetime, -- date end fk_action integer, -- type of action (optional link with id in llx_c_actioncomm or null) - code varchar(32) NULL, -- code of action for automatic action ('AC_OTH_AUTO' for automatic actions, 'AC_EMAILIN_AUTO' for email input, 'AC_xxx' for manual action...) + code varchar(50) NULL, -- code of action for automatic action ('AC_OTH_AUTO' for automatic actions, 'AC_EMAILIN_AUTO' for email input, 'AC_xxx' for manual action...) datec datetime, -- date creation tms timestamp, -- date modification diff --git a/htdocs/install/mysql/tables/llx_payment_salary.sql b/htdocs/install/mysql/tables/llx_payment_salary.sql index c56e6459aa0..0c19ee93915 100644 --- a/htdocs/install/mysql/tables/llx_payment_salary.sql +++ b/htdocs/install/mysql/tables/llx_payment_salary.sql @@ -19,7 +19,7 @@ create table llx_payment_salary ( rowid integer AUTO_INCREMENT PRIMARY KEY, - ref varchar(30) NOT NULL, -- payment reference number + ref varchar(30) NULL, -- payment reference number (currently NULL because there is no numbering manager yet) tms timestamp, datec datetime, -- Create date fk_user integer NOT NULL, diff --git a/htdocs/install/mysql/tables/llx_payment_various.sql b/htdocs/install/mysql/tables/llx_payment_various.sql index d3351287e58..023d6d018a7 100644 --- a/htdocs/install/mysql/tables/llx_payment_various.sql +++ b/htdocs/install/mysql/tables/llx_payment_various.sql @@ -19,7 +19,7 @@ create table llx_payment_various ( rowid integer AUTO_INCREMENT PRIMARY KEY, - ref varchar(30) NOT NULL, -- payment reference number + ref varchar(30) NULL, -- payment reference number (currently NULL because there is no numbering manager yet) num_payment varchar(50), -- num cheque or other label varchar(255), tms timestamp, diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 31f3d5e264a..c7e9baa04ac 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -161,6 +161,7 @@ LabelAccount=Label account LabelOperation=Label operation Sens=Sens LetteringCode=Lettering code +Lettering=Lettering Codejournal=Journal NumPiece=Piece number TransactionNumShort=Num. transaction diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 7083ed1114e..256cdc46105 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1817,7 +1817,7 @@ ChartLoaded=Chart of account loaded SocialNetworkSetup=Setup of module Social Networks EnableFeatureFor=Enable features for %s VATIsUsedIsOff=Note: The option to use sales Tax or VAT has been set to Off in the menu %s - %s, so Sale tax or Vat used will always be 0 for sales. -SwapSenderAndRecipientOnPDF=Swap sender and recipient address on PDF +SwapSenderAndRecipientOnPDF=Swap sender and recipient address position on PDF documents FeatureSupportedOnTextFieldsOnly=Warning, feature supported on text fields only. Also an URL parameter action=create or action=edit must be set OR page name must end with 'new.php' to trigger this feature. EmailCollector=Email collector EmailCollectorDescription=Add a scheduled job and a setup page to scan regularly email boxes (using IMAP protocol) and record emails received into your application, at the right place and/or create some record automatically (like leads). diff --git a/htdocs/langs/en_US/contracts.lang b/htdocs/langs/en_US/contracts.lang index b4e8d7c96d9..efe6cae4667 100644 --- a/htdocs/langs/en_US/contracts.lang +++ b/htdocs/langs/en_US/contracts.lang @@ -64,7 +64,8 @@ DateStartRealShort=Real start date DateEndReal=Real end date DateEndRealShort=Real end date CloseService=Close service -BoardRunningServices=Expired running services +BoardRunningServices=Services running +BoardExpiredServices=Services expired ServiceStatus=Status of service DraftContracts=Drafts contracts CloseRefusedBecauseOneServiceActive=Contract can't be closed as there is at least one open service on it diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 80955c0a74e..8a96e062203 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -337,4 +337,5 @@ CloneDestinationReference=Destination product reference ErrorCopyProductCombinations=There was an error while copying the product variants ErrorDestinationProductNotFound=Destination product not found ErrorProductCombinationNotFound=Product variant not found -ActionAvailableOnVariantProductOnly=Action only available on the variant of product \ No newline at end of file +ActionAvailableOnVariantProductOnly=Action only available on the variant of product +ProductsPricePerCustomer=Product prices per customers \ No newline at end of file diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 99f0133f175..4de381b0658 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -95,4 +95,5 @@ InternalURLOfPage=Internal URL of page ThisPageIsTranslationOf=This page/container is translation of ThisPageHasTranslationPages=This page/container has translation NoWebSiteCreateOneFirst=No website created yet. Create on first. -GoTo=Go to \ No newline at end of file +GoTo=Go to +DynamicPHPCodeContainsAForbiddenInstruction=You add dynamic PHP code that contains the PHP instruction '%s' that is forbidden by default as dynamic content (see hidden options WEBSITE_PHP_ALLOW_xxx to increase list of allowed commands). diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index c36882a2ad1..f17cbaed86c 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -456,7 +456,7 @@ Duration=Durée TotalDuration=Durée totale Summary=Résumé DolibarrStateBoard=Statistiques de la base -DolibarrWorkBoard=Éléments en attente +DolibarrWorkBoard=Tableau de bord des éléments ouverts NoOpenedElementToProcess=Aucun élément ouvert à traiter Available=Disponible NotYetAvailable=Pas encore disponible diff --git a/htdocs/product/stock/tpl/stockcorrection.tpl.php b/htdocs/product/stock/tpl/stockcorrection.tpl.php index 849bc15fc6b..afe66818a72 100644 --- a/htdocs/product/stock/tpl/stockcorrection.tpl.php +++ b/htdocs/product/stock/tpl/stockcorrection.tpl.php @@ -100,7 +100,7 @@ if (empty($conf) || ! is_object($conf)) { { print ''.$langs->trans('Project').''; print ''; - $formproject->select_projects(0, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); + $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); print ''; } print ''; diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 56646a1a470..e7cefc9b576 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -450,7 +450,7 @@ if (empty($reshook)) // Actions to send emails $trigger_name='PROJECT_SENTBYMAIL'; $paramname='id'; - $autocopy='MAIN_MAIL_AUTOCOPY_ORDER_TO'; // used to know the automatic BCC to add + $autocopy='MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add $trackid='proj'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; } @@ -1286,6 +1286,7 @@ elseif ($object->id > 0) $modelmail='project'; $defaulttopic='SendProjectRef'; $diroutput = $conf->projet->dir_output; + $autocopy='MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add $trackid = 'proj'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 23ee7fd8e2d..c2ea95d14ca 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -474,7 +474,7 @@ $listofreferent=array( 'lang'=>'banks', 'buttonnew'=>'AddVariousPayment', 'testnew'=>$user->rights->banque->modifier, - 'test'=>$conf->banque->enabled && $user->rights->banque->lire), + 'test'=>$conf->banque->enabled && $user->rights->banque->lire && empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)), /* No need for this, available on dedicated tab "Agenda/Events" 'agenda'=>array( 'name'=>"Agenda", diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ca074c87070..32159e7e639 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -59,7 +59,7 @@ class Societe extends CommonObject public $fieldsforcombobox='nom,name_alias'; protected $childtables=array("supplier_proposal"=>'SupplierProposal',"propal"=>'Proposal',"commande"=>'Order',"facture"=>'Invoice',"facture_rec"=>'RecurringInvoiceTemplate',"contrat"=>'Contract',"fichinter"=>'Fichinter',"facture_fourn"=>'SupplierInvoice',"commande_fournisseur"=>'SupplierOrder',"projet"=>'Project',"expedition"=>'Shipment',"prelevement_lignes"=>'DirectDebitRecord'); // To test if we can delete object - protected $childtablesoncascade=array("societe_prices", "societe_log", "societe_address", "product_fournisseur_price", "product_customer_price_log", "product_customer_price", "socpeople", "adherent", "societe_rib", "societe_remise", "societe_remise_except", "societe_commerciaux", "categorie", "notify", "notify_def", "actioncomm"); + protected $childtablesoncascade=array("societe_prices", "societe_log", "societe_address", "product_fournisseur_price", "product_customer_price_log", "product_customer_price", "socpeople", "adherent", "societe_account", "societe_rib", "societe_remise", "societe_remise_except", "societe_commerciaux", "categorie", "notify", "notify_def", "actioncomm"); public $picto = 'company'; /** diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index 3a3fb8507c9..ed8b3e41d4b 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -22,7 +22,7 @@ /** * \file htdocs/societe/consumption.php * \ingroup societe - * \brief Add a tab on thirpdarty view to list all products/services bought or sells by thirdparty + * \brief Add a tab on thirdparty view to list all products/services bought or sells by thirdparty */ require "../main.inc.php"; diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index d8e7168e5c0..97bf463bd97 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -452,7 +452,7 @@ class Stripe extends CommonObject $paymentarray["receipt_email"] = $societe->email; } - $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$ref")); + $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description")); } } else { @@ -480,7 +480,7 @@ class Stripe extends CommonObject $paymentarray["receipt_email"] = $societe->email; } - $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$ref","stripe_account" => "$account")); + $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description", "stripe_account" => "$account")); } if (isset($charge->id)) {} diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 85297634ec3..0d9f36602ea 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1877,6 +1877,7 @@ if ($action == 'create') $modelmail='supplier_proposal_send'; $defaulttopic='SendAskRef'; $diroutput = $conf->supplier_proposal->dir_output; + $autocopy='MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO'; $trackid = 'spr'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index c1ef12c1b2d..2775bae8470 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3196,6 +3196,10 @@ table.tableforservicepart1:first-of-type tr:first-of-type td { table.tableforservicepart1 tr td { border-top: 0px; } +// Payment Screen : Pointer cursor in the autofill image +table.noborder .AutoFillAmout { + cursor:pointer; +} .paymenttable, .margintable { /*border-top-width: px !important; @@ -3212,6 +3216,8 @@ table.tableforservicepart1 tr td { height: 22px; } + + /* Disable shadows */ .noshadow { -webkit-box-shadow: 0px 0px 0px #DDD !important; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index a02b4916c91..1bfaa24c066 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -3206,15 +3206,38 @@ class User extends CommonObject * @param int $offset page * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) * @param string $filtermode Filter mode (AND or OR) + * @param bool $entityfilter Activate entity filter * @return int <0 if KO, >0 if OK */ - function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter=array(), $filtermode='AND') + function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter=array(), $filtermode='AND', $entityfilter=false) { - global $conf; + global $conf, $user; $sql="SELECT t.rowid"; $sql.= ' FROM '.MAIN_DB_PREFIX .$this->table_element.' as t '; - $sql.= " WHERE 1"; + + if ($entityfilter) + { + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1) { + $sql.= " WHERE t.entity IS NOT NULL"; // Show all users + } else { + $sql.= ",".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql.= " WHERE ((ug.fk_user = t.rowid"; + $sql.= " AND ug.entity IN (".getEntity('user')."))"; + $sql.= " OR t.entity = 0)"; // Show always superadmin + } + } + else + { + $sql.= " WHERE t.entity IN (".getEntity('user').")"; + } + } + else + { + $sql.= " WHERE 1"; + } // Manage filter $sqlwhere = array(); diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 2385a558307..073aaa9fb24 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -169,6 +169,9 @@ $type = 'application/octet-stream'; if (GETPOST('type','alpha')) $type=GETPOST('type','alpha'); else $type=dol_mimetype($original_file); +// Security: This wrapper is for images. We do not allow type/html +if (preg_match('/html/', $type)) accessforbidden('Error: Using the image wrapper to output a file with a mime type HTML is not possible.', 1, 1, 1); + // Security: Delete string ../ into $original_file $original_file = str_replace("../","/", $original_file); @@ -176,7 +179,7 @@ $original_file = str_replace("../","/", $original_file); $refname=basename(dirname($original_file)."/"); // Security check -if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); +if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart', 1, 1, 1); $check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, $refname); $accessallowed = $check_access['accessallowed']; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 1ec9c2c65c4..c3d1378b1c1 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -1453,6 +1453,26 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf $objectpage->content = GETPOST('PAGE_CONTENT','none'); + // Security analysis + $phpfullcodestring = dolKeepOnlyPhpCode($objectpage->content); + //print dol_escape_htmltag($phpfullcodestring);exit; + $forbiddenphpcommands=array("exec", "passthru", "system", "shell_exec", "proc_open"); + if (empty($conf->global->WEBSITE_PHP_ALLOW_WRITE)) // If option is not on, we disallow functions to write files + { + $forbiddenphpcommands=array_merge($forbiddenphpcommands, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "unlink", "mkdir", "rmdir", "symlink", "touch", "umask")); + } + foreach($forbiddenphpcommands as $forbiddenphpcommand) + { + if (preg_match('/'.$forbiddenphpcommand.'\s*\(/ms', $phpfullcodestring)) + { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpcommand), null, 'errors'); + if ($action == 'updatesource') $action = 'editsource'; + if ($action == 'updatecontent') $action = 'editcontent'; + } + } + + // Clean data. We remove all the head section. $objectpage->content = preg_replace('/.*<\/head>/ims', '', $objectpage->content); /* $objectpage->content = preg_replace('//s', '', $objectpage->content); */ @@ -1463,6 +1483,8 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf { $error++; setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + if ($action == 'updatesource') $action = 'editsource'; + if ($action == 'updatecontent') $action = 'editcontent'; } if (! $error) @@ -1853,7 +1875,7 @@ if (! GETPOST('hide_websitemenu')) } if (! empty($conf->global->WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER)) { - $htmltext.= '
'.$conf->global->WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER; + $htmltext.= '
'.$langs->trans($conf->global->WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER); } else {