';
print '';
print $langs->trans('Docdate');
@@ -429,11 +434,12 @@ if ($action == 'create') {
print ' ';
print '';
} else {
- print $book->doc_date ? dol_print_date($book->doc_date, 'daytext') : ' ';
+ print $book->doc_date ? dol_print_date($book->doc_date, 'daytext') : ' ';
}
print ' ';
print ' ';
- //journal
+
+ // Journal
print '';
print '';
print $langs->trans('Codejournal');
@@ -455,7 +461,8 @@ if ($action == 'create') {
}
print ' ';
print ' ';
- //docref
+
+ // Ref document
print '';
print '';
print $langs->trans('Docref');
@@ -488,9 +495,20 @@ if ($action == 'create') {
print '';
// Doc type
+ if(! empty($book->doc_type))
+ {
+ print '';
+ print '' . $langs->trans("Doctype") . ' ';
+ print '' . $book->doc_type . ' ';
+ print ' ';
+ }
+
+ // Date document creation
print '';
- print '' . $langs->trans("Doctype") . ' ';
- print '' . $book->doc_type . ' ';
+ print '' . $langs->trans("DateCreation") . ' ';
+ print '';
+ print $book->date_creation ? dol_print_date($book->date_creation, 'daytext') : ' ';
+ print ' ';
print ' ';
// Validate
@@ -542,7 +560,6 @@ if ($action == 'create') {
print ' ';
-
$result = $book->fetchAllPerMvt($piece_num, $mode);
if ($result < 0) {
setEventMessages($book->error, $book->errors, 'errors');
@@ -570,7 +587,7 @@ if ($action == 'create') {
print_liste_field_titre("AccountAccountingShort");
print_liste_field_titre("SubledgerAccount");
print_liste_field_titre("LabelAccount");
- print_liste_field_titre("Label");
+ print_liste_field_titre("LabelOperation");
print_liste_field_titre("Debit", "", "", "", "", 'align="right"');
print_liste_field_titre("Credit", "", "", "", "", 'align="right"');
print_liste_field_titre("Action", "", "", "", "", 'width="60" align="center"');
@@ -587,16 +604,16 @@ if ($action == 'create') {
print $formaccounting->select_account($line->numero_compte, 'account_number', 1, array (), 1, 1, '');
print '';
print '';
- // TODO For the moment we keep a fre input text instead of a combo. The select_auxaccount has problem because it does not
- // use setup of keypress to select thirdparty and this hang browser on large database.
- if (! empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX))
- {
- print $formaccounting->select_auxaccount($line->subledger_account, 'subledger_account', 1);
- }
- else
- {
- print ' ';
- }
+ // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because it does not
+ // use setup of keypress to select thirdparty and this hang browser on large database.
+ if (! empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX))
+ {
+ print $formaccounting->select_auxaccount($line->subledger_account, 'subledger_account', 1);
+ }
+ else
+ {
+ print ' ';
+ }
print ' ';
print ' ';
print ' ';
@@ -644,14 +661,14 @@ if ($action == 'create') {
print '';
// TODO For the moment we keep a fre input text instead of a combo. The select_auxaccount has problem because it does not
// use setup of keypress to select thirdparty and this hang browser on large database.
- if (! empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX))
- {
- print $formaccounting->select_auxaccount($subledger_account, 'subledger_account', 1);
- }
- else
- {
- print ' ';
- }
+ if (! empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX))
+ {
+ print $formaccounting->select_auxaccount($subledger_account, 'subledger_account', 1);
+ }
+ else
+ {
+ print ' ';
+ }
print ' ';
print ' ';
print ' ';
@@ -665,15 +682,15 @@ if ($action == 'create') {
if ($mode=='_tmp' && $action=='')
{
- print ' ';
+ print ' ';
print '';
if ($total_debit == $total_credit)
{
- print '
piece_num . '&action=valid">'.$langs->trans("ValidTransaction").' ';
+ print '
piece_num . '&action=valid">'.$langs->trans("ValidTransaction").' ';
}
else
{
- print '
';
+ print '
';
}
print ' ';
diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php
index ac92dcab195..b09336aff48 100644
--- a/htdocs/accountancy/class/accountancyexport.class.php
+++ b/htdocs/accountancy/class/accountancyexport.class.php
@@ -6,6 +6,7 @@
* Copyright (C) 2015 Raphaël Doursenaud
* Copyright (C) 2016 Pierre-Henry Favre
* Copyright (C) 2016-2017 Alexandre Spangaro
+ * Copyright (C) 2017 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
@@ -49,7 +50,8 @@ class AccountancyExport
public static $EXPORT_TYPE_EBP = 7;
public static $EXPORT_TYPE_COGILOG = 8;
public static $EXPORT_TYPE_AGIRIS = 9;
-
+ public static $EXPORT_TYPE_CONFIGURABLE = 10;
+
/**
*
* @var string[] Error codes (or messages)
@@ -78,11 +80,11 @@ class AccountancyExport
$this->db = &$db;
$this->separator = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
- $this->end_line = "\n";
+ $this->end_line = empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?"\n":($conf->global->ACCOUNTING_EXPORT_ENDLINE==1?"\n":"\r\n");
}
/**
- * Array wit all export type available (key + label)
+ * Array with all export type available (key + label)
*
* @return array of type
*/
@@ -98,10 +100,73 @@ class AccountancyExport
self::$EXPORT_TYPE_QUADRATUS => $langs->trans('Modelcsv_quadratus'),
self::$EXPORT_TYPE_EBP => $langs->trans('Modelcsv_ebp'),
self::$EXPORT_TYPE_COGILOG => $langs->trans('Modelcsv_cogilog'),
- self::$EXPORT_TYPE_AGIRIS => $langs->trans('Modelcsv_agiris')
- );
+ self::$EXPORT_TYPE_AGIRIS => $langs->trans('Modelcsv_agiris'),
+ self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'),
+ );
}
+ /**
+ * Array with all export type available (key + label) and parameters for config
+ *
+ * @return array of type
+ */
+ public static function getTypeConfig() {
+ global $conf, $langs;
+
+ return array (
+ 'param' => array(
+ self::$EXPORT_TYPE_NORMAL => array(
+ 'label' => $langs->trans('Modelcsv_normal'),
+ 'ACCOUNTING_EXPORT_FORMAT' => empty($conf->global->ACCOUNTING_EXPORT_FORMAT)?'txt':$conf->global->ACCOUNTING_EXPORT_FORMAT,
+ 'ACCOUNTING_EXPORT_SEPARATORCSV' => empty($conf->global->ACCOUNTING_EXPORT_SEPARATORCSV)?',':$conf->global->ACCOUNTING_EXPORT_SEPARATORCSV,
+ 'ACCOUNTING_EXPORT_ENDLINE' => empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?1:$conf->global->ACCOUNTING_EXPORT_ENDLINE,
+ 'ACCOUNTING_EXPORT_DATE' => empty($conf->global->ACCOUNTING_EXPORT_DATE)?'%d%m%Y':$conf->global->ACCOUNTING_EXPORT_DATE,
+ ),
+ self::$EXPORT_TYPE_CEGID => array(
+ 'label' => $langs->trans('Modelcsv_CEGID'),
+ ),
+ self::$EXPORT_TYPE_COALA => array(
+ 'label' => $langs->trans('Modelcsv_COALA'),
+ ),
+ self::$EXPORT_TYPE_BOB50 => array(
+ 'label' => $langs->trans('Modelcsv_bob50'),
+ ),
+ self::$EXPORT_TYPE_CIEL => array(
+ 'label' => $langs->trans('Modelcsv_ciel'),
+ 'ACCOUNTING_EXPORT_FORMAT' => 'txt',
+ ),
+ self::$EXPORT_TYPE_QUADRATUS => array(
+ 'label' => $langs->trans('Modelcsv_quadratus'),
+ 'ACCOUNTING_EXPORT_FORMAT' => 'txt',
+ ),
+ self::$EXPORT_TYPE_EBP => array(
+ 'label' => $langs->trans('Modelcsv_ebp'),
+ ),
+ self::$EXPORT_TYPE_COGILOG => array(
+ 'label' => $langs->trans('Modelcsv_cogilog'),
+ ),
+ self::$EXPORT_TYPE_AGIRIS => array(
+ 'label' => $langs->trans('Modelcsv_agiris'),
+ ),
+ self::$EXPORT_TYPE_CONFIGURABLE => array(
+ 'label' => $langs->trans('Modelcsv_configurable'),
+ 'ACCOUNTING_EXPORT_FORMAT' => empty($conf->global->ACCOUNTING_EXPORT_FORMAT)?'txt':$conf->global->ACCOUNTING_EXPORT_FORMAT,
+ 'ACCOUNTING_EXPORT_SEPARATORCSV' => empty($conf->global->ACCOUNTING_EXPORT_SEPARATORCSV)?',':$conf->global->ACCOUNTING_EXPORT_SEPARATORCSV,
+ 'ACCOUNTING_EXPORT_ENDLINE' => empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?1:$conf->global->ACCOUNTING_EXPORT_ENDLINE,
+ 'ACCOUNTING_EXPORT_DATE' => empty($conf->global->ACCOUNTING_EXPORT_DATE)?'%d%m%Y':$conf->global->ACCOUNTING_EXPORT_DATE,
+ ),
+ ),
+ 'cr'=> array (
+ '1' => $langs->trans("Unix"),
+ '2' => $langs->trans("Windows")
+ ),
+ 'format' => array (
+ 'csv' => $langs->trans("csv"),
+ 'txt' => $langs->trans("txt")
+ ),
+ );
+ }
+
/**
* Download the export
*
@@ -151,6 +216,9 @@ class AccountancyExport
case self::$EXPORT_TYPE_AGIRIS :
$this->exportAgiris($TData);
break;
+ case self::$EXPORT_TYPE_CONFIGURABLE :
+ $this->exportConfigurable($TData);
+ break;
default:
$this->errors[] = $langs->trans('accountancy_error_modelnotfound');
break;
@@ -191,7 +259,8 @@ class AccountancyExport
public function exportCegid($objectLines) {
foreach ( $objectLines as $line ) {
$date = dol_print_date($line->doc_date, '%d%m%Y');
- $separator = ";";
+ $separator = ";";
+ $end_line = "\n";
print $date . $separator;
print $line->code_journal . $separator;
@@ -201,7 +270,7 @@ class AccountancyExport
print price($line->montant) . $separator;
print $line->label_operation . $separator;
print $line->doc_ref;
- print $this->end_line;
+ print $end_line;
}
}
@@ -215,24 +284,26 @@ class AccountancyExport
public function exportCogilog($objectLines) {
foreach ( $objectLines as $line ) {
$date = dol_print_date($line->doc_date, '%d%m%Y');
+ $separator = ";";
+ $end_line = "\n";
- print $line->code_journal . $this->separator;
- print $date . $this->separator;
- print $line->piece_num . $this->separator;
- print length_accountg($line->numero_compte) . $this->separator;
- print '' . $this->separator;
- print $line->label_operation . $this->separator;
- print $date . $this->separator;
+ print $line->code_journal . $separator;
+ print $date . $separator;
+ print $line->piece_num . $separator;
+ print length_accountg($line->numero_compte) . $separator;
+ print '' . $separator;
+ print $line->label_operation . $separator;
+ print $date . $separator;
if ($line->sens=='D') {
- print price($line->montant) . $this->separator;
- print '' . $this->separator;
+ print price($line->montant) . $separator;
+ print '' . $separator;
}elseif ($line->sens=='C') {
- print '' . $this->separator;
- print price($line->montant) . $this->separator;
+ print '' . $separator;
+ print price($line->montant) . $separator;
}
- print $line->doc_ref . $this->separator;
- print $line->label_operation . $this->separator;
- print $this->end_line;
+ print $line->doc_ref . $separator;
+ print $line->label_operation . $separator;
+ print $end_line;
}
}
@@ -245,18 +316,21 @@ class AccountancyExport
*/
public function exportCoala($objectLines) {
// Coala export
+ $separator = ";";
+ $end_line = "\n";
+
foreach ( $objectLines as $line ) {
$date = dol_print_date($line->doc_date, '%d/%m/%Y');
- print $date . $this->separator;
- print $line->code_journal . $this->separator;
- print length_accountg($line->numero_compte) . $this->separator;
- print $line->piece_num . $this->separator;
- print $line->doc_ref . $this->separator;
- print price($line->debit) . $this->separator;
- print price($line->credit) . $this->separator;
- print 'E' . $this->separator;
- print length_accountg($line->subledger_account) . $this->separator;
- print $this->end_line;
+ print $date . $separator;
+ print $line->code_journal . $separator;
+ print length_accountg($line->numero_compte) . $separator;
+ print $line->piece_num . $separator;
+ print $line->doc_ref . $separator;
+ print price($line->debit) . $separator;
+ print price($line->credit) . $separator;
+ print 'E' . $separator;
+ print length_accountg($line->subledger_account) . $separator;
+ print $end_line;
}
}
@@ -270,28 +344,31 @@ class AccountancyExport
public function exportBob50($objectLines) {
// Bob50
+ $separator = ";";
+ $end_line = "\n";
+
foreach ( $objectLines as $line ) {
- print $line->piece_num . $this->separator;
+ print $line->piece_num . $separator;
$date = dol_print_date($line->doc_date, '%d/%m/%Y');
- print $date . $this->separator;
+ print $date . $separator;
if (empty($line->subledger_account)) {
- print 'G' . $this->separator;
- print length_accounta($line->numero_compte) . $this->separator;
+ print 'G' . $separator;
+ print length_accounta($line->numero_compte) . $separator;
} else {
if (substr($line->numero_compte, 0, 3) == '411') {
- print 'C' . $this->separator;
+ print 'C' . $separator;
}
if (substr($line->numero_compte, 0, 3) == '401') {
- print 'F' . $this->separator;
+ print 'F' . $separator;
}
- print length_accountg($line->subledger_account) . $this->separator;
+ print length_accountg($line->subledger_account) . $separator;
}
- print price($line->debit) . $this->separator;
- print price($line->credit) . $this->separator;
- print dol_trunc($line->label_operation, 32) . $this->separator;
- print $this->end_line;
+ print price($line->debit) . $separator;
+ print price($line->credit) . $separator;
+ print dol_trunc($line->label_operation, 32) . $separator;
+ print $end_line;
}
}
@@ -305,7 +382,7 @@ class AccountancyExport
public function exportCiel(&$TData) {
global $conf;
- $this->end_line ="\r\n";
+ $end_line ="\r\n";
$i = 1;
$date_ecriture = dol_print_date(dol_now(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be yyyymmdd
@@ -328,7 +405,7 @@ class AccountancyExport
$Tab['intitule_compte'] = str_pad(self::trunc($data->label_operation, 34), 34);
$Tab['end'] = 'O2003';
- $Tab['end_line'] = $this->end_line;
+ $Tab['end_line'] = $end_line;
print implode($Tab);
$i ++;
@@ -345,7 +422,7 @@ class AccountancyExport
public function exportQuadratus(&$TData) {
global $conf;
- $this->end_line ="\r\n";
+ $end_line ="\r\n";
$date_ecriture = dol_print_date(time(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be ddmmyy
foreach ( $TData as $data ) {
@@ -380,7 +457,7 @@ class AccountancyExport
$Tab['num_piece3'] = str_pad(self::trunc($data->piece_num, 10), 10);
$Tab['filler4'] = str_repeat(' ', 73);
- $Tab['end_line'] = $this->end_line;
+ $Tab['end_line'] = $end_line;
print implode($Tab);
}
@@ -396,24 +473,25 @@ class AccountancyExport
*/
public function exportEbp($objectLines) {
- $this->separator = ',';
+ $separator = ',';
+ $end_line = "\n";
foreach ( $objectLines as $line ) {
$date = dol_print_date($line->doc_date, '%d%m%Y');
- print $line->id . $this->separator;
- print $date . $this->separator;
- print $line->code_journal . $this->separator;
- print length_accountg($line->numero_compte) . $this->separator;
- print substr(length_accountg($line->numero_compte),0,2) . $this->separator;
- print '"'.dol_trunc($line->label_operation,40,'right','UTF-8',1).'"' . $this->separator;
- print '"'.dol_trunc($line->piece_num,15,'right','UTF-8',1).'"'.$this->separator;
- print price2num($line->montant).$this->separator;
- print $line->sens.$this->separator;
- print $date . $this->separator;
+ print $line->id . $separator;
+ print $date . $separator;
+ print $line->code_journal . $separator;
+ print length_accountg($line->numero_compte) . $separator;
+ print substr(length_accountg($line->numero_compte),0,2) . $separator;
+ print '"'.dol_trunc($line->label_operation,40,'right','UTF-8',1).'"' . $separator;
+ print '"'.dol_trunc($line->piece_num,15,'right','UTF-8',1).'"'.$separator;
+ print price2num($line->montant).$separator;
+ print $line->sens.$separator;
+ print $date . $separator;
print 'EUR';
- print $this->end_line;
+ print $end_line;
}
}
@@ -427,33 +505,64 @@ class AccountancyExport
*/
public function exportAgiris($objectLines) {
- $this->separator = ';';
+ $separator = ';';
+ $end_line = "\n";
foreach ( $objectLines as $line ) {
$date = dol_print_date($line->doc_date, '%d%m%Y');
- print $line->piece_num . $this->separator;
- print $line->label_operation . $this->separator;
- print $date . $this->separator;
- print $line->label_operation . $this->separator;
+ print $line->piece_num . $separator;
+ print $line->label_operation . $separator;
+ print $date . $separator;
+ print $line->label_operation . $separator;
if (empty($line->subledger_account)) {
- print length_accountg($line->numero_compte) . $this->separator;
+ print length_accountg($line->numero_compte) . $separator;
} else {
- print length_accounta($line->subledger_account) . $this->separator;
+ print length_accounta($line->subledger_account) . $separator;
}
- print $line->doc_ref . $this->separator;
- print price($line->debit) . $this->separator;
- print price($line->credit) . $this->separator;
- print price($line->montant).$this->separator;
- print $line->sens.$this->separator;
+ print $line->doc_ref . $separator;
+ print price($line->debit) . $separator;
+ print price($line->credit) . $separator;
+ print price($line->montant) . $separator;
+ print $line->sens . $separator;
print $line->code_journal;
- print $this->end_line;
+ print $end_line;
}
}
+ /**
+ * Export format : Configurable
+ *
+ * @param array $objectLines data
+ *
+ * @return void
+ */
+ public function exportConfigurable($objectLines) {
+ global $conf;
+
+ foreach ($objectLines as $line) {
+ $tab = array();
+ // export configurable
+ $date = dol_print_date($line->doc_date, $conf->global->ACCOUNTING_EXPORT_DATE);
+ $tab[] = $date;
+ $tab[] = $line->doc_ref;
+ $tab[] = $line->piece_num;
+ $tab[] = $line->label_operation;
+ $tab[] = length_accountg($line->numero_compte);
+ $tab[] = length_accounta($line->subledger_account);
+ $tab[] = price($line->debit);
+ $tab[] = price($line->credit);
+ $tab[] = price($line->montant);
+ $tab[] = $line->code_journal;
+
+ $separator = $this->separator;
+ print implode($separator, $tab) . $this->end_line;
+ }
+ }
+
/**
*
diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php
index 2d26a2d06d8..d20a008d4fd 100644
--- a/htdocs/accountancy/customer/list.php
+++ b/htdocs/accountancy/customer/list.php
@@ -91,6 +91,9 @@ if ($user->societe_id > 0)
if (! $user->rights->accounting->bind->write)
accessforbidden();
+// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
+$hookmanager->initHooks(array('accountancycustomerlist'));
+
$formaccounting = new FormAccounting($db);
$accounting = new AccountingAccount($db);
$aarowid_s = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1);
@@ -104,29 +107,36 @@ $aarowid_p = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOU
if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; }
if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
-// Purge search criteria
-if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers
+$parameters=array();
+$reshook=$hookmanager->executeHooks('doActions',$parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+
+if (empty($reshook))
{
- $search_lineid = '';
- $search_ref = '';
- $search_invoice = '';
- $search_label = '';
- $search_desc = '';
- $search_amount = '';
- $search_account = '';
- $search_vat = '';
- $search_day = '';
- $search_month = '';
- $search_year = '';
+ // Purge search criteria
+ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers
+ {
+ $search_lineid = '';
+ $search_ref = '';
+ $search_invoice = '';
+ $search_label = '';
+ $search_desc = '';
+ $search_amount = '';
+ $search_account = '';
+ $search_vat = '';
+ $search_day = '';
+ $search_month = '';
+ $search_year = '';
+ }
+
+ // Mass actions
+ $objectclass='AccountingAccount';
+ $permtoread = $user->rights->accounting->read;
+ $permtodelete = $user->rights->accounting->delete;
+ $uploaddir = $conf->accounting->dir_output;
+ include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
-// Mass actions
-$objectclass='Skeleton';
-$objectlabel='Skeleton';
-$permtoread = $user->rights->accounting->read;
-$permtodelete = $user->rights->accounting->delete;
-$uploaddir = $conf->accounting->dir_output;
-include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
if ($massaction == 'ventil') {
$msg='';
@@ -192,6 +202,9 @@ $sql = "SELECT f.facnumber, f.rowid as facid, f.datef, f.type as ftype,";
$sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
$sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_sell as code_sell, p.tva_tx as tva_tx_prod,";
$sql .= " aa.rowid as aarowid";
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
$sql .= " FROM " . MAIN_DB_PREFIX . "facture as f";
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "facturedet as l ON f.rowid = l.fk_facture";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = l.fk_product";
@@ -246,6 +259,11 @@ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
}
$sql .= " AND f.entity IN (" . getEntity('facture', 0) . ")"; // We don't share object for accountancy
+// Add where from hooks
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
+
$sql .= $db->order($sortfield, $sortorder);
// Count total nb of records
diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
index 86026f69f09..270a6b1ab09 100644
--- a/htdocs/accountancy/index.php
+++ b/htdocs/accountancy/index.php
@@ -66,7 +66,7 @@ $step = 0;
print $langs->trans("AccountancyAreaDescIntro")." \n";
print " \n";print " \n";
-print_fiche_titre($langs->trans("AccountancyAreaDescActionOnce"), '', 'object_calendar')." \n";
+print_fiche_titre(' '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')." \n";
print ' ';
print " \n";
@@ -142,7 +142,7 @@ print ' ';
print " \n";
-print_fiche_titre($langs->trans("AccountancyAreaDescActionFreq"), '', 'object_calendarweek');
+print_fiche_titre(' '.$langs->trans("AccountancyAreaDescActionFreq"), '', '');
print ' ';
print " \n";
$step = 0;
diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php
index f154d0b77d0..1750b90acd7 100644
--- a/htdocs/accountancy/supplier/list.php
+++ b/htdocs/accountancy/supplier/list.php
@@ -91,6 +91,9 @@ if ($user->societe_id > 0)
if (! $user->rights->accounting->bind->write)
accessforbidden();
+// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
+$hookmanager->initHooks(array('accountancysupplierlist'));
+
$formaccounting = new FormAccounting($db);
$accounting = new AccountingAccount($db);
// TODO: we should need to check if result is a really exist accountaccount rowid.....
@@ -105,29 +108,35 @@ $aarowid_p = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUN
if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; }
if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
-// Purge search criteria
-if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers
-{
- $search_lineid = '';
- $search_ref = '';
- $search_invoice = '';
- $search_label = '';
- $search_desc = '';
- $search_amount = '';
- $search_account = '';
- $search_vat = '';
- $search_day = '';
- $search_month = '';
- $search_year = '';
-}
+$parameters=array();
+$reshook=$hookmanager->executeHooks('doActions',$parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-// Mass actions
-$objectclass='Skeleton';
-$objectlabel='Skeleton';
-$permtoread = $user->rights->accounting->read;
-$permtodelete = $user->rights->accounting->delete;
-$uploaddir = $conf->accounting->dir_output;
-include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
+if (empty($reshook))
+{
+ // Purge search criteria
+ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers
+ {
+ $search_lineid = '';
+ $search_ref = '';
+ $search_invoice = '';
+ $search_label = '';
+ $search_desc = '';
+ $search_amount = '';
+ $search_account = '';
+ $search_vat = '';
+ $search_day = '';
+ $search_month = '';
+ $search_year = '';
+ }
+
+ // Mass actions
+ $objectclass='AccountingAccount';
+ $permtoread = $user->rights->accounting->read;
+ $permtodelete = $user->rights->accounting->delete;
+ $uploaddir = $conf->accounting->dir_output;
+ include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
+}
if ($massaction == 'ventil') {
$msg='';
@@ -194,6 +203,9 @@ $sql = "SELECT f.rowid as facid, f.ref, f.ref_supplier, f.libelle as invoice_lab
$sql.= " l.rowid, l.fk_product, l.description, l.total_ht as price, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
$sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_buy as code_buy, p.tva_tx as tva_tx_prod,";
$sql.= " aa.rowid as aarowid";
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
$sql.= " FROM " . MAIN_DB_PREFIX . "facture_fourn as f";
$sql.= " INNER JOIN " . MAIN_DB_PREFIX . "facture_fourn_det as l ON f.rowid = l.fk_facture_fourn";
$sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = l.fk_product";
@@ -243,6 +255,11 @@ else if ($search_year > 0)
}
$sql .= " AND f.entity IN (" . getEntity('facture_fourn', 0) . ")"; // We don't share object for accountancy
+// Add where from hooks
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
+
$sql .= $db->order($sortfield, $sortorder);
// Count total nb of records
diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php
index 6cc0ddd0c4f..59328f24fd5 100644
--- a/htdocs/adherents/document.php
+++ b/htdocs/adherents/document.php
@@ -52,7 +52,7 @@ $result=restrictedArea($user,'adherent',$id);
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
-if ($page == -1 || $page == null) { $page = 0 ; }
+if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page ;
$pageprev = $page - 1;
$pagenext = $page + 1;
diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php
index 6b4bcaa74ae..398039b228e 100644
--- a/htdocs/adherents/subscription/list.php
+++ b/htdocs/adherents/subscription/list.php
@@ -46,7 +46,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
-if ($page == -1 || $page == null) { $page = 0 ; }
+if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page ;
$pageprev = $page - 1;
$pagenext = $page + 1;
diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index 068513b245c..fb9a101d474 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -74,7 +74,7 @@ $active = 1;
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
-if ($page == -1 || $page == null) { $page = 0 ; }
+if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $listlimit * $page ;
$pageprev = $page - 1;
$pagenext = $page + 1;
diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php
index 4e25e93084b..8c1cb138bc3 100644
--- a/htdocs/admin/mails_templates.php
+++ b/htdocs/admin/mails_templates.php
@@ -70,7 +70,7 @@ $active = 1;
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
-if ($page == -1 || $page == null) { $page = 0 ; }
+if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $listlimit * $page ;
$pageprev = $page - 1;
$pagenext = $page + 1;
diff --git a/htdocs/admin/tools/listsessions.php b/htdocs/admin/tools/listsessions.php
index 6106fbe8dd8..76f7debf3e7 100644
--- a/htdocs/admin/tools/listsessions.php
+++ b/htdocs/admin/tools/listsessions.php
@@ -47,7 +47,7 @@ $langs->load("other");
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
-if ($page == -1 || $page == null) { $page = 0 ; }
+if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page ;
$pageprev = $page - 1;
$pagenext = $page + 1;
diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php
index dede8690c06..5c85cddfaee 100644
--- a/htdocs/api/class/api.class.php
+++ b/htdocs/api/class/api.class.php
@@ -96,6 +96,7 @@ class DolibarrApi
// Remove $db object property for object
unset($object->db);
+ unset($object->ismultientitymanaged);
// Remove linkedObjects. We should already have linkedObjectIds that avoid huge responses
unset($object->linkedObjects);
@@ -129,6 +130,8 @@ class DolibarrApi
unset($object->statuts_short);
unset($object->statuts_logo);
unset($object->statuts_long);
+ unset($object->labelstatut);
+ unset($object->labelstatut_short);
unset($object->element);
unset($object->fk_element);
diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php
index 92b48dfd0c6..da97215dc0c 100644
--- a/htdocs/api/class/api_documents.class.php
+++ b/htdocs/api/class/api_documents.class.php
@@ -53,8 +53,10 @@ class Documents extends DolibarrApi
/**
- * Returns a document. Note that, this API is similar to using the wrapper link "documents.php" to download
- * a file (used for internal HTML links of documents into application), but with no need to be into a logged session (no need to post the session cookie).
+ * Download a document.
+ *
+ * Note that, this API is similar to using the wrapper link "documents.php" to download a file (used for
+ * internal HTML links of documents into application), but with no need to have a session cookie (the token is used instead).
*
* @param string $module_part Name of module or area concerned by file download ('facture', ...)
* @param string $original_file Relative path with filename, relative to modulepart (for example: IN201701-999/IN201701-999.pdf)
@@ -67,6 +69,8 @@ class Documents extends DolibarrApi
* @throws 400
* @throws 401
* @throws 200
+ *
+ * @url GET /download
*/
public function index($module_part, $original_file='', $regeneratedoc=0)
{
@@ -132,7 +136,7 @@ class Documents extends DolibarrApi
/**
* Return the list of documents of a dedicated element (from its ID or Ref)
*
- * @param string $modulepart Name of module or area concerned ('facture', 'project', 'member', ...)
+ * @param string $modulepart Name of module or area concerned ('thirdparty', 'member', 'facture', 'project', ...)
* @param int $id ID of element
* @param string $ref Ref of element
* @param string $sortfield Sort criteria ('','fullname','relativename','name','date','size')
@@ -141,7 +145,7 @@ class Documents extends DolibarrApi
*
* @throws RestException
*
- * @url GET list
+ * @url GET /
*/
function getDocumentsListByElement($modulepart, $id=0, $ref='', $sortfield='', $sortorder='')
{
@@ -216,7 +220,8 @@ class Documents extends DolibarrApi
/**
- * Push a file.
+ * Upload a file.
+ *
* Test sample 1: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }.
* Test sample 2: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }.
*
@@ -229,6 +234,8 @@ class Documents extends DolibarrApi
* @param int $overwriteifexists Overwrite file if exists (1 by default)
* @return bool State of copy
* @throws RestException
+ *
+ * @url GET /upload
*/
public function post($filename, $modulepart, $ref='', $subdir='', $filecontent='', $fileencoding='', $overwriteifexists=0)
{
diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php
index c6b71e8b25c..d59e0036423 100644
--- a/htdocs/api/class/api_login.class.php
+++ b/htdocs/api/class/api_login.class.php
@@ -36,7 +36,7 @@ class Login
*
* Request the API token for a couple username / password.
* Using method POST is recommanded for security reasons (method GET is often logged by default by web servers with parameters so with login and pass into server log file).
- * Both methods are provided for developer conveniance. Best is to not use at all the login API method and enter directly the "api_key" into field at the top right of page (Note: "api_key" can be found/set on the user page).
+ * Both methods are provided for developer conveniance. Best is to not use at all the login API method and enter directly the "DOLAPIKEY" into field at the top right of page. Note: Tha API key (DOLAPIKEY) can be found/set on the user page.
*
* @param string $login User login
* @param string $password User password
diff --git a/htdocs/api/class/api_dictionary.class.php b/htdocs/api/class/api_setup.class.php
similarity index 98%
rename from htdocs/api/class/api_dictionary.class.php
rename to htdocs/api/class/api_setup.class.php
index d551f3d866f..ab11c1e2e2f 100644
--- a/htdocs/api/class/api_dictionary.class.php
+++ b/htdocs/api/class/api_setup.class.php
@@ -30,7 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php';
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
-class Dictionary extends DolibarrApi
+class Setup extends DolibarrApi
{
private $translations = null;
@@ -53,7 +53,7 @@ class Dictionary extends DolibarrApi
* @param int $active Payment type is active or not {@min 0} {@max 1}
* @param string $sqlfilters SQL criteria to filter with. Syntax example "(t.code:=:'CHQ')"
*
- * @url GET payment/types
+ * @url GET dictionary/payment_types
*
* @return array [List of payment types]
*
@@ -122,7 +122,7 @@ class Dictionary extends DolibarrApi
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return List of countries
*
- * @url GET countries
+ * @url GET dictionary/countries
*
* @throws RestException
*/
@@ -188,7 +188,7 @@ class Dictionary extends DolibarrApi
* @param string $lang Code of the language the name of the
* country must be translated to
*
- * @url GET countries/{id}
+ * @url GET dictionary/countries/{id}
*
* @throws RestException
*/
@@ -212,7 +212,7 @@ class Dictionary extends DolibarrApi
* Clean sensible object datas
*
* @param object $object Object to clean
- * @return array Array of cleaned object properties
+ * @return array Array of cleaned object properties
*/
function _cleanObjectDatas($object)
{
@@ -263,7 +263,7 @@ class Dictionary extends DolibarrApi
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return List of events types
*
- * @url GET events
+ * @url GET dictionary/event_types
*
* @throws RestException
*/
@@ -402,7 +402,7 @@ class Dictionary extends DolibarrApi
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return List of towns
*
- * @url GET towns
+ * @url GET dictionary/towns
*
* @throws RestException
*/
@@ -463,7 +463,7 @@ class Dictionary extends DolibarrApi
* @param int $active Payment term is active or not {@min 0} {@max 1}
* @param string $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')"
*
- * @url GET payment/terms
+ * @url GET dictionary/payment_terms
*
* @return array List of payment terms
*
diff --git a/htdocs/api/class/api_status.class.php b/htdocs/api/class/api_status.class.php
index 2ac8da018d6..ea61731b51a 100644
--- a/htdocs/api/class/api_status.class.php
+++ b/htdocs/api/class/api_status.class.php
@@ -21,7 +21,7 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
/**
* API that gives the status of the Dolibarr instance.
*
- * @access protected
+ * @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
class Status
@@ -30,10 +30,13 @@ class Status
* Get status (Dolibarr version)
*/
function index() {
+ global $conf;
+
return array(
'success' => array(
'code' => 200,
- 'dolibarr_version' => DOL_VERSION
+ 'dolibarr_version' => DOL_VERSION,
+ 'access_locked' => (empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)?'0':$conf->global->MAIN_ONLY_LOGIN_ALLOWED)
)
);
}
diff --git a/htdocs/api/index.php b/htdocs/api/index.php
index fb9498f3592..50e0421010a 100644
--- a/htdocs/api/index.php
+++ b/htdocs/api/index.php
@@ -141,8 +141,9 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' |
$moduledirforclass = getModuleDirForApiClass($module);
$modulenameforenabled = $module;
if ($module == 'propale') { $modulenameforenabled='propal'; }
+ if ($module == 'supplierproposal') { $modulenameforenabled='supplier_proposal'; }
- dol_syslog("Found module file ".$file." - module=".$module." - moduledirforclass=".$moduledirforclass);
+ dol_syslog("Found module file ".$file." - module=".$module." - modulenameforenabled=".$modulenameforenabled." - moduledirforclass=".$moduledirforclass);
// Defined if module is enabled
$enabled=true;
@@ -182,10 +183,15 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' |
$classname = ucwords($regapi[1]);
$classname = str_replace('_', '', $classname);
require_once $dir_part.$file_searched;
- if (class_exists($classname))
+ if (class_exists($classname.'Api'))
+ {
+ //dol_syslog("Found API by index.php: classname=".$classname."Api for module ".$dir." into ".$dir_part.$file_searched);
+ $listofapis[strtolower($classname.'Api')] = $classname.'Api';
+ }
+ elseif (class_exists($classname))
{
//dol_syslog("Found API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched);
- $listofapis[] = $classname;
+ $listofapis[strtolower($classname)] = $classname;
}
else
{
@@ -202,10 +208,10 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' |
// Sort the classes before adding them to Restler.
// The Restler API Explorer shows the classes in the order they are added and it's a mess if they are not sorted.
- sort($listofapis);
- foreach ($listofapis as $classname)
+ asort($listofapis);
+ foreach ($listofapis as $apiname => $classname)
{
- $api->r->addAPIClass($classname);
+ $api->r->addAPIClass($classname, $apiname);
}
}
@@ -218,25 +224,26 @@ if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json'
$module = $regbis[1];
}
- // Load a dedicated API file
- dol_syslog("Load a dedicated API file");
-
$module=strtolower($module);
$moduledirforclass = getModuleDirForApiClass($module);
+ // Load a dedicated API file
+ dol_syslog("Load a dedicated API file moduledirforclass=".$moduledirforclass);
+
if (in_array($module, array('category','contact','customer','invoice','order','product','thirdparty','user'))) // Old Apis
{
$classfile = $module;
if ($module == 'customer') { $classfile = 'thirdparty'; }
if ($module == 'order') { $classfile = 'commande'; }
- $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_deprecated_'.$classfile.'.class.php');
+ $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_deprecated_'.$classfile.'.class.php', 0, 2);
$classname=ucwords($module);
if ($module == 'customer') { $classname='Thirdparty'; }
if ($module == 'order') { $classname='Commande'; }
//var_dump($classfile);var_dump($classname);exit;
- $res = include_once $dir_part_file;
- if (! $res)
+ $res = false;
+ if ($dir_part_file) $res = include_once $dir_part_file;
+ if (! $res)
{
print 'API not found (failed to include API file)';
header('HTTP/1.1 501 API not found (failed to include API file)');
@@ -246,21 +253,27 @@ if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json'
}
else
{
- $classfile = str_replace('_', '', $module);
- if ($module == 'contracts') $moduledirforclass = 'contrat';
- if ($module == 'supplierinvoices') $classfile = 'supplier_invoices';
- if ($module == 'supplierorders') $classfile = 'supplier_orders';
- $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php');
+ $tmpmodule = $module;
+ if ($tmpmodule != 'api') $tmpmodule = preg_replace('/api$/i','', $tmpmodule);
+ $classfile = str_replace('_', '', $tmpmodule);
+ if ($module == 'supplierproposals') $classfile = 'supplier_proposals';
+ if ($module == 'supplierorders') $classfile = 'supplier_orders';
+ if ($module == 'supplierinvoices') $classfile = 'supplier_invoices';
+ $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php', 0, 2);
+
$classname=ucwords($module);
- $res = include_once $dir_part_file;
- if (! $res)
+ dol_syslog('Search /'.$moduledirforclass.'/class/api_'.$classfile.'.class.php => dir_part_file='.$dir_part_file.' classname='.$classname);
+
+ $res = false;
+ if ($dir_part_file) $res = include_once $dir_part_file;
+ if (! $res)
{
print 'API not found (failed to include API file)';
header('HTTP/1.1 501 API not found (failed to include API file)');
exit(0);
}
-
+
if (class_exists($classname)) $api->r->addAPIClass($classname);
}
}
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index 7004457b97d..431ac1b5569 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -297,7 +297,11 @@ if ($status == 'done') $title=$langs->trans("DoneActions");
if ($status == 'todo') $title=$langs->trans("ToDoActions");
$param='';
-if ($actioncode || isset($_GET['actioncode']) || isset($_POST['actioncode'])) $param.="&actioncode=".$actioncode;
+if ($actioncode || isset($_GET['actioncode']) || isset($_POST['actioncode'])) {
+ if(is_array($actioncode)) {
+ foreach($actioncode as $str_action) $param.="&actioncode[]=".$str_action;
+ } else $param.="&actioncode=".$actioncode;
+}
if ($resourceid > 0) $param.="&resourceid=".$resourceid;
if ($status || isset($_GET['status']) || isset($_POST['status'])) $param.="&status=".$status;
if ($filter) $param.="&filter=".$filter;
@@ -482,7 +486,14 @@ if (! empty($actioncode))
elseif ($actioncode == 'AC_ALL_AUTO') $sql.= " AND ca.type = 'systemauto'";
else
{
- $sql.=" AND ca.code IN ('".implode("','", explode(',',$actioncode))."')";
+ if (is_array($actioncode))
+ {
+ $sql.=" AND ca.code IN ('".implode("','", $actioncode)."')";
+ }
+ else
+ {
+ $sql.=" AND ca.code IN ('".implode("','", explode(',', $actioncode))."')";
+ }
}
}
}
diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php
index 982974b3d7a..faa7cef8ed9 100644
--- a/htdocs/comm/action/listactions.php
+++ b/htdocs/comm/action/listactions.php
@@ -169,7 +169,11 @@ $listofextcals=array();
$param='';
if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
-if ($actioncode != '') $param.="&actioncode=".$actioncode;
+if ($actioncode != '') {
+ if(is_array($actioncode)) {
+ foreach($actioncode as $str_action) $param.="&actioncode[]=".$str_action;
+ } else $param.="&actioncode=".$actioncode;
+}
if ($resourceid > 0) $param.="&resourceid=".$resourceid;
if ($status != '' && $status > -1) $param.="&status=".$status;
if ($filter) $param.="&filter=".$filter;
@@ -227,7 +231,14 @@ if (! empty($actioncode))
elseif ($actioncode == 'AC_ALL_AUTO') $sql.= " AND c.type = 'systemauto'";
else
{
- $sql.=" AND c.code IN ('".implode("','", explode(',',$actioncode))."')";
+ if (is_array($actioncode))
+ {
+ $sql.=" AND c.code IN ('".implode("','", $actioncode)."')";
+ }
+ else
+ {
+ $sql.=" AND c.code IN ('".implode("','", explode(',', $actioncode))."')";
+ }
}
}
}
diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php
index 792d4f9760d..05eba093cfd 100644
--- a/htdocs/comm/action/peruser.php
+++ b/htdocs/comm/action/peruser.php
@@ -203,7 +203,11 @@ if ($status == 'done') $title=$langs->trans("DoneActions");
if ($status == 'todo') $title=$langs->trans("ToDoActions");
$param='';
-if ($actioncode || isset($_GET['actioncode']) || isset($_POST['actioncode'])) $param.="&actioncode=".$actioncode;
+if ($actioncode || isset($_GET['actioncode']) || isset($_POST['actioncode'])) {
+ if(is_array($actioncode)) {
+ foreach($actioncode as $str_action) $param.="&actioncode[]=".$str_action;
+ } else $param.="&actioncode=".$actioncode;
+}
if ($resourceid > 0) $param.="&resourceid=".$resourceid;
if ($status || isset($_GET['status']) || isset($_POST['status'])) $param.="&status=".$status;
if ($filter) $param.="&filter=".$filter;
@@ -394,7 +398,14 @@ if (! empty($actioncode))
elseif ($actioncode == 'AC_ALL_AUTO') $sql.= " AND ca.type = 'systemauto'";
else
{
- $sql.=" AND ca.code IN ('".implode("','", explode(',',$actioncode))."')";
+ if (is_array($actioncode))
+ {
+ $sql.=" AND ca.code IN ('".implode("','", $actioncode)."')";
+ }
+ else
+ {
+ $sql.=" AND ca.code IN ('".implode("','", explode(',', $actioncode))."')";
+ }
}
}
}
diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
index 63a12e5d25a..a15ed888a6e 100644
--- a/htdocs/comm/propal/card.php
+++ b/htdocs/comm/propal/card.php
@@ -2368,13 +2368,19 @@ if ($action == 'create')
$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
// Show online signature link
- $useonlinepayment = $conf->global->MAIN_FEATURES_LEVEL;
+ $useonlinesignature = $conf->global->MAIN_FEATURES_LEVEL; // Replace this with 1 when feature to make online signature is ok
- if ($object->statut != Propal::STATUS_DRAFT && $useonlinepayment)
+ if ($object->statut != Propal::STATUS_DRAFT && $useonlinesignature)
{
- print ' ';
+ print ' ';
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
- print showOnlineSignatureUrl('proposal', $object->ref);
+ print showOnlineSignatureUrl('proposal', $object->ref).' ';
+ }
+
+ if ($object->statut != Propal::STATUS_DRAFT && ! empty($conf->global->PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD))
+ {
+ print ' '."\n";
+ print showDirectDownloadLink($object).' ';
}
print ' ';
diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php
index 364f63bd4e4..97ea07bf7e6 100644
--- a/htdocs/comm/propal/class/api_proposals.class.php
+++ b/htdocs/comm/propal/class/api_proposals.class.php
@@ -90,7 +90,7 @@ class Proposals extends DolibarrApi
* @param string $sortorder Sort order
* @param int $limit Limit for list
* @param int $page Page number
- * @param string $thirdparty_ids Thirdparty ids to filter commercial proposal of. Example: '1' or '1,2,3' {@pattern /^2|3$/i}
+ * @param string $thirdparty_ids Thirdparty ids to filter commercial proposals. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i}
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')"
* @return array Array of order objects
*/
@@ -152,9 +152,9 @@ class Proposals extends DolibarrApi
while ($i < $min)
{
$obj = $db->fetch_object($result);
- $propal_static = new Propal($db);
- if($propal_static->fetch($obj->rowid)) {
- $obj_ret[] = $this->_cleanObjectDatas($propal_static);
+ $proposal_static = new Propal($db);
+ if($proposal_static->fetch($obj->rowid)) {
+ $obj_ret[] = $this->_cleanObjectDatas($proposal_static);
}
$i++;
}
@@ -163,7 +163,7 @@ class Proposals extends DolibarrApi
throw new RestException(503, 'Error when retrieve propal list : '.$db->lasterror());
}
if( ! count($obj_ret)) {
- throw new RestException(404, 'No order found');
+ throw new RestException(404, 'No proposal found');
}
return $obj_ret;
}
@@ -580,6 +580,7 @@ class Proposals extends DolibarrApi
$object = parent::_cleanObjectDatas($object);
+ unset($object->note);
unset($object->name);
unset($object->lastname);
unset($object->firstname);
diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php
index b94045ee747..54ff5e1afc0 100644
--- a/htdocs/comm/propal/class/propal.class.php
+++ b/htdocs/comm/propal/class/propal.class.php
@@ -836,8 +836,9 @@ class Propal extends CommonObject
if (empty($this->availability_id)) $this->availability_id=0;
if (empty($this->demand_reason_id)) $this->demand_reason_id=0;
- // Multicurrency
- if (!empty($this->multicurrency_code)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $this->date);
+ // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
+ if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $this->date);
+ else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
if (empty($this->fk_multicurrency))
{
$this->multicurrency_code = $conf->currency;
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index 0d73b288f0b..238b677395e 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -2584,6 +2584,20 @@ if ($action == 'create' && $user->rights->commande->creer)
$linktoelem = $form->showLinkToObjectBlock($object, null, array('order'));
$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
+ // Show online signature link
+ $useonlinepayment = $conf->global->ORDER_SHOW_ONLINE_PAYMENT_ON_ORDER;
+ if ($object->statut != Commande::STATUS_DRAFT && $useonlinepayment)
+ {
+ print ' ';
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
+ print showOnlinePaymentUrl('order', $object->ref).' ';
+ }
+
+ if ($object->statut != Commande::STATUS_DRAFT && ! empty($conf->global->ORDER_ALLOW_EXTERNAL_DOWNLOAD))
+ {
+ print ' '."\n";
+ print showDirectDownloadLink($object).' ';
+ }
print '
';
diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php
index e31aaa4e060..a6788f95698 100644
--- a/htdocs/commande/class/api_orders.class.php
+++ b/htdocs/commande/class/api_orders.class.php
@@ -552,6 +552,7 @@ class Orders extends DolibarrApi
$object = parent::_cleanObjectDatas($object);
+ unset($object->note);
unset($object->address);
unset($object->barcode_type);
unset($object->barcode_type_code);
diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index 36162e71384..04ba162cb9e 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -712,7 +712,7 @@ class Commande extends CommonOrder
// $date_commande is deprecated
$date = ($this->date_commande ? $this->date_commande : $this->date);
- // Multicurrency (test on $this->multicurrency_tx because we sould take the default rate only if not using origin rate)
+ // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $date);
else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
if (empty($this->fk_multicurrency))
@@ -3119,7 +3119,6 @@ class Commande extends CommonOrder
// End call triggers
}
- //TODO: Check for error after each action. If one failed we rollback, don't waste time to do action if previous fail
if (! $error)
{
// Delete order details
@@ -3129,23 +3128,24 @@ class Commande extends CommonOrder
$error++;
$this->errors[]=$this->db->lasterror();
}
+ }
- // Delete order
- $sql = 'DELETE FROM '.MAIN_DB_PREFIX."commande WHERE rowid = ".$this->id;
- if (! $this->db->query($sql) )
- {
- $error++;
- $this->errors[]=$this->db->lasterror();
- }
-
+ if (! $error)
+ {
// Delete linked object
$res = $this->deleteObjectLinked();
if ($res < 0) $error++;
+ }
+ if (! $error)
+ {
// Delete linked contacts
$res = $this->delete_linked_contact();
if ($res < 0) $error++;
+ }
+ if (! $error)
+ {
// Remove extrafields
if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
{
@@ -3156,8 +3156,22 @@ class Commande extends CommonOrder
dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
}
}
+ }
- // On efface le repertoire de pdf provisoire
+ if (! $error)
+ {
+ // Delete object
+ $sql = 'DELETE FROM '.MAIN_DB_PREFIX."commande WHERE rowid = ".$this->id;
+ if (! $this->db->query($sql) )
+ {
+ $error++;
+ $this->errors[]=$this->db->lasterror();
+ }
+ }
+
+ if (! $error)
+ {
+ // Remove directory with files
$comref = dol_sanitizeFileName($this->ref);
if ($conf->commande->dir_output && !empty($this->ref))
{
@@ -3183,8 +3197,6 @@ class Commande extends CommonOrder
}
}
}
-
-
}
if (! $error)
diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php
index 0fc7657f184..8aafef55fba 100644
--- a/htdocs/compta/bank/card.php
+++ b/htdocs/compta/bank/card.php
@@ -197,8 +197,15 @@ if ($action == 'update')
$object->proprio = trim($_POST["proprio"]);
$object->owner_address = trim($_POST["owner_address"]);
- $account_number = GETPOST('account_number', 'int');
- if ($account_number <= 0) { $object->account_number = ''; } else { $object->account_number = $account_number; }
+ $account_number = GETPOST('account_number', 'alpha');
+ if (empty($account_number) || $account_number == '-1')
+ {
+ $object->account_number = '';
+ }
+ else
+ {
+ $object->account_number = $account_number;
+ }
$fk_accountancy_journal = GETPOST('fk_accountancy_journal','int');
if ($fk_accountancy_journal <= 0) { $object->fk_accountancy_journal = ''; } else { $object->fk_accountancy_journal = $fk_accountancy_journal; }
@@ -213,7 +220,7 @@ if ($action == 'update')
if ($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED && empty($object->account_number))
{
- setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("AccountancyCode")), null, 'error');
+ setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("AccountancyCode")), null, 'errors');
$action='edit'; // Force chargement page en mode creation
$error++;
}
diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php
index 7696427b059..3819e2acccb 100644
--- a/htdocs/compta/bank/transfer.php
+++ b/htdocs/compta/bank/transfer.php
@@ -82,9 +82,12 @@ if ($action == 'add')
$accountto=new Account($db);
$accountto->fetch(GETPOST('account_to','int'));
- if ($accountto->currency_code == $accountfrom->currency_code) {
+ if ($accountto->currency_code == $accountfrom->currency_code)
+ {
$amountto=$amount;
- } else {
+ }
+ else
+ {
if (! $amountto)
{
$error++;
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 868856094df..8365a52f277 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -4382,9 +4382,15 @@ else if ($id > 0 || ! empty($ref))
if ($object->statut != Facture::STATUS_DRAFT && $useonlinepayment)
{
- print ' ';
+ print ' '."\n";
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
- print showOnlinePaymentUrl('invoice', $object->ref);
+ print showOnlinePaymentUrl('invoice', $object->ref).' ';
+ }
+
+ if ($object->statut != Facture::STATUS_DRAFT && ! empty($conf->global->INVOICE_ALLOW_EXTERNAL_DOWNLOAD))
+ {
+ print ' '."\n";
+ print showDirectDownloadLink($object).' ';
}
print '
';
diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php
index 222404411d7..fec3edd11ea 100644
--- a/htdocs/compta/facture/class/api_invoices.class.php
+++ b/htdocs/compta/facture/class/api_invoices.class.php
@@ -903,6 +903,7 @@ class Invoices extends DolibarrApi
$object = parent::_cleanObjectDatas($object);
+ unset($object->note);
unset($object->address);
unset($object->barcode_type);
unset($object->barcode_type_code);
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 6f36bd016b4..9801726246b 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -246,7 +246,7 @@ class Facture extends CommonInvoice
$this->brouillon = 1;
if (empty($this->entity)) $this->entity = $conf->entity;
- // Multicurrency (test on $this->multicurrency_tx because we sould take the default rate only if not using origin rate)
+ // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code);
else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
if (empty($this->fk_multicurrency))
@@ -3193,7 +3193,7 @@ class Facture extends CommonInvoice
$field2='fk_paiementfourn';
}
- $sql = 'SELECT pf.amount, pf.multicurrency_amount, p.fk_paiement, p.datep, p.num_paiement as num, t.code';
+ $sql = 'SELECT p.ref, pf.amount, pf.multicurrency_amount, p.fk_paiement, p.datep, p.num_paiement as num, t.code';
$sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t';
$sql.= ' WHERE pf.'.$field.' = '.$this->id;
//$sql.= ' WHERE pf.'.$field.' = 1';
@@ -3211,7 +3211,7 @@ class Facture extends CommonInvoice
while ($i < $num)
{
$obj = $this->db->fetch_object($resql);
- $retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep, 'num'=>$obj->num);
+ $retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep, 'num'=>$obj->num, 'ref'=>$obj->ref);
$i++;
}
$this->db->free($resql);
diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php
index 38bfef6ebe2..06e5a628b86 100644
--- a/htdocs/contrat/list.php
+++ b/htdocs/contrat/list.php
@@ -64,7 +64,7 @@ $search_sale=GETPOST('search_sale','int');
$search_product_category=GETPOST('search_product_category','int');
$search_dfmonth=GETPOST('search_dfmonth','int');
$search_dfyear=GETPOST('search_dfyear','int');
-$search_op2df=GETPOST('search_op2df');
+$search_op2df=GETPOST('search_op2df','alpha');
$day=GETPOST("day","int");
$year=GETPOST("year","int");
$month=GETPOST("month","int");
@@ -129,7 +129,7 @@ $arrayfields=array(
'c.date_contrat'=>array('label'=>$langs->trans("DateContract"), 'checked'=>1),
'c.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
'c.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
- 'lower_planned_end_date'=>array('label'=>$langs->trans("LowerDateEndPlannedShort"), 'checked'=>1, 'position'=>900),
+ 'lower_planned_end_date'=>array('label'=>$langs->trans("LowerDateEndPlannedShort"), 'checked'=>1, 'position'=>900, 'help'=>$langs->trans("LowerDateEndPlannedShort")),
'status'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
);
// Extra fields
@@ -285,30 +285,24 @@ foreach ($search_array_options as $key => $val)
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
-
-if ($search_dfyear > 0)
-{
-// $sql.= " AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") ".$search_op2df."= '".$db->idate(($search_op2df == "<" ? dol_get_last_day($search_dfyear,$search_dfmonth,false) : dol_get_first_day($search_dfyear,$search_dfmonth,false)))."'";
-}
-
$sql.= " GROUP BY c.rowid, c.ref, c.datec, c.tms, c.date_contrat, c.statut, c.ref_customer, c.ref_supplier, c.note_private, c.note_public,";
$sql.= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.code_client,';
$sql.= " typent.code,";
$sql.= " state.code_departement, state.nom";
-//$sql.= " MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").")";
// Add fields from extrafields
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : '');
// Add where from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
-
-if ($search_dfyear > 0)
+if ($search_dfyear > 0 && $search_op2df)
{
- $sql.= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") ".$search_op2df."= '".$db->idate(($search_op2df == "<" ? dol_get_last_day($search_dfyear,$search_dfmonth,false) : dol_get_first_day($search_dfyear,$search_dfmonth,false)))."'";
+ if ($search_op2df == '<=') $sql.= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear,$search_dfmonth,false))."'";
+ elseif ($search_op2df == '>=') $sql.= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear,$search_dfmonth,false))."'";
+ else $sql.= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear,$search_dfmonth,false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear,$search_dfmonth,false))."'";
}
-
$sql.= $db->order($sortfield,$sortorder);
+//print $sql;
$totalnboflines=0;
$result=$db->query($sql);
@@ -566,7 +560,7 @@ if ($resql)
if (! empty($arrayfields['lower_planned_end_date']['checked']))
{
print '
';
- $arrayofoperators=array('<'=>'<','>'=>'>');
+ $arrayofoperators=array('0'=>'','='=>'=','<='=>'<=','>='=>'>=');
print $form->selectarray('search_op2df',$arrayofoperators,$search_op2df,0);
print '';
print $formother->select_month($search_dfmonth, 'search_dfmonth', 1);
diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php
index 1f47a94f6d2..ea5d6c3db26 100644
--- a/htdocs/core/actions_linkedfiles.inc.php
+++ b/htdocs/core/actions_linkedfiles.inc.php
@@ -56,7 +56,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
{
if ($object->id)
{
- $urlfile = GETPOST('urlfile', 'alpha'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
+ $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
if (GETPOST('section', 'alpha')) $file = $upload_dir . "/" . $urlfile; // For a delete of GED module urlfile contains full path from upload_dir
else // For documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile.
{
diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php
index 2607002dff3..ddcf8eb62d8 100644
--- a/htdocs/core/ajax/ajaxdirpreview.php
+++ b/htdocs/core/ajax/ajaxdirpreview.php
@@ -165,7 +165,7 @@ if ($type == 'directory')
$sorting = (strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC);
// Right area. If module is defined here, we are in automatic ecm.
- $automodules = array('company', 'invoice', 'invoice_supplier', 'propal', 'order', 'order_supplier', 'contract', 'product', 'tax', 'project', 'fichinter', 'user', 'expensereport');
+ $automodules = array('company', 'invoice', 'invoice_supplier', 'propal', 'supplier_proposal', 'order', 'order_supplier', 'contract', 'product', 'tax', 'project', 'fichinter', 'user', 'expensereport');
// TODO change for multicompany sharing
// Auto area for suppliers invoices
@@ -174,8 +174,10 @@ if ($type == 'directory')
else if ($module == 'invoice') $upload_dir = $conf->facture->dir_output;
// Auto area for suppliers invoices
else if ($module == 'invoice_supplier') $upload_dir = $conf->fournisseur->facture->dir_output;
- // Auto area for customers orders
+ // Auto area for customers proposal
else if ($module == 'propal') $upload_dir = $conf->propal->dir_output;
+ // Auto area for suppliers proposal
+ else if ($module == 'supplier_proposal') $upload_dir = $conf->supplier_proposal->dir_output;
// Auto area for customers orders
else if ($module == 'order') $upload_dir = $conf->commande->dir_output;
// Auto area for suppliers orders
@@ -218,7 +220,8 @@ if ($type == 'directory')
if ($module == 'medias')
{
$relativepath=GETPOST('file','alpha');
- $upload_dir = $dolibarr_main_data_root.'/medias/'.$relativepath;
+ if ($relativepath && $relativepath!= '/') $relativepath.='/';
+ $upload_dir = $dolibarr_main_data_root.'/'.$module.'/'.$relativepath;
}
else
{
@@ -243,7 +246,11 @@ if ($type == 'directory')
$textifempty = $langs->trans('NoFileFound');
}
- else if ($section === '0') $textifempty=''.$langs->trans("DirNotSynchronizedSyncFirst").'
';
+ else if ($section === '0')
+ {
+ if ($module == 'ecm') $textifempty=''.$langs->trans("DirNotSynchronizedSyncFirst").'
';
+ else $textifempty = $langs->trans('NoFileFound');
+ }
else $textifempty=($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection"));
if ($module == 'medias')
diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
index ea4bf830e21..9d0908953c6 100644
--- a/htdocs/core/ajax/ajaxdirtree.php
+++ b/htdocs/core/ajax/ajaxdirtree.php
@@ -23,25 +23,35 @@
// This script is called with a POST method.
-// Directory to scan (full path) is inside POST['dir'].
+// Directory to scan (full path) is inside POST['dir'] and encode by js escape() if ajax is used or encoded by urlencode if mode=noajax
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
-$res=@include '../../main.inc.php';
-include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-include_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php';
-include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
-include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
+if (! isset($mode) || $mode != 'noajax') // For ajax call
+{
+ $res=@include '../../main.inc.php';
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php';
+ include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+ include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
-$openeddir = GETPOST('openeddir');
-$modulepart= GETPOST('modulepart');
-$selecteddir = jsUnEscape(GETPOST('dir')); // relative path. We must decode using same encoding function used by javascript: escape()
-if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir); // We removed last '/' except if it is '/'
+ $openeddir = GETPOST('openeddir');
+ $modulepart= GETPOST('modulepart');
+ $selecteddir = jsUnEscape(GETPOST('dir')); // relative path. We must decode using same encoding function used by javascript: escape()
+ if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir); // We removed last '/' except if it is '/'
+}
+else // For no ajax call
+{
+ $openeddir = GETPOST('openeddir');
+ $modulepart= GETPOST('modulepart');
+ $selecteddir = GETPOST('dir');
+ if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir); // We removed last '/' except if it is '/'
+ if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
+}
$langs->load("ecm");
@@ -76,7 +86,10 @@ if ($modulepart == 'medias')
* View
*/
-top_httphead();
+if (! isset($mode) || $mode != 'noajax')
+{
+ top_httphead();
+}
//print ''."\n";
$userstatic=new User($db);
@@ -97,151 +110,323 @@ foreach($sqltree as $keycursor => $val)
}
}
-
-if (file_exists($fullpathselecteddir))
+if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
{
- $files = @scandir($fullpathselecteddir);
+ if (file_exists($fullpathselecteddir))
+ {
+ $files = @scandir($fullpathselecteddir);
- if ($files)
- {
- natcasesort($files);
- if ( count($files) > 2 ) /* The 2 accounts for . and .. */
- {
- echo "\n";
+ if ($files)
+ {
+ natcasesort($files);
+ if (count($files) > 2) /* The 2 accounts for . and .. */
+ {
+ echo ''."\n";
- // All dirs
- foreach( $files as $file ) // $file can be '.', '..', or 'My dir' or 'My file'
- {
- if ($file == 'temp') continue;
+ // All dirs
+ foreach ($files as $file) // $file can be '.', '..', or 'My dir' or 'My file'
+ {
+ if ($file == 'temp') continue;
- $nbofsubdir=0;
- $nboffilesinsubdir=0;
+ $nbofsubdir=0;
+ $nboffilesinsubdir=0;
- $val=array();
+ $val=array();
- // Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan
- foreach($sqltree as $key => $tmpval)
- {
- //print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)." \n";
- if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file)) // We found equivalent record into database
- {
- $val=$tmpval;
- $resarray=tree_showpad($sqltree,$key,1);
+ // Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan
+ foreach($sqltree as $key => $tmpval)
+ {
+ //print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)." \n";
+ if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file)) // We found equivalent record into database
+ {
+ $val=$tmpval;
+ $resarray=tree_showpad($sqltree,$key,1);
- // Refresh cache for this subdir
- if (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] < 0) // Cache is not up to date, so we update it for this directory t
- {
- $result=$ecmdirstatic->fetch($val['id']);
- $ecmdirstatic->ref=$ecmdirstatic->label;
+ // Refresh cache for this subdir
+ if (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] < 0) // Cache is not up to date, so we update it for this directory t
+ {
+ $result=$ecmdirstatic->fetch($val['id']);
+ $ecmdirstatic->ref=$ecmdirstatic->label;
- $result=$ecmdirstatic->refreshcachenboffile(0);
- $val['cachenbofdoc']=$result;
- }
+ $result=$ecmdirstatic->refreshcachenboffile(0);
+ $val['cachenbofdoc']=$result;
+ }
- $a=$resarray[0];
- $nbofsubdir=$resarray[1];
- $nboffilesinsubdir=$resarray[2];
- break;
- }
- }
+ $a=$resarray[0];
+ $nbofsubdir=$resarray[1];
+ $nboffilesinsubdir=$resarray[2];
+ break;
+ }
+ }
- //print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
- if ($file != '.' && $file != '..' && ((! empty($val['fullrelativename']) && $val['id'] >= 0) || dol_is_dir($fullpathselecteddir . (preg_match('/\/$/',$fullpathselecteddir)?'':'/') . $file)))
- {
- if (empty($val['fullrelativename'])) // If we did not find entry into database, but found a directory (dol_is_dir was ok at previous test)
- {
- $val['fullrelativename']=$file;
- $val['id']=0;
- $val['label']=$file;
- $val['description']='';
- $nboffilesinsubdir=$langs->trans("Unknown");
- }
+ //print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
+ if ($file != '.' && $file != '..' && ((! empty($val['fullrelativename']) && $val['id'] >= 0) || dol_is_dir($fullpathselecteddir . (preg_match('/\/$/',$fullpathselecteddir)?'':'/') . $file)))
+ {
+ if (empty($val['fullrelativename'])) // If we did not find entry into database, but found a directory (dol_is_dir was ok at previous test)
+ {
+ $val['fullrelativename']=(($selecteddir && $selecteddir != '/')?$selecteddir.'/':'').$file;
+ $val['id']=0;
+ $val['label']=$file;
+ $val['description']='';
+ $nboffilesinsubdir=$langs->trans("Unknown");
+ }
- print '';
+ print ' ';
- print "";
- print dol_escape_htmltag($file);
- print " ";
+ print "";
+ print dol_escape_htmltag($file);
+ print " ";
- print '';
+ print '
';
- print '
';
+ print '';
- /*print '';
- print dol_escape_htmltag($file);
- print ' ';*/
+ /*print '';
+ print dol_escape_htmltag($file);
+ print ' ';*/
- // Nb of docs
- print '';
- print (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:' ';
- print ' ';
- print '';
- if ($nbofsubdir > 0 && $nboffilesinsubdir > 0) print '+'.$nboffilesinsubdir.' ';
- print ' ';
+ // Nb of docs
+ print '';
+ print (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:' ';
+ print ' ';
+ print '';
+ if ($nbofsubdir > 0 && $nboffilesinsubdir > 0) print '+'.$nboffilesinsubdir.' ';
+ print ' ';
- // Edit link
- print ''.img_view($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle"').' ';
+ // Edit link
+ print ''.img_view($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle"').' ';
- // Add link
- //print ''.img_edit_add().' ';
- //print ' ';
+ // Add link
+ //print ''.img_edit_add().' ';
+ //print ' ';
- // Info
- print '';
- $userstatic->id=isset($val['fk_user_c'])?$val['fk_user_c']:0;
- $userstatic->lastname=isset($val['login_c'])?$val['login_c']:0;
- $htmltooltip=''.$langs->trans("ECMSection").' : '.$val['label'].' ';
- $htmltooltip=''.$langs->trans("Type").' : '.$langs->trans("ECMSectionManual").' ';
- $htmltooltip.=''.$langs->trans("ECMCreationUser").' : '.$userstatic->getNomUrl(1, '', false, 1).' ';
- $htmltooltip.=''.$langs->trans("ECMCreationDate").' : '.(isset($val['date_c'])?dol_print_date($val['date_c'],"dayhour"):$langs->trans("NeedRefresh")).' ';
- $htmltooltip.=''.$langs->trans("Description").' : '.$val['description'].' ';
- $htmltooltip.=''.$langs->trans("ECMNbOfFilesInDir").' : '.((isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:$langs->trans("NeedRefresh")).' ';
- if ($nboffilesinsubdir > 0) $htmltooltip.=''.$langs->trans("ECMNbOfFilesInSubDir").' : '.$nboffilesinsubdir;
- else $htmltooltip.=''.$langs->trans("ECMNbOfSubDir").' : '.($nbofsubdir >= 0 ? $nbofsubdir : $langs->trans("NeedRefresh")).' ';
- print $form->textwithpicto('',$htmltooltip,1,"info");
- print " ";
+ // Info
+ if ($modulepart == 'ecm')
+ {
+ print '';
+ $userstatic->id=isset($val['fk_user_c'])?$val['fk_user_c']:0;
+ $userstatic->lastname=isset($val['login_c'])?$val['login_c']:0;
+ $htmltooltip=''.$langs->trans("ECMSection").' : '.$val['label'].' ';
+ $htmltooltip=''.$langs->trans("Type").' : '.$langs->trans("ECMSectionManual").' ';
+ $htmltooltip.=''.$langs->trans("ECMCreationUser").' : '.$userstatic->getNomUrl(1, '', false, 1).' ';
+ $htmltooltip.=''.$langs->trans("ECMCreationDate").' : '.(isset($val['date_c'])?dol_print_date($val['date_c'],"dayhour"):$langs->trans("NeedRefresh")).' ';
+ $htmltooltip.=''.$langs->trans("Description").' : '.$val['description'].' ';
+ $htmltooltip.=''.$langs->trans("ECMNbOfFilesInDir").' : '.((isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:$langs->trans("NeedRefresh")).' ';
+ if ($nboffilesinsubdir > 0) $htmltooltip.=''.$langs->trans("ECMNbOfFilesInSubDir").' : '.$nboffilesinsubdir;
+ else $htmltooltip.=''.$langs->trans("ECMNbOfSubDir").' : '.($nbofsubdir >= 0 ? $nbofsubdir : $langs->trans("NeedRefresh")).' ';
+ print $form->textwithpicto('',$htmltooltip,1,"info");
+ print " ";
+ }
- print "
\n";
- print '';
+ print "
\n";
+ print '
';
- //print '
';
- print "\n";
- }
- }
+ //print '
';
+ print "\n";
+ }
+ }
- // Enable jquery handlers on new generated HTML objects
- print "\n\n";
- print '';
+ /* TODO Remove this. Is replaced with function as 3rd parameter of fileTree */
+ jQuery(".fmdirlia").click(function(e) {
+ id=jQuery(this).attr(\'id\').substr(12);
+ jQuery("#formuserfile_section_dir").val(jQuery(this).attr(\'rel\'));
+ jQuery("#formuserfile_section_id").val(id);
+ });
+ });
+ ';
- echo "\n";
+ echo "\n";
- }
- }
- else print "PermissionDenied";
+ }
+ }
+ else print "PermissionDenied";
+ }
+
+ // This ajax service is called only when a directory $selecteddir is opened but not when closed.
+ //print '';
}
-// This ajax service is called only when a directory $selecteddir is opened but not when closed.
-//print '';
-if (is_object($db)) $db->close();
+if (empty($conf->use_javascript_ajax) || ! empty($conf->global->MAIN_ECM_DISABLE_JS))
+{
+ print '
';
+}
+
+
+// Close db if mode is not noajax
+if ((! isset($mode) || $mode != 'noajax') && is_object($db)) $db->close();
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 47b27641436..7f73630f7f6 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -5340,8 +5340,9 @@ abstract class CommonObject
}
}
- if ($key == 'ref') $value=$this->getNomUrl(1, '', 0, '', 1);
- elseif ($key == 'status') $value=$this->getLibStatut(3);
+ // Format output value differently according to properties of field
+ if ($key == 'ref' && method_exists($this, 'getNomUrl')) $value=$this->getNomUrl(1, '', 0, '', 1);
+ elseif ($key == 'status' && method_exists($this, 'getLibStatut')) $value=$this->getLibStatut(3);
elseif ($type == 'date')
{
$value=dol_print_date($value,'day');
@@ -5382,11 +5383,11 @@ abstract class CommonObject
}
elseif ($type == 'select')
{
- $value=$params['options'][$value];
+ $value=$param['options'][$value];
}
elseif ($type == 'sellist')
{
- $param_list=array_keys($params['options']);
+ $param_list=array_keys($param['options']);
$InfoFieldList = explode(":", $param_list[0]);
$selectkey="rowid";
@@ -5463,7 +5464,7 @@ abstract class CommonObject
}
elseif ($type == 'radio')
{
- $value=$params['options'][$value];
+ $value=$param['options'][$value];
}
elseif ($type == 'checkbox')
{
@@ -5472,7 +5473,7 @@ abstract class CommonObject
if (is_array($value_arr))
{
foreach ($value_arr as $keyval=>$valueval) {
- $toprint[]='
'.$params['options'][$valueval].' ';
+ $toprint[]='
'.$param['options'][$valueval].' ';
}
}
$value='
'.implode(' ', $toprint).' ';
@@ -5481,7 +5482,7 @@ abstract class CommonObject
{
$value_arr = explode(',', $value);
- $param_list = array_keys($params['options']);
+ $param_list = array_keys($param['options']);
$InfoFieldList = explode(":", $param_list[0]);
$selectkey = "rowid";
@@ -6262,8 +6263,11 @@ abstract class CommonObject
unset($fieldvalues['rowid']); // The field 'rowid' is reserved field name for autoincrement field so we don't need it into update.
$keys=array();
+ $values = array();
foreach ($fieldvalues as $k => $v) {
$keys[$k] = $k;
+ $value = $this->fields[$k];
+ $values[$k] = $this->quote($v, $value);
$tmp[] = $k.'='.$this->quote($v, $this->fields[$k]);
}
diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index ca7bed7ff4e..9fb13da7dd9 100644
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -141,7 +141,7 @@ class ExtraFields
* @param int $alwayseditable Is attribute always editable regardless of the document status
* @param string $perms Permission to check
* @param int $list Visibilty
- * @param int $ishidden Deprecated. Us visibility instead.
+ * @param int $ishidden Deprecated. Use visibility instead.
* @param string $computed Computed value
* @param string $entity Entity of extrafields
* @param string $langfile Language file
@@ -742,7 +742,7 @@ class ExtraFields
$this->attribute_param[$tab->name]=($tab->param ? unserialize($tab->param) : '');
$this->attribute_pos[$tab->name]=$tab->pos;
$this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable;
- $this->attribute_perms[$tab->name]=$tab->perms;
+ $this->attribute_perms[$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
$this->attribute_langfile[$tab->name]=$tab->langs;
$this->attribute_list[$tab->name]=$tab->list;
$this->attribute_entityid[$tab->name]=$tab->entity;
@@ -759,7 +759,7 @@ class ExtraFields
$this->attributes[$tab->elementtype]['param'][$tab->name]=($tab->param ? unserialize($tab->param) : '');
$this->attributes[$tab->elementtype]['pos'][$tab->name]=$tab->pos;
$this->attributes[$tab->elementtype]['alwayseditable'][$tab->name]=$tab->alwayseditable;
- $this->attributes[$tab->elementtype]['perms'][$tab->name]=$tab->perms;
+ $this->attributes[$tab->elementtype]['perms'][$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
$this->attributes[$tab->elementtype]['langfile'][$tab->name]=$tab->langs;
$this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list;
$this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity;
@@ -975,6 +975,7 @@ class ExtraFields
$param_list=array_keys($param['options']);
$InfoFieldList = explode(":", $param_list[0]);
$parentName='';
+ $parentField='';
// 0 : tableName
// 1 : label field name
// 2 : key fields name (if differ of rowid)
@@ -1106,7 +1107,7 @@ class ExtraFields
$out.='
'.$labeltoshow.' ';
}
- if (!empty($InfoFieldList[3]))
+ if (!empty($InfoFieldList[3]) && $parentField)
{
$parent = $parentName.':'.$obj->{$parentField};
}
@@ -1156,6 +1157,8 @@ class ExtraFields
if (is_array($param['options'])) {
$param_list = array_keys($param['options']);
$InfoFieldList = explode(":", $param_list[0]);
+ $parentName='';
+ $parentField='';
// 0 : tableName
// 1 : label field name
// 2 : key fields name (if differ of rowid)
@@ -1229,6 +1232,7 @@ class ExtraFields
$labeltoshow = '';
$obj = $this->db->fetch_object($resql);
+ $notrans = false;
// Several field into label (eq table:code|libelle:rowid)
$fields_label = explode('|', $InfoFieldList[1]);
if (is_array($fields_label)) {
@@ -1269,7 +1273,7 @@ class ExtraFields
$data[$obj->rowid]=$labeltoshow;
}
- if (! empty($InfoFieldList[3])) {
+ if (! empty($InfoFieldList[3]) && $parentField) {
$parent = $parentName . ':' . $obj->{$parentField};
}
@@ -1286,12 +1290,11 @@ class ExtraFields
print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.
';
}
}
- $out .= '';
}
elseif ($type == 'link')
{
$param_list=array_keys($param['options']); // $param_list='ObjectName:classPath'
- $showempty=(($val['notnull'] == 1 && $val['default'] != '')?0:1);
+ $showempty=(($required && $default != '')?0:1);
$out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty);
}
elseif ($type == 'password')
@@ -1334,7 +1337,7 @@ class ExtraFields
$perms=$this->attribute_perms[$key];
$langfile=$this->attribute_langfile[$key];
$list=$this->attribute_list[$key];
- $hidden=(($list != 0) ? 1 : 0); // If zero, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
+ $hidden=(($list == 0) ? 1 : 0); // If zero, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
if ($hidden) return ''; // This is a protection. If field is hidden, we should just not call this method.
@@ -1480,6 +1483,7 @@ class ExtraFields
{
$value_arr=explode(',',$value);
$value='';
+ $toprint=array();
if (is_array($value_arr))
{
foreach ($value_arr as $keyval=>$valueval) {
diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
index dee63987d45..cf5d02a7b31 100644
--- a/htdocs/core/class/utils.class.php
+++ b/htdocs/core/class/utils.class.php
@@ -449,4 +449,78 @@ class Utils
return 0;
}
+
+
+
+ /**
+ * Execute a CLI command.
+ *
+ * @param string $command Command line to execute.
+ * @param string $outputfile Output file (used only when method is 2). For exemple $conf->admin->dir_temp.'/out.tmp';
+ * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method
+ * @return array array('result'=>...,'output'=>...,'error'=>...). result = 0 means OK.
+ */
+ function executeCLI($command, $outputfile, $execmethod=0)
+ {
+ global $conf, $langs;
+
+ $result = 0;
+ $output = '';
+ $error = '';
+
+ $command=escapeshellcmd($command);
+ $command.=" 2>&1";
+
+ if (! empty($conf->global->MAIN_EXEC_USE_POPEN)) $execmethod=$conf->global->MAIN_EXEC_USE_POPEN;
+ if (empty($execmethod)) $execmethod=1;
+ //$execmethod=1;
+
+ dol_syslog("Utils::executeCLI execmethod=".$execmethod." system:".$command, LOG_DEBUG);
+ $output_arr=array();
+
+ if ($execmethod == 1)
+ {
+ exec($command, $output_arr, $retval);
+ $result = $retval;
+ if ($retval != 0)
+ {
+ $langs->load("errors");
+ dol_syslog("Utils::executeCLI retval after exec=".$retval, LOG_ERR);
+ $error = 'Error '.$retval;
+ }
+ }
+ if ($execmethod == 2) // With this method, there is no way to get the return code, only output
+ {
+ $ok=0;
+ $handle = fopen($outputfile, 'w+b');
+ if ($handle)
+ {
+ dol_syslog("Utils::executeCLI run command ".$command);
+ $handlein = popen($command, 'r');
+ while (!feof($handlein))
+ {
+ $read = fgets($handlein);
+ fwrite($handle,$read);
+ $output_arr[]=$read;
+ }
+ pclose($handlein);
+ fclose($handle);
+ }
+ if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
+ }
+
+ // Update with result
+ if (is_array($output_arr) && count($output_arr)>0)
+ {
+ foreach($output_arr as $val)
+ {
+ $output.=$val.($execmethod == 2 ? '' : "\n");
+ }
+ }
+
+ dol_syslog("Utils::executeCLI result=".$result." output=".$output." error=".$error, LOG_DEBUG);
+
+ return array('result'=>$result, 'output'=>$output, 'error'=>$error);
+ }
+
}
diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php
index 99b799d5d6e..fa87fb3a4d6 100644
--- a/htdocs/core/db/DoliDB.class.php
+++ b/htdocs/core/db/DoliDB.class.php
@@ -84,12 +84,12 @@ abstract class DoliDB implements Database
* Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field.
* Function to use to build INSERT, UPDATE or WHERE predica
*
- * @param int $param Date TMS to convert
- * @return string Date in a string YYYYMMDDHHMMSS
+ * @param int $param Date TMS to convert
+ * @return string Date in a string YYYYMMDDHHMMSS
*/
function idate($param)
{
- return dol_print_date($param,"%Y%m%d%H%M%S");
+ return dol_print_date($param,"%Y-%m-%d %H:%M:%S");
}
/**
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 2f59c7e388c..6fd7beb86bb 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -1052,7 +1052,11 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable
$file_name_osencoded=dol_osencode($file_name);
// Check if destination dir is writable
- // TODO
+ if (! is_writable(dirname($file_name_osencoded)))
+ {
+ dol_syslog("Files.lib::dol_move_uploaded_file Dir ".dirname($file_name_osencoded)." is not writable. Return 'ErrorDirNotWritable'", LOG_WARNING);
+ return 'ErrorDirNotWritable';
+ }
// Check if destination file already exists
if (! $allowoverwrite)
@@ -1468,7 +1472,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio
}
$nbfile = count($TFile['name']);
-
+ $nbok = 0;
for ($i = 0; $i < $nbfile; $i++)
{
// Define $destfull (path to file including filename) and $destfile (only filename)
@@ -1548,8 +1552,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio
}
}
- $res = 1;
- setEventMessages($langs->trans("FileTransferComplete"), null, 'mesgs');
+ $nbok++;
}
else
{
@@ -1568,7 +1571,11 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio
}
}
}
-
+ if ($nbok > 0)
+ {
+ $res = 1;
+ setEventMessages($langs->trans("FileTransferComplete"), null, 'mesgs');
+ }
}
} elseif ($link) {
require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 5d8be8ec224..7660b198313 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -270,10 +270,11 @@ function GETPOSTISSET($paramname)
* 'custom'= custom filter specify $filter and $options)
* @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get, 4 = post then get then cookie)
* @param int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails)
- * @param mixed $options Options to pass to filter_var when $check is set to 'custom'.
+ * @param mixed $options Options to pass to filter_var when $check is set to 'custom'
+ * @param string $noreplace Force disable of replacement of __xxx__ strings.
* @return string|string[] Value found (string or array), or '' if check fails
*/
-function GETPOST($paramname, $check='alpha', $method=0, $filter=NULL, $options=NULL)
+function GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NULL, $noreplace=0)
{
global $mysoc,$user,$conf;
@@ -467,7 +468,7 @@ function GETPOST($paramname, $check='alpha', $method=0, $filter=NULL, $options=N
// Substitution variables for GETPOST (used to get final url with variable parameters or final default value with variable paramaters)
// Example of variables: __DAY__, __MONTH__, __YEAR__, __MYCOUNTRYID__, __USERID__, __ENTITYID__, ...
// We do this only if var is a GET. If it is a POST, may be we want to post the text with vars as the setup text.
- if (! is_array($out) && empty($_POST[$paramname]))
+ if (! is_array($out) && empty($_POST[$paramname]) && empty($noreplace))
{
$maxloop=20; $loopnb=0; // Protection against infinite loop
while (preg_match('/__([A-Z0-9]+_?[A-Z0-9]+)__/i', $out, $reg) && ($loopnb < $maxloop)) // Detect '__ABCDEF__' as key 'ABCDEF' and '__ABC_DEF__' as key 'ABC_DEF'. Detection is also correct when 2 vars are side by side.
@@ -653,7 +654,9 @@ function dol_include_once($relpath, $classname='')
*
* @param string $path Relative path to file (if mode=0) or relative url (if mode=1). Ie: mydir/myfile, ../myfile
* @param int $type 0=Used for a Filesystem path, 1=Used for an URL path (output relative), 2=Used for an URL path (output full path using same host that current url), 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file)
- * @param int $returnemptyifnotfound If path==0 and if file was not found, do not return default path but an empty string
+ * @param int $returnemptyifnotfound 0:If $type==0 and if file was not found into alternate dir, return default path into main dir (no test on it)
+ * 1:If $type==0 and if file was not found into alternate dir, return empty string
+ * 2:If $type==0 and if file was not found into alternate dir, test into main dir, return default path if found, empty string if not found
* @return string Full filesystem path (if path=0), Full url path (if mode=1)
*/
function dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
@@ -674,9 +677,9 @@ function dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
return $res;
}
}
- if ($returnemptyifnotfound) // Not found, we return empty string
+ if ($returnemptyifnotfound) // Not found into alternate dir
{
- return '';
+ if ($returnemptyifnotfound == 1 || ! file_exists($res)) return '';
}
}
else // For an url path
@@ -2717,10 +2720,11 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo
* @param int $srconly Return only content of the src attribute of img.
* @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip.
* @param string $alt Force alt for bind peoplae
+ * @param string $morecss Add more class css on img tag (For example 'myclascss')
* @return string Return img tag
* @see #img_object, #img_picto_common
*/
-function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly=0, $notitle=0, $alt='')
+function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly=0, $notitle=0, $alt='', $morecss='')
{
global $conf, $langs;
@@ -2742,7 +2746,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
if ($picto == 'off') { $fakey = 'fa-square-o'; $fasize='1.3em'; }
if ($picto == 'on') { $fakey = 'fa-check-square-o'; $fasize='1.3em'; }
$enabledisablehtml='';
- $enabledisablehtml.='
';
+ $enabledisablehtml.='';
if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $enabledisablehtml.=$titlealt;
$enabledisablehtml.=' ';
return $enabledisablehtml;
@@ -3647,7 +3651,7 @@ function load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png',
$return.= "\n";
$return.= '';
- if ($picto) $return.= ''.img_picto('',$picto, 'class="valignmiddle" id="pictotitle"', $pictoisfullpath).' ';
+ if ($picto) $return.= ''.img_picto('',$picto, 'class="valignmiddle widthpictotitle" id="pictotitle"', $pictoisfullpath).' ';
$return.= '';
$return.= ''.$titre.'
';
$return.= ' ';
@@ -6649,6 +6653,28 @@ function natural_search($fields, $value, $mode=0, $nofirstand=0)
return $res;
}
+/**
+ * Return string with full Url
+ *
+ * @param Object $object Object
+ * @return string Url string
+ */
+function showDirectDownloadLink($object)
+{
+ global $conf, $langs;
+
+ $out='';
+ $url = $object->getLastMainDocLink($object->element);
+
+ if ($url)
+ {
+ $out.= img_picto('','object_globe.png').' '.$langs->trans("DirectDownloadLink").' ';
+ $out.= ' ';
+ $out.= ajax_autoselect("directdownloadlink", 0);
+ }
+ return $out;
+}
+
/**
* Return the filename of file to get the thumbs
*
diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
index 7697c4e56a9..e699758de99 100644
--- a/htdocs/core/lib/functions2.lib.php
+++ b/htdocs/core/lib/functions2.lib.php
@@ -1607,7 +1607,7 @@ function getListOfModels($db,$type,$maxfilenamelength=0)
if (is_dir($tmpdir))
{
// all type of template is allowed
- $tmpfiles=dol_dir_list($tmpdir, 'files', 0, '', '', 'name', SORT_ASC, 0);
+ $tmpfiles=dol_dir_list($tmpdir, 'files', 0, '', '', 'name', SORT_ASC, 0);
if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles);
}
}
@@ -2193,18 +2193,18 @@ function cartesianArray(array $input) {
function getModuleDirForApiClass($module)
{
$moduledirforclass=$module;
+ if ($moduledirforclass != 'api') $moduledirforclass = preg_replace('/api$/i','',$moduledirforclass);
- if (in_array($module, array('login', 'access', 'status', 'documents'))) {
+ if ($module == 'contracts') {
+ $moduledirforclass = 'contrat';
+ }
+ elseif (in_array($module, array('login', 'setup', 'access', 'status', 'documents'))) {
$moduledirforclass = 'api';
}
- if (preg_match('/^dictionary/', $module)) {
- $moduledirforclass = 'api';
- }
-
- if ($module == 'contact' || $module == 'contacts' || $module == 'customer' || $module == 'thirdparty' || $module == 'thirdparties') {
+ elseif ($module == 'contact' || $module == 'contacts' || $module == 'customer' || $module == 'thirdparty' || $module == 'thirdparties') {
$moduledirforclass = 'societe';
}
- if ($module == 'propale' || $module == 'proposals') {
+ elseif ($module == 'propale' || $module == 'proposals') {
$moduledirforclass = 'comm/propal';
}
elseif ($module == 'agenda' || $module == 'agendaevents') {
@@ -2237,6 +2237,9 @@ function getModuleDirForApiClass($module)
elseif ($module == 'stock' || $module == 'stockmovements' || $module == 'warehouses') {
$moduledirforclass = 'product/stock';
}
+ elseif ($module == 'supplierproposals' || $module == 'supplierproposal' || $module == 'supplier_proposal') {
+ $moduledirforclass = 'supplier_proposal';
+ }
elseif ($module == 'fournisseur' || $module == 'supplierinvoices' || $module == 'supplierorders') {
$moduledirforclass = 'fourn';
}
diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php
index c526d57bee0..e953a8018cb 100644
--- a/htdocs/core/lib/security2.lib.php
+++ b/htdocs/core/lib/security2.lib.php
@@ -454,18 +454,21 @@ function getRandomPassword($generic=false)
$uppercase = "ASDFGHJKLZXCVBNMQWERTYUIOP";
$numbers = "1234567890";
$randomCode = "";
+ $nbofchar = round($length/3);
+ $nbofcharlast = ($length - 2*$nbofchar);
+ var_dump($nbofchar.'-'.$nbofcharlast);
if (function_exists('random_int')) // Cryptographic random
{
$max = strlen($lowercase) - 1;
- for ($x = 0; $x < abs($length/3); $x++) {
+ for ($x = 0; $x < $nbofchar; $x++) {
$randomCode .= $lowercase{random_int(0, $max)};
}
$max = strlen($uppercase) - 1;
- for ($x = 0; $x < abs($length/3); $x++) {
+ for ($x = 0; $x < $nbofchar; $x++) {
$randomCode .= $uppercase{random_int(0, $max)};
}
$max = strlen($numbers) - 1;
- for ($x = 0; $x < abs($length/3); $x++) {
+ for ($x = 0; $x < $nbofcharlast; $x++) {
$randomCode .= $numbers{random_int(0, $max)};
}
@@ -474,15 +477,15 @@ function getRandomPassword($generic=false)
else // Old platform, non cryptographic random
{
$max = strlen($lowercase) - 1;
- for ($x = 0; $x < abs($length/3); $x++) {
+ for ($x = 0; $x < $nbofchar; $x++) {
$randomCode .= $lowercase{mt_rand(0, $max)};
}
$max = strlen($uppercase) - 1;
- for ($x = 0; $x < abs($length/3); $x++) {
+ for ($x = 0; $x < $nbofchar; $x++) {
$randomCode .= $uppercase{mt_rand(0, $max)};
}
$max = strlen($numbers) - 1;
- for ($x = 0; $x < abs($length/3); $x++) {
+ for ($x = 0; $x < $nbofcharlast; $x++) {
$randomCode .= $numbers{mt_rand(0, $max)};
}
diff --git a/htdocs/core/lib/tax.lib.php b/htdocs/core/lib/tax.lib.php
index 6fbfbec3bf6..400ed453004 100644
--- a/htdocs/core/lib/tax.lib.php
+++ b/htdocs/core/lib/tax.lib.php
@@ -528,20 +528,16 @@ function tax_by_date($type, $db, $y, $q, $date_start, $date_end, $modetax, $dire
$sql='';
// Count on payments date
- $sql = "SELECT e.rowid, d.product_type as dtype, e.rowid as facid, d.$f_rate as rate, d.total_ht as total_ht, d.total_ttc as total_ttc, d.total_tva as total_vat, e.note_private as descr,";
+ $sql = "SELECT d.rowid, d.product_type as dtype, e.rowid as facid, d.$f_rate as rate, d.total_ht as total_ht, d.total_ttc as total_ttc, d.total_tva as total_vat, e.note_private as descr,";
$sql .=" d.total_localtax1 as total_localtax1, d.total_localtax2 as total_localtax2, ";
$sql.= " e.date_debut as date_start, e.date_fin as date_end,";
- $sql.= " e.ref as facnum, e.total_ttc as ftotal_ttc, e.date_create, s.nom as company_name, s.rowid as company_id, d.fk_c_type_fees as type,";
+ $sql.= " e.ref as facnum, e.total_ttc as ftotal_ttc, e.date_create, d.fk_c_type_fees as type,";
$sql.= " p.fk_bank as payment_id, p.amount as payment_amount, p.rowid as pid, e.ref as pref";
- $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,";
- $sql.= " ".MAIN_DB_PREFIX."expensereport_det as d,";
- $sql.= " ".MAIN_DB_PREFIX."expensereport as e,";
- $sql.= " ".MAIN_DB_PREFIX."payment_expensereport as p";
+ $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as e ";
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."expensereport_det as d ON d.fk_expensereport = e.rowid ";
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."payment_expensereport as p ON p.fk_expensereport = e.rowid ";
$sql.= " WHERE e.entity = " . $conf->entity;
- $sql.= " AND e.fk_statut in (6)";
- $sql.= " AND e.rowid = p.fk_expensereport";
- $sql.= " AND s.rowid = e.entity";
- $sql.= " AND d.fk_expensereport = e.rowid";
+ $sql.= " AND e.fk_statut in (6)";
if ($y && $m)
{
$sql.= " AND p.datep >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
@@ -591,8 +587,8 @@ function tax_by_date($type, $db, $y, $q, $date_start, $date_end, $modetax, $dire
$list[$assoc['rate']]['dtotal_ttc'][] = $assoc['total_ttc'];
$list[$assoc['rate']]['dtype'][] = 'ExpenseReportPayment';
$list[$assoc['rate']]['datef'][] = $assoc['datef'];
- $list[$assoc['rate']]['company_name'][] = $assoc['company_name'];
- $list[$assoc['rate']]['company_id'][] = $assoc['company_id'];
+ $list[$assoc['rate']]['company_name'][] = '';
+ $list[$assoc['rate']]['company_id'][] = '';
$list[$assoc['rate']]['ddate_start'][] = $db->jdate($assoc['date_start']);
$list[$assoc['rate']]['ddate_end'][] = $db->jdate($assoc['date_end']);
diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
index 1810e32868f..9a344ef0355 100644
--- a/htdocs/core/lib/website.lib.php
+++ b/htdocs/core/lib/website.lib.php
@@ -34,6 +34,8 @@
function dolWebsiteReplacementOfLinks($website, $content)
{
// Replace php code. Note $content may come from database and does not contains body tags.
+
+ $content = preg_replace('/value="<\?php((?!\?>).)*\?>\n*/ims', 'value="...php..."', $content);
$content = preg_replace('/<\?php((?!\?>).)*\?>\n*/ims', '...php... ', $content);
// Replace relative link / with dolibarr URL
@@ -192,127 +194,6 @@ function dolIncludeHtmlContent($contentfile)
$includehtmlcontentopened--;
}
-/**
- * Generate a zip with all data of web site.
- *
- * @param Website $website Object website
- * @return string Path to file with zip
- */
-function exportWebSite($website)
-{
- global $db, $conf;
-
- dol_mkdir($conf->website->dir_temp);
- $srcdir = $conf->website->dir_output.'/'.$website->ref;
- $destdir = $conf->website->dir_temp.'/'.$website->ref;
-
- $arrayreplacement=array();
-
- dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacement);
-
- $srcdir = DOL_DATA_ROOT.'/medias/images/'.$website->ref;
- $destdir = $conf->website->dir_temp.'/'.$website->ref.'/medias/images/'.$website->ref;
-
- dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacement);
-
- // Build sql file
- dol_mkdir($conf->website->dir_temp.'/'.$website->ref.'/export');
-
- $filesql = $conf->website->dir_temp.'/'.$website->ref.'/export/pages.sql';
- $fp = fopen($filesql,"w");
-
- $objectpages = new WebsitePage($db);
- $listofpages = $objectpages->fetchAll($website->id);
-
- // Assign ->newid and ->newfk_page
- $i=1;
- foreach($listofpages as $pageid => $objectpageold)
- {
- $objectpageold->newid=$i;
- $i++;
- }
- $i=1;
- foreach($listofpages as $pageid => $objectpageold)
- {
- // Search newid
- $newfk_page=0;
- foreach($listofpages as $pageid2 => $objectpageold2)
- {
- if ($pageid2 == $objectpageold->fk_page)
- {
- $newfk_page = $objectpageold2->newid;
- break;
- }
- }
- $objectpageold->newfk_page=$newfk_page;
- $i++;
- }
- foreach($listofpages as $pageid => $objectpageold)
- {
- $line = 'INSERT INTO llx_website_page(rowid, fk_page, fk_website, pageurl, title, description, keyword, status, date_creation, tms, lang, import_key, grabbed_from, content)';
- $line.= " VALUES(";
- $line.= $objectpageold->newid."+__MAXROWID__, ";
- $line.= ($objectpageold->newfk_page ? $db->escape($objectpageold->newfk_page)."+__MAXROWID__" : "null").", ";
- $line.= "__WEBSITE_ID__, ";
- $line.= "'".$db->escape($objectpageold->pageurl)."', ";
- $line.= "'".$db->escape($objectpageold->title)."', ";
- $line.= "'".$db->escape($objectpageold->description)."', ";
- $line.= "'".$db->escape($objectpageold->keyword)."', ";
- $line.= "'".$db->escape($objectpageold->status)."', ";
- $line.= "'".$db->idate($objectpageold->date_creation)."', ";
- $line.= "'".$db->idate($objectpageold->date_modification)."', ";
- $line.= "'".$db->escape($objectpageold->lang)."', ";
- $line.= ($objectpageold->import_key ? "'".$db->escape($objectpageold->import_key)."'" : "null").", ";
- $line.= "'".$db->escape($objectpageold->grabbed_from)."', ";
- $line.= "'".$db->escape($objectpageold->content)."'";
- $line.= ");";
- $line.= "\n";
- fputs($fp, $line);
- }
-
- fclose($fp);
- if (! empty($conf->global->MAIN_UMASK))
- @chmod($filesql, octdec($conf->global->MAIN_UMASK));
-
- // Build zip file
- $filedir = $conf->website->dir_temp.'/'.$website->ref;
- $fileglob = $conf->website->dir_temp.'/'.$website->ref.'/export/website_'.$website->ref.'-*.zip';
- $filename = $conf->website->dir_temp.'/'.$website->ref.'/export/website_'.$website->ref.'-'.dol_print_date(dol_now(),'dayhourlog').'.zip';
-
- dol_delete_file($fileglob, 0);
- dol_compress_file($filedir, $filename, 'zip');
-
- return $filename;
-}
-
-
-/**
- * Open a zip with all data of web site and load it into database.
- *
- * @param string $pathtofile Path of zip file
- * @return int <0 if KO, >0 if OK
- */
-function importWebSite($pathtofile)
-{
- global $db;
-
- $result = 0;
-
- $filename = basename($pathtofile);
- if (! preg_match('/^website_(.*)-(.*)$/', $filename, $reg))
- {
- $this->errors[]='Bad format for filename '.$filename.'. Must be website_XXX-VERSION.';
- return -1;
- }
-
- $websitecode = $reg[1];
-
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."website(ref, entity, description, status) values('".$websitecode."', ".$conf->entity.", 'Portal to sell your SaaS. Do not remove this entry.', 1)";
- $resql = $db->query($sql);
-
-
- return $result;
-}
/**
diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php
index 96f0dca04fa..d4ffc513521 100644
--- a/htdocs/core/modules/import/import_csv.modules.php
+++ b/htdocs/core/modules/import/import_csv.modules.php
@@ -54,7 +54,7 @@ class ImportCsv extends ModeleImports
var $cacheconvert=array(); // Array to cache list of value found after a convertion
var $cachefieldtable=array(); // Array to cache list of value found into fields@tables
-
+
var $nbinsert = 0; // # of insert done during the import
var $nbupdate = 0; // # of update done during the import
@@ -170,7 +170,7 @@ class ImportCsv extends ModeleImports
return $ret;
}
-
+
/**
* Return nb of records. File must be closed.
*
@@ -181,7 +181,7 @@ class ImportCsv extends ModeleImports
{
return dol_count_nb_of_line($file);
}
-
+
/**
* Input header line from file
@@ -269,7 +269,7 @@ class ImportCsv extends ModeleImports
* @param Object $objimport Object import (contains objimport->array_import_tables, objimport->array_import_fields, objimport->array_import_convertvalue, ...)
* @param int $maxfields Max number of fields to use
* @param string $importid Import key
- * @param array $updatekeys Array of keys to use to try to do update
+ * @param array $updatekeys Array of keys to use to try to do an update first before insert. This field are defined into the module descriptor.
* @return int <0 if KO, >0 if OK
*/
function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$maxfields,$importid,$updatekeys)
@@ -375,7 +375,7 @@ class ImportCsv extends ModeleImports
if (! is_numeric($newval) && $newval != '' && ! preg_match('/^id:/i',$newval)) $isidorref='ref';
$newval=preg_replace('/^(id|ref):/i','',$newval); // Remove id: or ref: that was used to force if field is id or ref
//print 'Val is now '.$newval.' and is type '.$isidorref." \n";
-
+
if ($isidorref == 'ref') // If value into input import file is a ref, we apply the function defined into descriptor
{
$file=(empty($objimport->array_import_convertvalue[0][$val]['classfile'])?$objimport->array_import_convertvalue[0][$val]['file']:$objimport->array_import_convertvalue[0][$val]['classfile']);
@@ -478,9 +478,9 @@ class ImportCsv extends ModeleImports
}
if (is_numeric($defaultref) && $defaultref <= 0) $defaultref='';
$newval=$defaultref;
- }
-
-
+ }
+
+
elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='numeric')
{
$newval = price2num($newval);
@@ -588,11 +588,12 @@ class ImportCsv extends ModeleImports
{
$updatedone = false;
$insertdone = false;
+
if (!empty($updatekeys)) {
// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
if (empty($lastinsertid)) {
$sqlSelect = 'SELECT rowid FROM '.$tablename;
-
+
$data = array_combine($listfields, $listvalues);
$where = array();
$filters = array();
@@ -603,7 +604,7 @@ class ImportCsv extends ModeleImports
$filters[] = $col.' = '.$data[$key];
}
$sqlSelect.= ' WHERE '.implode(' AND ', $where);
-
+
$resql=$this->db->query($sqlSelect);
if($resql) {
$res = $this->db->fetch_object($resql);
@@ -626,23 +627,23 @@ class ImportCsv extends ModeleImports
$error++;
}
}
-
+
if (!empty($lastinsertid)) {
// Build SQL UPDATE request
$sqlstart = 'UPDATE '.$tablename;
-
+
$data = array_combine($listfields, $listvalues);
$set = array();
foreach ($data as $key => $val) {
$set[] = $key.' = '.$val;
}
$sqlstart.= ' SET '.implode(', ', $set);
-
+
if(empty($keyfield)) $keyfield = 'rowid';
$sqlend = ' WHERE '.$keyfield.' = '.$lastinsertid;
-
+
$sql = $sqlstart.$sqlend;
-
+
// Run update request
$resql=$this->db->query($sql);
if($resql) {
@@ -667,14 +668,14 @@ class ImportCsv extends ModeleImports
if (! empty($tablewithentity_cache[$tablename])) {
$sqlstart.= ', entity';
$sqlend.= ', '.$conf->entity;
- }
+ }
if (! empty($objimport->array_import_tables_creator[0][$alias])) {
$sqlstart.= ', '.$objimport->array_import_tables_creator[0][$alias];
$sqlend.=', '.$user->id;
}
$sql = $sqlstart.$sqlend.')';
dol_syslog("import_csv.modules", LOG_DEBUG);
-
+
// Run insert request
if ($sql)
{
diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php
index eff3b8f8b21..d4c97deecf0 100644
--- a/htdocs/core/modules/import/import_xlsx.modules.php
+++ b/htdocs/core/modules/import/import_xlsx.modules.php
@@ -54,10 +54,10 @@ class ImportXlsx extends ModeleImports
var $cacheconvert=array(); // Array to cache list of value found after a convertion
var $cachefieldtable=array(); // Array to cache list of value found into fields@tables
-
+
var $workbook; // temporary import file
var $record; // current record
- var $headers;
+ var $headers;
/**
@@ -95,7 +95,7 @@ class ImportXlsx extends ModeleImports
if (preg_match('/^societe_/',$datatoimport)) $this->thirpartyobject=new Societe($this->db);
}
-
+
/**
* Output header of an example file for this format
*
@@ -136,17 +136,18 @@ class ImportXlsx extends ModeleImports
*/
function write_title_example($outputlangs,$headerlinefields)
{
- global $conf;
- $this->workbook->getActiveSheet()->getStyle('1')->getFont()->setBold(true);
- $this->workbook->getActiveSheet()->getStyle('1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
+ global $conf;
+ $this->workbook->getActiveSheet()->getStyle('1')->getFont()->setBold(true);
+ $this->workbook->getActiveSheet()->getStyle('1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
+
+ $col = 0;
+ foreach($headerlinefields as $field) {
+ $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, 1, $outputlangs->transnoentities($field));
+ // set autowidth
+ //$this->workbook->getActiveSheet()->getColumnDimension($this->column2Letter($col + 1))->setAutoSize(true);
+ $col++;
+ }
- $col = 0;
- foreach($headerlinefields as $field) {
- $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, 1, $outputlangs->transnoentities($field));
- // set autowidth
- //$this->workbook->getActiveSheet()->getColumnDimension($this->column2Letter($col + 1))->setAutoSize(true);
- $col++;
- }
return ''; // final output will be generated in footer
}
@@ -159,13 +160,14 @@ class ImportXlsx extends ModeleImports
*/
function write_record_example($outputlangs,$contentlinevalues)
{
- $col = 0;
- $row = 2;
- foreach($contentlinevalues as $cell) {
- $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, $row, $cell);
- $col++;
- }
- return ''; // final output will be generated in footer
+ $col = 0;
+ $row = 2;
+ foreach($contentlinevalues as $cell) {
+ $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, $row, $cell);
+ $col++;
+ }
+
+ return ''; // final output will be generated in footer
}
/**
@@ -177,15 +179,15 @@ class ImportXlsx extends ModeleImports
function write_footer_example($outputlangs)
{
// return te file content as a string
- $tempfile = tempnam(sys_get_temp_dir(), 'dol');
- $objWriter = new PHPExcel_Writer_Excel2007($this->workbook);
- $objWriter->save($tempfile);
- $this->workbook->disconnectWorksheets();
- unset($this->workbook);
+ $tempfile = tempnam(sys_get_temp_dir(), 'dol');
+ $objWriter = new PHPExcel_Writer_Excel2007($this->workbook);
+ $objWriter->save($tempfile);
+ $this->workbook->disconnectWorksheets();
+ unset($this->workbook);
- $content = file_get_contents($tempfile);
- unlink($tempfile);
- return $content;
+ $content = file_get_contents($tempfile);
+ unlink($tempfile);
+ return $content;
}
@@ -211,10 +213,10 @@ class ImportXlsx extends ModeleImports
return $ret;
}
-
+
/**
* Return nb of records. File must be closed.
- *
+ *
* @param string $file Path of filename
* @return int <0 if KO, >=0 if OK
*/
@@ -222,15 +224,15 @@ class ImportXlsx extends ModeleImports
{
$reader = new PHPExcel_Reader_Excel2007();
$this->workbook = $reader->load($file);
-
- $rowcount = $this->workbook->getActiveSheet()->getHighestDataRow();
-
- $this->workbook->disconnectWorksheets();
- unset($this->workbook);
-
+
+ $rowcount = $this->workbook->getActiveSheet()->getHighestDataRow();
+
+ $this->workbook->disconnectWorksheets();
+ unset($this->workbook);
+
return $rowcount;
- }
-
+ }
+
/**
* Input header line from file
@@ -292,7 +294,7 @@ class ImportXlsx extends ModeleImports
* @param Object $objimport Object import (contains objimport->array_import_tables, objimport->array_import_fields, objimport->array_import_convertvalue, ...)
* @param int $maxfields Max number of fields to use
* @param string $importid Import key
- * @param array $updatekeys Array of keys to use to try to do update
+ * @param array $updatekeys Array of keys to use to try to do an update first before insert. This field are defined into the module descriptor.
* @return int <0 if KO, >0 if OK
*/
// What is this doing here ? it is common to all imports, is should be in the parent class
@@ -399,7 +401,7 @@ class ImportXlsx extends ModeleImports
if (! is_numeric($newval) && $newval != '' && ! preg_match('/^id:/i',$newval)) $isidorref='ref';
$newval=preg_replace('/^(id|ref):/i','',$newval); // Remove id: or ref: that was used to force if field is id or ref
//print 'Val is now '.$newval.' and is type '.$isidorref." \n";
-
+
if ($isidorref == 'ref') // If value into input import file is a ref, we apply the function defined into descriptor
{
$file=(empty($objimport->array_import_convertvalue[0][$val]['classfile'])?$objimport->array_import_convertvalue[0][$val]['file']:$objimport->array_import_convertvalue[0][$val]['classfile']);
@@ -502,9 +504,9 @@ class ImportXlsx extends ModeleImports
}
if (is_numeric($defaultref) && $defaultref <= 0) $defaultref='';
$newval=$defaultref;
- }
-
-
+ }
+
+
elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='numeric')
{
$newval = price2num($newval);
@@ -616,7 +618,7 @@ class ImportXlsx extends ModeleImports
// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
if (empty($lastinsertid)) {
$sqlSelect = 'SELECT rowid FROM '.$tablename;
-
+
$data = array_combine($listfields, $listvalues);
$where = array();
$filters = array();
@@ -627,7 +629,7 @@ class ImportXlsx extends ModeleImports
$filters[] = $col.' = '.$data[$key];
}
$sqlSelect.= ' WHERE '.implode(' AND ', $where);
-
+
$resql=$this->db->query($sqlSelect);
if($resql) {
$res = $this->db->fetch_object($resql);
@@ -650,23 +652,23 @@ class ImportXlsx extends ModeleImports
$error++;
}
}
-
+
if (!empty($lastinsertid)) {
// Build SQL UPDATE request
$sqlstart = 'UPDATE '.$tablename;
-
+
$data = array_combine($listfields, $listvalues);
$set = array();
foreach ($data as $key => $val) {
$set[] = $key.' = '.$val;
}
$sqlstart.= ' SET '.implode(', ', $set);
-
+
if(empty($keyfield)) $keyfield = 'rowid';
$sqlend = ' WHERE '.$keyfield.' = '.$lastinsertid;
-
+
$sql = $sqlstart.$sqlend;
-
+
// Run update request
$resql=$this->db->query($sql);
if($resql) {
@@ -691,14 +693,14 @@ class ImportXlsx extends ModeleImports
if (! empty($tablewithentity_cache[$tablename])) {
$sqlstart.= ', entity';
$sqlend.= ', '.$conf->entity;
- }
+ }
if (! empty($objimport->array_import_tables_creator[0][$alias])) {
$sqlstart.= ', '.$objimport->array_import_tables_creator[0][$alias];
$sqlend.=', '.$user->id;
}
$sql = $sqlstart.$sqlend.')';
dol_syslog("import_xlsx.modules", LOG_DEBUG);
-
+
// Run insert request
if ($sql)
{
diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php
index 79541c10105..5f44b843e1f 100644
--- a/htdocs/core/modules/modProduct.class.php
+++ b/htdocs/core/modules/modProduct.class.php
@@ -308,7 +308,6 @@ class modProduct extends DolibarrModules
if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.recuperableonly'=>'NPR'));
if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax1_tx'=>'LT1', 'sp.localtax1_type'=>'LT1Type'));
if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax2_tx'=>'LT2', 'sp.localtax2_type'=>'LT2Type'));
-
$this->import_convertvalue_array[$r]=array(
'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')
@@ -352,30 +351,19 @@ class modProduct extends DolibarrModules
if (! empty($conf->global->MAIN_MULTILANGS))
{
$r++;
- /* FIXME Must be a dedicated import profil. Not working yet
- $this->import_code[$r]=$this->rights_class.'_multiprice';
- $this->import_label[$r]="ProductTranslations";
+ $this->import_code[$r]=$this->rights_class.'_languages';
+ $this->import_label[$r]="ProductsOrServicesTranslations";
$this->import_icon[$r]=$this->picto;
$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]['l']=MAIN_DB_PREFIX.'product_lang';
+ $this->import_tables_array[$r]=array('l'=>MAIN_DB_PREFIX.'product_lang');
// multiline translation, one line per translation
- $this->import_fields_array[$r]['l.lang']='Language';
- $this->import_fields_array[$r]['l.label']='TranslatedLabel';
- $this->import_fields_array[$r]['l.description']='TranslatedDescription';
- $this->import_fields_array[$r]['l.note']='TranslatedNote';
- $this->import_examplevalues_array[$r]['l.lang']='en_US';
- */
- // single line translation, one column per translation
- /*
- foreach($langs as $l) {
- $this->import_tables_array[$r][$l] = MAIN_DB_PREFIX.'product_lang';
- $this->import_fields_array[$r][$l.'.label']=$l.'_label';
- $this->import_fields_array[$r][$l.'.description']=$l.'_description';
- $this->import_fields_array[$r][$l.'.note']=$l.'_note';
- $this->import_fieldshidden_array[$r][$l.'.lang']="'$l'";
- $this->import_fieldshidden_array[$r][$l.'.fk_product']='lastrowid-'.MAIN_DB_PREFIX.'product';
- }
- */
+ $this->import_fields_array[$r]=array('l.fk_product'=>'Ref', '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');
}
}
diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php
index 961b031e232..eed1008ca34 100644
--- a/htdocs/core/modules/modService.class.php
+++ b/htdocs/core/modules/modService.class.php
@@ -133,8 +133,8 @@ class modService extends DolibarrModules
// Menus
//-------
$this->menu = 1; // This module add menu entries. They are coded into menu manager.
-
-
+
+
// Exports
//--------
$r=0;
@@ -315,6 +315,24 @@ class modService extends DolibarrModules
'pr.tva_tx'=>'19.6',
'pr.date_price'=>'2013-04-10');
}
+
+ if (! empty($conf->global->MAIN_MULTILANGS))
+ {
+ $r++;
+ $this->import_code[$r]=$this->rights_class.'_languages';
+ $this->import_label[$r]="ProductsOrServicesTranslations";
+ $this->import_icon[$r]=$this->picto;
+ $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]['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');
+ }
}
}
diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php
index 3ebf3f22d02..88494be7e04 100644
--- a/htdocs/cron/class/cronjob.class.php
+++ b/htdocs/cron/class/cronjob.class.php
@@ -1060,7 +1060,14 @@ class Cronjob extends CommonObject
$outputfile=$outputdir.'/cronjob.'.$userlogin.'.out'; // File used with popen method
// Execute a CLI
- $retval = $this->executeCLI($this->command, $outputfile);
+ include_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
+ $utils = new Utils($db);
+ $arrayresult = $utils->executeCLI($this->command, $outputfile);
+
+ $retval = $arrayresult['result'];
+ $this->error = $arrayresult['error'];
+ $this->lastoutput = $arrayresult['output'];
+ $this->lastresult = $arrayresult['result'];
}
}
@@ -1082,82 +1089,6 @@ class Cronjob extends CommonObject
}
- /**
- * Execute a CLI command.
- * this->error, this->lastoutput, this->lastresult are also set.
- *
- * @param string $command Command line
- * @param string $outputfile Output file
- * @param int $execmethod 0=Use default method, 1=Use the PHP 'exec', 2=Use the 'popen' method
- * @return int Retval
- */
- function executeCLI($command, $outputfile, $execmethod=0)
- {
- global $conf, $langs;
-
- $retval = 0;
-
- $command=escapeshellcmd($command);
- $command.=" 2>&1";
-
- if (! empty($conf->global->MAIN_EXEC_USE_POPEN)) $execmethod=$conf->global->MAIN_EXEC_USE_POPEN;
- if (empty($execmethod)) $execmethod=1;
- //$execmethod=1;
-
- dol_syslog(get_class($this)."::executeCLI execmethod=".$execmethod." system:".$command, LOG_DEBUG);
- $output_arr=array();
-
- if ($execmethod == 1)
- {
- exec($command, $output_arr, $retval);
- if ($retval != 0)
- {
- $langs->load("errors");
- dol_syslog(get_class($this)."::executeCLI retval after exec=".$retval, LOG_ERR);
- $this->error = 'Error '.$retval;
- $this->lastoutput = ''; // Will be filled later from $output_arr
- $this->lastresult = $retval;
- $retval = $this->lastresult;
- $error++;
- }
- }
- if ($execmethod == 2) // With this method, there is no way to get the return code, only output
- {
- $ok=0;
- $handle = fopen($outputfile, 'w+b');
- if ($handle)
- {
- dol_syslog(get_class($this)."::executeCLI run command ".$command);
- $handlein = popen($command, 'r');
- while (!feof($handlein))
- {
- $read = fgets($handlein);
- fwrite($handle,$read);
- $output_arr[]=$read;
- }
- pclose($handlein);
- fclose($handle);
- }
- if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
- }
-
- // Update with result
- if (is_array($output_arr) && count($output_arr)>0)
- {
- foreach($output_arr as $val)
- {
- $this->lastoutput.=$val.($execmethod == 2 ? '' : "\n");
- }
- }
-
- $this->lastresult=$retval;
-
- dol_syslog(get_class($this)."::executeCLI output_arr:".var_export($output_arr,true)." lastoutput=".$this->lastoutput." lastresult=".$this->lastresult, LOG_DEBUG);
-
- return $retval;
- }
-
-
/**
* Reprogram a job
*
diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php
index 77fb16f5afd..56f9b692e94 100644
--- a/htdocs/ecm/index.php
+++ b/htdocs/ecm/index.php
@@ -14,13 +14,14 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
+ * You can call this page with param module=medias to get a filemanager for medias.
*/
/**
* \file htdocs/ecm/index.php
* \ingroup ecm
* \brief Main page for ECM section area
- * \author Laurent Destailleur
*/
require '../main.inc.php';
@@ -31,14 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php';
require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
// Load traductions files
-$langs->load("ecm");
-$langs->load("companies");
-$langs->load("other");
-$langs->load("users");
-$langs->load("orders");
-$langs->load("propal");
-$langs->load("bills");
-$langs->load("contracts");
+$langs->loadLangs(array("ecm","companies","other","users","orders","propal","bills","contracts"));
// Security check
if ($user->societe_id) $socid=$user->societe_id;
@@ -48,7 +42,6 @@ $result = restrictedArea($user, 'ecm', 0);
$socid=GETPOST('socid','int');
$action=GETPOST('action','aZ09');
$section=GETPOST('section','int')?GETPOST('section','int'):GETPOST('section_id','int');
-$module=GETPOST('module','alpha');
if (! $section) $section=0;
$section_dir=GETPOST('section_dir','alpha');
@@ -145,7 +138,6 @@ if ($action == 'confirm_deletefile')
{
// GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections.
//var_dump(GETPOST('urlfile'));exit;
- $langs->load("other");
$upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:'');
$file = $upload_dir . "/" . GETPOST('urlfile','alpha'); // Do not use urldecode here ($_GET and $_POST are already decoded by PHP).
@@ -324,31 +316,29 @@ if ($action == 'refreshmanual')
//print $_SESSION["dol_screenheight"];
$maxheightwin=(isset($_SESSION["dol_screenheight"]) && $_SESSION["dol_screenheight"] > 466)?($_SESSION["dol_screenheight"]-136):660; // Also into index_auto.php file
+$moreheadcss='';
+$moreheadjs='';
+
//$morejs=array();
$morejs=array('includes/jquery/plugins/blockUI/jquery.blockUI.js','core/js/blockUI.js'); // Used by ecm/tpl/enabledfiletreeajax.tpl.pgp
-if (empty($conf->global->MAIN_ECM_DISABLE_JS)) $morejs[]="/includes/jquery/plugins/jqueryFileTree/jqueryFileTree.js";
+if (empty($conf->global->MAIN_ECM_DISABLE_JS)) $morejs[]="includes/jquery/plugins/jqueryFileTree/jqueryFileTree.js";
+$moreheadjs.=''."\n";
llxHeader($moreheadcss.$moreheadjs,$langs->trans("ECMArea"),'','','','',$morejs,'',0,0);
+$head = ecm_prepare_dasboard_head('');
+dol_fiche_head($head, 'index', $langs->trans("ECMArea").' - '.$langs->trans("ECMFileManager"), -1, '');
-// Add sections to manage
-$rowspan=0;
-$sectionauto=array();
-// Confirm remove file (for non javascript users)
-if ($action == 'delete' && empty($conf->use_javascript_ajax))
-{
- print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile','','',1);
+// Add filemanager component
+$module='ecm';
+include DOL_DOCUMENT_ROOT.'/ecm/tpl/filemanager.tpl.php';
-}
-
-if ($module != 'medias')
-{
- $head = ecm_prepare_dasboard_head('');
- dol_fiche_head($head, 'index', $langs->trans("ECMArea").' - '.$langs->trans("ECMFileManager"), -1, '');
-}
+/*
// Start container of all panels
?>
@@ -443,7 +433,7 @@ if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$acti
{
print ' ';
- // Show filemanager tree
+ // Show filemanager tree (will be filled by call of ajax enablefiletreeajax.tpl.php that execute ajaxdirtree.php)
print '
';
if ($action == 'deletefile') print $form->formconfirm('eeeee', $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 'deletefile');
@@ -453,164 +443,20 @@ if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$acti
else
{
print ' ';
+
+ if (empty($module)) $module='ecm';
+
+ $_POST['modulepart'] = $module;
+ $_POST['openeddir'] = GETPOST('openeddir');
+ $_POST['dir'] = empty($_POST['dir'])?'/':$_POST['dir'];
+
+ // Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show)
print '';
print ' ';
}
@@ -643,19 +489,15 @@ include_once DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';
use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) {
include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php';
}
+*/
-
+// End of page
+dol_fiche_end();
llxFooter();
diff --git a/htdocs/ecm/index_auto.php b/htdocs/ecm/index_auto.php
index 3fa2bc1dc7a..5a394188c18 100644
--- a/htdocs/ecm/index_auto.php
+++ b/htdocs/ecm/index_auto.php
@@ -31,14 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php';
require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
// Load traductions files
-$langs->load("ecm");
-$langs->load("companies");
-$langs->load("other");
-$langs->load("users");
-$langs->load("orders");
-$langs->load("propal");
-$langs->load("bills");
-$langs->load("contracts");
+$langs->loadLangs(array("ecm","companies","other","users","orders","propal","bills","contracts"));
// Security check
if ($user->societe_id) $socid=$user->societe_id;
@@ -306,10 +299,16 @@ if ($action == 'refreshmanual')
//print $_SESSION["dol_screenheight"];
$maxheightwin=(isset($_SESSION["dol_screenheight"]) && $_SESSION["dol_screenheight"] > 466)?($_SESSION["dol_screenheight"]-136):660; // Also into index.php file
+$moreheadcss='';
+$moreheadjs='';
+
//$morejs=array();
$morejs=array('includes/jquery/plugins/blockUI/jquery.blockUI.js','core/js/blockUI.js'); // Used by ecm/tpl/enabledfiletreeajax.tpl.pgp
-if (empty($conf->global->MAIN_ECM_DISABLE_JS)) $morejs[]="/includes/jquery/plugins/jqueryFileTree/jqueryFileTree.js";
+if (empty($conf->global->MAIN_ECM_DISABLE_JS)) $morejs[]="includes/jquery/plugins/jqueryFileTree/jqueryFileTree.js";
+$moreheadjs.=''."\n";
llxHeader($moreheadcss.$moreheadjs,$langs->trans("ECMArea"),'','','','',$morejs,'',0,0);
@@ -325,6 +324,7 @@ if (! empty($conf->global->ECM_AUTO_TREE_ENABLED))
if (! empty($conf->contrat->enabled)) { $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'contract','test'=>$conf->contrat->enabled, 'label'=>$langs->trans("Contracts"), 'desc'=>$langs->trans("ECMDocsByContracts")); }
if (! empty($conf->commande->enabled)) { $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'order', 'test'=>$conf->commande->enabled, 'label'=>$langs->trans("CustomersOrders"), 'desc'=>$langs->trans("ECMDocsByOrders")); }
if (! empty($conf->facture->enabled)) { $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'invoice', 'test'=>$conf->facture->enabled, 'label'=>$langs->trans("CustomersInvoices"), 'desc'=>$langs->trans("ECMDocsByInvoices")); }
+ if (! empty($conf->supplier_proposal->enabled)) { $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'supplier_proposal', 'test'=>$conf->supplier_proposal->enabled, 'label'=>$langs->trans("SupplierProposals"), 'desc'=>$langs->trans("ECMDocsBySupplierProposals")); }
if (! empty($conf->fournisseur->enabled)) { $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'order_supplier', 'test'=>$conf->fournisseur->enabled, 'label'=>$langs->trans("SuppliersOrders"), 'desc'=>$langs->trans("ECMDocsByOrders")); }
if (! empty($conf->fournisseur->enabled)) { $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'invoice_supplier', 'test'=>$conf->fournisseur->enabled, 'label'=>$langs->trans("SuppliersInvoices"), 'desc'=>$langs->trans("ECMDocsByInvoices")); }
if (! empty($conf->tax->enabled)) { $langs->load("compta"); $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'tax', 'test'=>$conf->tax->enabled, 'label'=>$langs->trans("SocialContributions"), 'desc'=>$langs->trans("ECMDocsBySocialContributions")); }
@@ -334,13 +334,10 @@ if (! empty($conf->global->ECM_AUTO_TREE_ENABLED))
$rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'user', 'test'=>1, 'label'=>$langs->trans("Users"), 'desc'=>$langs->trans("ECMDocsByUsers"));
}
-//print load_fiche_titre($langs->trans("ECMArea").' - '.$langs->trans("ECMFileManager"));
+$head = ecm_prepare_dasboard_head('');
+dol_fiche_head($head, 'index_auto', $langs->trans("ECMArea").' - '.$langs->trans("ECMFileManager"), -1, '');
+
-$helptext1=''; $helptext2='';
-$helptext1.=$langs->trans("ECMAreaDesc");
-$helptext1.=$langs->trans("ECMAreaDesc2");
-$helptext2.=$langs->trans("ECMAreaDesc");
-$helptext2.=$langs->trans("ECMAreaDesc2");
// Confirm remove file (for non javascript users)
if ($action == 'delete' && empty($conf->use_javascript_ajax))
@@ -349,17 +346,6 @@ if ($action == 'delete' && empty($conf->use_javascript_ajax))
}
-//if (! empty($conf->use_javascript_ajax)) $classviewhide='hidden';
-//else $classviewhide='visible';
-$classviewhide='inline-block';
-
-
-
-
-$head = ecm_prepare_dasboard_head('');
-dol_fiche_head($head, 'index_auto', $langs->trans("ECMArea").' - '.$langs->trans("ECMFileManager"), -1, '');
-
-
// Start container of all panels
?>
@@ -381,7 +367,7 @@ print '';
?>
-
+
-
+
use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) {
include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php';
}
+dol_fiche_end();
llxFooter();
diff --git a/htdocs/ecm/search.php b/htdocs/ecm/search.php
index 070acf2d4e1..2f5c921dc78 100644
--- a/htdocs/ecm/search.php
+++ b/htdocs/ecm/search.php
@@ -1,5 +1,5 @@
+/* Copyright (C) 2008-2017 Laurent Destailleur
* Copyright (C) 2008-2009 Regis Houssin
*
* This program is free software; you can redistribute it and/or modify
@@ -19,8 +19,7 @@
/**
* \file htdocs/ecm/index.php
* \ingroup ecm
- * \brief Main page for ECM section area
- * \author Laurent Destailleur
+ * \brief Page to make advanced search into ECM
*/
require '../main.inc.php';
diff --git a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
index 3f19e1d666f..4be1bf1979a 100644
--- a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
+++ b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
@@ -33,7 +33,7 @@ $(document).ready(function() {
$('#filetree').fileTree({
root: '',
- // Ajax called if we click to expand a dir (not a file). Parameter of dir is provided as a POST parameter.
+ // Ajax called if we click to expand a dir (not a file). Parameter 'dir' is provided as a POST parameter by fileTree code.
script: '',
folderEvent: 'click', // 'dblclick'
multiFolder: false },
@@ -93,4 +93,4 @@ function loadandshowpreview(filedirname,section)
}
-
+
diff --git a/htdocs/ecm/tpl/filemanager.tpl.php b/htdocs/ecm/tpl/filemanager.tpl.php
new file mode 100644
index 00000000000..e80e9fd3e83
--- /dev/null
+++ b/htdocs/ecm/tpl/filemanager.tpl.php
@@ -0,0 +1,195 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Output code for the filemanager
+ * $module must be defined ('ecm', 'medias', ...)
+ */
+?>
+
+
+
+
+use_javascript_ajax))
+{
+ print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile','','',1);
+}
+
+// Start container of all panels
+?>
+
+
+
';
+// End top panel, toolbar
+
+?>
+
+
+formconfirm($_SERVER["PHP_SELF"].'?section='.$section, $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$ecmdir->label), 'confirm_deletesection','','',1);
+}
+// End confirm
+
+
+if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$action) || $action == 'delete')
+{
+ print '
'."\n";
+
+ print ''."\n";
+ print ''."\n";
+ print '';
+ print ' '.$langs->trans("ECMSections");
+ print ' ';
+
+ $showonrightsize='';
+
+ // Manual section
+ $htmltooltip=$langs->trans("ECMAreaDesc2");
+
+ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
+ {
+ print '';
+
+ // Show filemanager tree (will be filled by call of ajax enablefiletreeajax.tpl.php that execute ajaxdirtree.php)
+ print '
';
+
+ if ($action == 'deletefile') print $form->formconfirm('eeeee', $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 'deletefile');
+
+ print ' ';
+ }
+ else
+ {
+ print '';
+
+ if (empty($module)) $module='ecm';
+
+ $_POST['modulepart'] = $module;
+ $_POST['openeddir'] = GETPOST('openeddir');
+ $_POST['dir'] = empty($_POST['dir'])?'/':$_POST['dir'];
+
+ // Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show)
+ print '';
+
+ $mode='noajax';
+ $url=DOL_URL_ROOT.'/ecm/index.php';
+ include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirtree.php';
+
+ print '
';
+ print ' ';
+ }
+
+
+ print "
";
+}
+
+
+// End left panel
+?>
+
+
+
+use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) {
+ include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php';
+}
+
+?>
+
diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php
index 25cf644db0f..237d09570d1 100644
--- a/htdocs/fichinter/class/fichinter.class.php
+++ b/htdocs/fichinter/class/fichinter.class.php
@@ -840,85 +840,96 @@ class Fichinter extends CommonObject
$this->db->begin();
+ if (! $error && ! $notrigger)
+ {
+ // Call trigger
+ $result=$this->call_trigger('FICHINTER_DELETE',$user);
+ if ($result < 0) { $error++; $this->db->rollback(); return -1; }
+ // End call triggers
+ }
+
// Delete linked object
- $res = $this->deleteObjectLinked();
- if ($res < 0) $error++;
+ if (! $error)
+ {
+ $res = $this->deleteObjectLinked();
+ if ($res < 0) $error++;
+ }
// Delete linked contacts
- $res = $this->delete_linked_contact();
- if ($res < 0)
+ if (! $error)
{
- $this->error='ErrorFailToDeleteLinkedContact';
- $error++;
+ $res = $this->delete_linked_contact();
+ if ($res < 0)
+ {
+ $this->error='ErrorFailToDeleteLinkedContact';
+ $error++;
+ }
}
- if ($error)
+ if (! $error)
{
- $this->db->rollback();
- return -1;
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
+ $sql.= " WHERE fk_fichinter = ".$this->id;
+
+ $resql = $this->db->query($sql);
+ if (! $resql) $error++;
}
- $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
- $sql.= " WHERE fk_fichinter = ".$this->id;
-
- dol_syslog("Fichinter::delete", LOG_DEBUG);
- if ( $this->db->query($sql) )
+ if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
{
+ // Remove extrafields
+ $res = $this->deleteExtraFields();
+ if ($res < 0) $error++;
+ }
+
+ if (! $error)
+ {
+ // Delete object
$sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
$sql.= " WHERE rowid = ".$this->id;
$sql.= " AND entity = ".$conf->entity;
dol_syslog("Fichinter::delete", LOG_DEBUG);
- if ( $this->db->query($sql) )
+ $resql = $this->db->query($sql);
+ if (! $resql) $error++;
+ }
+
+ if (! $error)
+ {
+ // Remove directory with files
+ $fichinterref = dol_sanitizeFileName($this->ref);
+ if ($conf->ficheinter->dir_output)
{
-
- // Remove directory with files
- $fichinterref = dol_sanitizeFileName($this->ref);
- if ($conf->ficheinter->dir_output)
+ $dir = $conf->ficheinter->dir_output . "/" . $fichinterref ;
+ $file = $conf->ficheinter->dir_output . "/" . $fichinterref . "/" . $fichinterref . ".pdf";
+ if (file_exists($file))
{
- $dir = $conf->ficheinter->dir_output . "/" . $fichinterref ;
- $file = $conf->ficheinter->dir_output . "/" . $fichinterref . "/" . $fichinterref . ".pdf";
- if (file_exists($file))
- {
- dol_delete_preview($this);
+ dol_delete_preview($this);
- if (! dol_delete_file($file,0,0,0,$this)) // For triggers
- {
- $this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
- return 0;
- }
- }
- if (file_exists($dir))
+ if (! dol_delete_file($file,0,0,0,$this)) // For triggers
{
- if (! dol_delete_dir_recursive($dir))
- {
- $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
- return 0;
- }
+ $this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
+ return 0;
}
}
-
- if (! $notrigger)
+ if (file_exists($dir))
{
- // Call trigger
- $result=$this->call_trigger('FICHINTER_DELETE',$user);
- if ($result < 0) { $error++; $this->db->rollback(); return -1; }
- // End call triggers
+ if (! dol_delete_dir_recursive($dir))
+ {
+ $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
+ return 0;
+ }
}
+ }
+ }
- $this->db->commit();
- return 1;
- }
- else
- {
- $this->error=$this->db->lasterror();
- $this->db->rollback();
- return -2;
- }
+ if (! $error)
+ {
+ $this->db->commit();
+ return 1;
}
else
{
- $this->error=$this->db->lasterror();
$this->db->rollback();
return -1;
}
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index e3e29e83335..7f002bc40c0 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -673,9 +673,11 @@ class CommandeFournisseur extends CommonOrder
$linkstart.=$linkclose.'>';
$linkend='';
- if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend);
- if ($withpicto && $withpicto != 2) $result.=' ';
- $result.=$linkstart.$this->ref.$linkend;
+ $result .= $linkstart;
+ if ($withpicto) $result.=img_object(($notooltip?'':$label), $this->picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
+ if ($withpicto != 2) $result.= $this->ref;
+ $result .= $linkend;
+
return $result;
}
@@ -1128,7 +1130,7 @@ class CommandeFournisseur extends CommonOrder
// Clean parameters
if (empty($this->source)) $this->source = 0;
- // Multicurrency (test on $this->multicurrency_tx because we sould take the default rate only if not using origin rate)
+ // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code);
else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
if (empty($this->fk_multicurrency))
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index afaa2e6a60f..15bd4366a29 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -229,7 +229,7 @@ class FactureFournisseur extends CommonInvoice
$amount = $this->amount;
$remise = $this->remise;
- // Multicurrency (test on $this->multicurrency_tx because we sould take the default rate only if not using origin rate)
+ // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code);
else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
if (empty($this->fk_multicurrency))
@@ -1948,8 +1948,11 @@ class FactureFournisseur extends CommonInvoice
$linkstart.=$linkclose.'>';
$linkend='';
- if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend.' ');
- $result.=$linkstart.($max?dol_trunc($ref,$max):$ref).$linkend;
+ $result .= $linkstart;
+ if ($withpicto) $result.=img_object(($notooltip?'':$label), $this->picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
+ if ($withpicto != 2) $result.= ($max?dol_trunc($ref,$max):$ref);
+ $result .= $linkend;
+
return $result;
}
diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php
index 5b3548cc8fb..bcf2c7d99ec 100644
--- a/htdocs/hrm/index.php
+++ b/htdocs/hrm/index.php
@@ -75,6 +75,18 @@ llxHeader('', $langs->trans('HRMArea'));
print load_fiche_titre($langs->trans("HRMArea"),'', 'title_hrm.png');
+
+if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) $setupcompanynotcomplete=1;
+if ( empty($setupcompanynotcomplete))
+{
+ $langs->load("errors");
+ $warnpicto=img_warning($langs->trans("WarningMandatorySetupNotComplete"));
+ print '
';
+
+ exit;
+}
+
+
print '
';
if (! empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is useless due to the global search combo
diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php
index 0847f1c4262..1549e7124e0 100644
--- a/htdocs/imports/import.php
+++ b/htdocs/imports/import.php
@@ -225,7 +225,7 @@ if ($step == 3 && $datatoimport)
$param='&datatoimport='.$datatoimport.'&format='.$format;
if ($excludefirstline) $param.='&excludefirstline='.$excludefirstline;
if ($endatlinenb) $param.='&endatlinenb='.$endatlinenb;
-
+
$file = $conf->import->dir_temp . '/' . GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
$ret=dol_delete_file($file);
if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
@@ -362,7 +362,7 @@ if ($step == 1 || ! $datatoimport)
print '
';
$titleofmodule=$objimport->array_import_module[$key]->getName();
// Special cas for import common to module/services
- if (in_array($objimport->array_import_code[$key], array('produit_supplierprices','produit_multiprice'))) $titleofmodule=$langs->trans("ProductOrService");
+ if (in_array($objimport->array_import_code[$key], array('produit_supplierprices','produit_multiprice','produit_languages'))) $titleofmodule=$langs->trans("ProductOrService");
print $titleofmodule;
print ' ';
//print $value;
@@ -415,7 +415,7 @@ if ($step == 2 && $datatoimport)
print ' ';
$titleofmodule=$objimport->array_import_module[0]->getName();
// Special cas for import common to module/services
- if (in_array($objimport->array_import_code[0], array('produit_supplierprices','produit_multiprice'))) $titleofmodule=$langs->trans("ProductOrService");
+ if (in_array($objimport->array_import_code[0], array('produit_supplierprices','produit_multiprice','produit_languages'))) $titleofmodule=$langs->trans("ProductOrService");
print $titleofmodule;
print ' ';
@@ -429,9 +429,9 @@ if ($step == 2 && $datatoimport)
print '
';
print ' ';
-
+
dol_fiche_end();
-
+
print '
';
print '';
-
+
dol_fiche_end();
-
+
print ' '."\n";
@@ -873,7 +873,7 @@ if ($step == 4 && $datatoimport)
$lefti=1;
foreach ($array_match_file_to_database as $key => $val)
{
-
+
show_elem($fieldssource,$key,$val,$var); // key is field number in source file
//print '> '.$lefti.'-'.$key.'-'.$val;
$listofkeys[$key]=1;
@@ -890,7 +890,7 @@ if ($step == 4 && $datatoimport)
$num=count($fieldssource);
while ($lefti <= $num)
{
-
+
$newkey=getnewkey($fieldssource,$listofkeys);
show_elem($fieldssource,$newkey,'',$var); // key start after field number in source file
//print '> '.$lefti.'-'.$newkey;
@@ -913,7 +913,7 @@ if ($step == 4 && $datatoimport)
print '';
foreach($fieldstarget as $code=>$label)
{
-
+
print '';
$i++;
@@ -1148,7 +1148,7 @@ if ($step == 4 && $datatoimport)
$var=false;
while ($i < $num)
{
-
+
$obj = $db->fetch_object($resql);
print ' ';
print $obj->label;
@@ -1213,16 +1213,16 @@ if ($step == 5 && $datatoimport)
if ($excludefirstline) $param.='&excludefirstline='.$excludefirstline;
if ($endatlinenb) $param.='&endatlinenb='.$endatlinenb;
if (!empty($updatekeys)) $param.='&updatekeys[]='.implode('&updatekeys[]=', $updatekeys);
-
+
llxHeader('',$langs->trans("NewImport"),'EN:Module_Imports_En|FR:Module_Imports|ES:Módulo_Importaciones');
$head = import_prepare_head($param,5);
-
+
print '';
print ' '; // step 5
print ' '; // step 5
-
+
dol_fiche_head($head, 'step5', $langs->trans("NewImport"), -1);
print '
';
@@ -1235,7 +1235,7 @@ if ($step == 5 && $datatoimport)
print '';
$titleofmodule=$objimport->array_import_module[0]->getName();
// Special cas for import common to module/services
- if (in_array($objimport->array_import_code[0], array('produit_supplierprices','produit_multiprice'))) $titleofmodule=$langs->trans("ProductOrService");
+ if (in_array($objimport->array_import_code[0], array('produit_supplierprices','produit_multiprice','produit_languages'))) $titleofmodule=$langs->trans("ProductOrService");
print $titleofmodule;
print ' ';
@@ -1248,9 +1248,9 @@ if ($step == 5 && $datatoimport)
print '
';
print '';
-
+
print ' ';
-
+
print ''.$langs->trans("InformationOnSourceFile").' ';
print '
';
print '';
@@ -1274,7 +1274,7 @@ if ($step == 5 && $datatoimport)
print htmlentities($enclosure);
print '
';
}
-
+
// File to import
print ''.$langs->trans("FileToImport").' ';
print '';
@@ -1326,7 +1326,7 @@ if ($step == 5 && $datatoimport)
if($action=='launchsimu') {
if (count($updatekeys))
{
- print $form->multiselectarray('updatekeysbis', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '', 'disabled');
+ print $form->multiselectarray('updatekeysbis', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%', 'disabled');
}
else
{
@@ -1351,16 +1351,16 @@ if ($step == 5 && $datatoimport)
print_r($objimport->array_import_updatekeys);
echo '';*/
print ' ';
-
+
print '
';
print '';
-
+
print ' ';
print ''.$langs->trans("InformationOnTargetTables").' ';
print '
';
print '';
-
+
print '
';
//print ''.$langs->trans("InformationOnTargetTables").' ';
@@ -1426,7 +1426,7 @@ if ($step == 5 && $datatoimport)
print '
';
print '
';
-
+
dol_fiche_end();
@@ -1488,10 +1488,10 @@ if ($step == 5 && $datatoimport)
}
if ($excludefirstline && ($sourcelinenb < $excludefirstline)) continue;
if ($endatlinenb && ($sourcelinenb > $endatlinenb)) continue;
-
+
// Run import
$result=$obj->import_insert($arrayrecord,$array_match_file_to_database,$objimport,count($fieldssource),$importid,$updatekeys);
-
+
if (count($obj->errors)) $arrayoferrors[$sourcelinenb]=$obj->errors;
if (count($obj->warnings)) $arrayofwarnings[$sourcelinenb]=$obj->warnings;
if (! count($obj->errors) && ! count($obj->warnings)) $nbok++;
@@ -1505,7 +1505,7 @@ if ($step == 5 && $datatoimport)
}
$error=0;
-
+
// Run the sql after import if defined
//var_dump($objimport->array_import_run_sql_after[0]);
if (! empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0]))
@@ -1515,14 +1515,14 @@ if ($step == 5 && $datatoimport)
{
$i++;
$resqlafterimport=$db->query($sqlafterimport);
- if (! $resqlafterimport)
+ if (! $resqlafterimport)
{
$arrayoferrors['none'][]=array('lib'=>$langs->trans("Error running final request: ".$sqlafterimport));
$error++;
}
}
}
-
+
$db->rollback(); // We force rollback because this was just a simulation.
// Show OK
@@ -1613,7 +1613,7 @@ if ($step == 5 && $datatoimport)
print ''.$langs->trans("RunImportFile").' ';
}
print '';
-
+
}
print '';
@@ -1668,8 +1668,10 @@ if ($step == 6 && $datatoimport)
$head = import_prepare_head($param,6);
- dol_fiche_head($head, 'step6', $langs->trans("NewImport"));
+ dol_fiche_head($head, 'step6', $langs->trans("NewImport"), -1);
+ print '
';
+ print '';
print '
';
@@ -1678,7 +1680,7 @@ if ($step == 6 && $datatoimport)
print '';
$titleofmodule=$objimport->array_import_module[0]->getName();
// Special cas for import common to module/services
- if (in_array($objimport->array_import_code[0], array('produit_supplierprices','produit_multiprice'))) $titleofmodule=$langs->trans("ProductOrService");
+ if (in_array($objimport->array_import_code[0], array('produit_supplierprices','produit_multiprice','produit_languages'))) $titleofmodule=$langs->trans("ProductOrService");
print $titleofmodule;
print ' ';
@@ -1690,10 +1692,13 @@ if ($step == 6 && $datatoimport)
print '';
print '
';
-
+ print '
';
+
print ' ';
-
- print ''.$langs->trans("InformationOnSourceFile").' ';
+
+ print ''.$langs->trans("InformationOnSourceFile").' ';
+ print '
';
+ print '';
print ' ';
- print ''.$langs->trans("InformationOnTargetTables").' ';
+ print ''.$langs->trans("InformationOnTargetTables").' ';
+ print '
';
+ print '';
print '
';
//print ''.$langs->trans("InformationOnTargetTables").' ';
@@ -1812,6 +1820,7 @@ if ($step == 6 && $datatoimport)
print '';
print '
';
+ print '
';
// Launch import
$arrayoferrors=array();
@@ -1852,7 +1861,7 @@ if ($step == 6 && $datatoimport)
// Run import
$result=$obj->import_insert($arrayrecord,$array_match_file_to_database,$objimport,count($fieldssource),$importid,$updatekeys);
-
+
if (count($obj->errors)) $arrayoferrors[$sourcelinenb]=$obj->errors;
if (count($obj->warnings)) $arrayofwarnings[$sourcelinenb]=$obj->warnings;
if (! count($obj->errors) && ! count($obj->warnings)) $nbok++;
@@ -1866,10 +1875,10 @@ if ($step == 6 && $datatoimport)
}
if (count($arrayoferrors) > 0) $db->rollback(); // We force rollback because this was errors.
- else
+ else
{
$error=0;
-
+
// Run the sql after import if defined
//var_dump($objimport->array_import_run_sql_after[0]);
if (! empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0]))
@@ -1879,18 +1888,18 @@ if ($step == 6 && $datatoimport)
{
$i++;
$resqlafterimport=$db->query($sqlafterimport);
- if (! $resqlafterimport)
+ if (! $resqlafterimport)
{
$arrayoferrors['none'][]=array('lib'=>$langs->trans("Error running final request: ".$sqlafterimport));
$error++;
}
}
}
-
+
if (! $error) $db->commit(); // We can commit if no errors.
else $db->rollback();
}
-
+
dol_fiche_end();
@@ -1930,7 +1939,7 @@ function show_elem($fieldssource,$pos,$key,$var,$nostyle='')
global $langs,$bc;
$height='24';
-
+
print "\n\n\n";
print ''."\n";
diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
index 75ae31b9279..1a71f04f4ab 100644
--- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
+++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
@@ -168,9 +168,12 @@ ALTER TABLE llx_accounting_account ADD COLUMN import_key varchar(14);
ALTER TABLE llx_accounting_account ADD COLUMN extraparams varchar(255);
ALTER TABLE llx_accounting_bookkeeping ADD COLUMN import_key varchar(14);
ALTER TABLE llx_accounting_bookkeeping ADD COLUMN extraparams varchar(255);
+ALTER TABLE llx_accounting_bookkeeping_tmp ADD COLUMN extraparams varchar(255);
ALTER TABLE llx_accounting_bookkeeping ADD COLUMN date_lim_reglement datetime DEFAULT NULL;
ALTER TABLE llx_accounting_bookkeeping ADD COLUMN fk_user integer NULL;
+ALTER TABLE llx_accounting_bookkeeping_tmp ADD COLUMN date_lim_reglement datetime DEFAULT NULL;
+ALTER TABLE llx_accounting_bookkeeping_tmp ADD COLUMN fk_user integer NULL;
ALTER TABLE llx_menu MODIFY fk_mainmenu varchar(100);
@@ -521,6 +524,9 @@ ALTER TABLE llx_actioncomm_reminder ADD UNIQUE INDEX uk_actioncomm_reminder_uniq
-- May have error due to duplicate keys
ALTER TABLE llx_resource ADD UNIQUE INDEX uk_resource_ref (ref, entity);
+ALTER TABLE llx_product ADD COLUMN accountancy_code_sell_intra varchar(32) AFTER accountancy_code_sell;
+ALTER TABLE llx_product ADD COLUMN accountancy_code_sell_export varchar(32) AFTER accountancy_code_sell_intra;
+
-- SPEC : use database type 'double' to store monetary values
ALTER TABLE llx_blockedlog MODIFY COLUMN amounts double(24,8);
ALTER TABLE llx_chargessociales MODIFY COLUMN amount double(24,8);
diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql
index 7bc403fd3b3..f2845490f67 100755
--- a/htdocs/install/mysql/migration/repair.sql
+++ b/htdocs/install/mysql/migration/repair.sql
@@ -122,6 +122,8 @@ delete from llx_adherent_extrafields where fk_object not in (select rowid from l
delete from llx_product_extrafields where fk_object not in (select rowid from llx_product);
--delete from llx_societe_commerciaux where fk_soc not in (select rowid from llx_societe);
+UPDATE llx_product SET datec = tms WHERE datec IS NULL;
+
-- Clean stocks
diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql
index c7f8faa6f63..4169b858536 100644
--- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql
+++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql
@@ -45,7 +45,7 @@ CREATE TABLE llx_accounting_bookkeeping
fk_user_modif integer, -- | user making last change
date_creation datetime, -- FEC:EcritureDate | creation date
tms timestamp, -- | date last modification
- fk_user integer NULL, -- The id of user that validate the accounting source document
+ fk_user integer NULL, -- The id of user that validate the accounting source document
code_journal varchar(32) NOT NULL, -- FEC:JournalCode
journal_label varchar(255), -- FEC:JournalLib
piece_num integer NOT NULL, -- FEC:EcritureNum | accounting source document
diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql
index 3b4a4e54143..eee850181b3 100644
--- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql
+++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql
@@ -44,11 +44,13 @@ CREATE TABLE llx_accounting_bookkeeping_tmp
fk_user_author integer NOT NULL, -- | user creating
fk_user_modif integer, -- | user making last change
date_creation datetime, -- FEC:EcritureDate | creation date
- tms timestamp, -- | date last modification
- import_key varchar(14),
+ tms timestamp, -- | date last modification
+ fk_user integer NULL, -- The id of user that validate the accounting source document
code_journal varchar(32) NOT NULL, -- FEC:JournalCode
journal_label varchar(255), -- FEC:JournalLib
piece_num integer NOT NULL, -- FEC:EcritureNum
validated tinyint DEFAULT 0 NOT NULL, -- | 0 line not validated / 1 line validated (No deleting / No modification)
date_validated datetime -- FEC:ValidDate
+ import_key varchar(14),
+ extraparams varchar(255) -- for other parameters with json format
) ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql
index 04267d22d3a..64dcebe4616 100755
--- a/htdocs/install/mysql/tables/llx_product.sql
+++ b/htdocs/install/mysql/tables/llx_product.sql
@@ -23,73 +23,75 @@
create table llx_product
(
- rowid integer AUTO_INCREMENT PRIMARY KEY,
- ref varchar(128) NOT NULL,
- entity integer DEFAULT 1 NOT NULL, -- Multi company id
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ ref varchar(128) NOT NULL,
+ entity integer DEFAULT 1 NOT NULL, -- Multi company id
- ref_ext varchar(128), -- reference into an external system (not used by dolibarr)
+ ref_ext varchar(128), -- reference into an external system (not used by dolibarr)
- datec datetime,
- tms timestamp,
- fk_parent integer DEFAULT 0, -- Not used. Used by external modules. Virtual product id
+ datec datetime,
+ tms timestamp,
+ fk_parent integer DEFAULT 0, -- Not used. Used by external modules. Virtual product id
- label varchar(255) NOT NULL,
- description text,
- note_public text,
- note text,
- customcode varchar(32), -- Optionnal custom code
- fk_country integer DEFAULT NULL, -- Optionnal id of original country
- price double(24,8) DEFAULT 0,
- price_ttc double(24,8) DEFAULT 0,
- price_min double(24,8) DEFAULT 0,
- price_min_ttc double(24,8) DEFAULT 0,
- price_base_type varchar(3) DEFAULT 'HT',
- cost_price double(24,8) DEFAULT NULL, -- Cost price without tax. Can be used for margin calculation.
- default_vat_code varchar(10), -- Same code than into table llx_c_tva (but no constraints). Should be used in priority to find default vat, npr, localtaxes for product.
- tva_tx double(6,3), -- Default VAT rate of product
- recuperableonly integer NOT NULL DEFAULT '0', -- French NPR VAT
- localtax1_tx double(6,3) DEFAULT 0, --
- localtax1_type varchar(10) NOT NULL DEFAULT '0', --
- localtax2_tx double(6,3) DEFAULT 0, --
- localtax2_type varchar(10) NOT NULL DEFAULT '0', --
- fk_user_author integer DEFAULT NULL, -- user making creation
- fk_user_modif integer, -- user making last change
- tosell tinyint DEFAULT 1, -- Product you sell
- tobuy tinyint DEFAULT 1, -- Product you buy
- onportal tinyint DEFAULT 0, -- If it is a product you sell and you want to sell it on portal (module website must be on)
- tobatch tinyint DEFAULT 0 NOT NULL, -- Is it a product that need a batch management (eat-by or lot management)
- fk_product_type integer DEFAULT 0, -- Type of product: 0 for regular product, 1 for service, 9 for other (used by external module)
- duration varchar(6),
- seuil_stock_alerte integer DEFAULT NULL,
- url varchar(255),
- barcode varchar(255) DEFAULT NULL, -- barcode
- fk_barcode_type integer DEFAULT NULL, -- barcode type
- accountancy_code_sell varchar(32), -- Selling accountancy code
- accountancy_code_buy varchar(32), -- Buying accountancy code
- partnumber varchar(32), -- Part/Serial number. TODO To use it into screen if not a duplicate of barcode.
- weight float DEFAULT NULL,
- weight_units tinyint DEFAULT NULL,
- length float DEFAULT NULL,
- length_units tinyint DEFAULT NULL,
- width float DEFAULT NULL,
- width_units tinyint DEFAULT NULL,
- height float DEFAULT NULL,
- height_units tinyint DEFAULT NULL,
- surface float DEFAULT NULL,
- surface_units tinyint DEFAULT NULL,
- volume float DEFAULT NULL,
- volume_units tinyint DEFAULT NULL,
- stock real, -- Current physical stock (dernormalized field)
- pmp double(24,8) DEFAULT 0 NOT NULL, -- To store valuation of stock calculated using average price method, for this product
- fifo double(24,8), -- To store valuation of stock calculated using fifo method, for this product. TODO Not used, should be replaced by stock value stored into movement table.
- lifo double(24,8), -- To store valuation of stock calculated using lifo method, for this product. TODO Not used, should be replaced by stock value stored into movement table.
- canvas varchar(32) DEFAULT NULL,
- finished tinyint DEFAULT NULL, -- 1=manufactured product, 0=matiere premiere
- hidden tinyint DEFAULT 0, -- Not used. Deprecated.
- import_key varchar(14), -- Import key
- model_pdf varchar(255), -- model save dodument used
- fk_price_expression integer, -- Link to the rule for dynamic price calculation
- desiredstock integer DEFAULT 0,
- fk_unit integer DEFAULT NULL,
- price_autogen TINYINT DEFAULT 0
+ label varchar(255) NOT NULL,
+ description text,
+ note_public text,
+ note text,
+ customcode varchar(32), -- Optionnal custom code
+ fk_country integer DEFAULT NULL, -- Optionnal id of original country
+ price double(24,8) DEFAULT 0,
+ price_ttc double(24,8) DEFAULT 0,
+ price_min double(24,8) DEFAULT 0,
+ price_min_ttc double(24,8) DEFAULT 0,
+ price_base_type varchar(3) DEFAULT 'HT',
+ cost_price double(24,8) DEFAULT NULL, -- Cost price without tax. Can be used for margin calculation.
+ default_vat_code varchar(10), -- Same code than into table llx_c_tva (but no constraints). Should be used in priority to find default vat, npr, localtaxes for product.
+ tva_tx double(6,3), -- Default VAT rate of product
+ recuperableonly integer NOT NULL DEFAULT '0', -- French NPR VAT
+ localtax1_tx double(6,3) DEFAULT 0,
+ localtax1_type varchar(10) NOT NULL DEFAULT '0',
+ localtax2_tx double(6,3) DEFAULT 0,
+ localtax2_type varchar(10) NOT NULL DEFAULT '0',
+ fk_user_author integer DEFAULT NULL, -- user making creation
+ fk_user_modif integer, -- user making last change
+ tosell tinyint DEFAULT 1, -- Product you sell
+ tobuy tinyint DEFAULT 1, -- Product you buy
+ onportal tinyint DEFAULT 0, -- If it is a product you sell and you want to sell it on portal (module website must be on)
+ tobatch tinyint DEFAULT 0 NOT NULL, -- Is it a product that need a batch management (eat-by or lot management)
+ fk_product_type integer DEFAULT 0, -- Type of product: 0 for regular product, 1 for service, 9 for other (used by external module)
+ duration varchar(6),
+ seuil_stock_alerte integer DEFAULT NULL,
+ url varchar(255),
+ barcode varchar(255) DEFAULT NULL, -- barcode
+ fk_barcode_type integer DEFAULT NULL, -- barcode type
+ accountancy_code_sell varchar(32), -- Selling accountancy code
+ accountancy_code_sell_intra varchar(32), -- Selling accountancy code for vat intracommunity
+ accountancy_code_sell_export varchar(32), -- Selling accountancy code for vat export
+ accountancy_code_buy varchar(32), -- Buying accountancy code
+ partnumber varchar(32), -- Part/Serial number. TODO To use it into screen if not a duplicate of barcode.
+ weight float DEFAULT NULL,
+ weight_units tinyint DEFAULT NULL,
+ length float DEFAULT NULL,
+ length_units tinyint DEFAULT NULL,
+ width float DEFAULT NULL,
+ width_units tinyint DEFAULT NULL,
+ height float DEFAULT NULL,
+ height_units tinyint DEFAULT NULL,
+ surface float DEFAULT NULL,
+ surface_units tinyint DEFAULT NULL,
+ volume float DEFAULT NULL,
+ volume_units tinyint DEFAULT NULL,
+ stock real, -- Current physical stock (dernormalized field)
+ pmp double(24,8) DEFAULT 0 NOT NULL, -- To store valuation of stock calculated using average price method, for this product
+ fifo double(24,8), -- To store valuation of stock calculated using fifo method, for this product. TODO Not used, should be replaced by stock value stored into movement table.
+ lifo double(24,8), -- To store valuation of stock calculated using lifo method, for this product. TODO Not used, should be replaced by stock value stored into movement table.
+ canvas varchar(32) DEFAULT NULL,
+ finished tinyint DEFAULT NULL, -- 1=manufactured product, 0=matiere premiere
+ hidden tinyint DEFAULT 0, -- Not used. Deprecated.
+ import_key varchar(14), -- Import key
+ model_pdf varchar(255), -- model save dodument used
+ fk_price_expression integer, -- Link to the rule for dynamic price calculation
+ desiredstock integer DEFAULT 0,
+ fk_unit integer DEFAULT NULL,
+ price_autogen tinyint DEFAULT 0
)ENGINE=innodb;
diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
index 869adb18499..000e9d9695a 100644
--- a/htdocs/langs/en_US/accountancy.lang
+++ b/htdocs/langs/en_US/accountancy.lang
@@ -7,6 +7,8 @@ ACCOUNTING_EXPORT_LABEL=Export label
ACCOUNTING_EXPORT_AMOUNT=Export amount
ACCOUNTING_EXPORT_DEVISE=Export currency
Selectformat=Select the format for the file
+ACCOUNTING_EXPORT_FORMAT=Select the format for the file
+ACCOUNTING_EXPORT_ENDLINE=Select the carriage return type
ACCOUNTING_EXPORT_PREFIX_SPEC=Specify the prefix for the file name
ThisService=This service
ThisProduct=This product
@@ -252,6 +254,7 @@ Modelcsv_quadratus=Export towards Quadratus QuadraCompta
Modelcsv_ebp=Export towards EBP
Modelcsv_cogilog=Export towards Cogilog
Modelcsv_agiris=Export towards Agiris (Test)
+Modelcsv_configurable=Export Configurable
ChartofaccountsId=Chart of accounts Id
## Tools - Init accounting account on product / service
diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang
index 9febf20505f..8c402d53705 100644
--- a/htdocs/langs/en_US/compta.lang
+++ b/htdocs/langs/en_US/compta.lang
@@ -79,6 +79,7 @@ AccountancyTreasuryArea=Accountancy/Treasury area
NewPayment=New payment
Payments=Payments
PaymentCustomerInvoice=Customer invoice payment
+PaymentSupplierInvoice=Supplier invoice payment
PaymentSocialContribution=Social/fiscal tax payment
PaymentVat=VAT payment
ListPayment=List of payments
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index 55138235335..67c7fa81da0 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -22,6 +22,8 @@ MassBarcodeInit=Mass barcode init
MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete.
ProductAccountancyBuyCode=Accounting code (purchase)
ProductAccountancySellCode=Accounting code (sale)
+ProductAccountancySellIntraCode=Accounting code (sale intra-community)
+ProductAccountancySellExportCode=Accounting code (sale export)
ProductOrService=Product or Service
ProductsAndServices=Products and Services
ProductsOrServices=Products or Services
@@ -141,7 +143,7 @@ RowMaterial=Raw Material
CloneProduct=Clone product or service
ConfirmCloneProduct=Are you sure you want to clone product or service
%s ?
CloneContentProduct=Clone all main informations of product/service
-ClonePricesProduct=Clone main informations and prices
+ClonePricesProduct=Clone prices
CloneCompositionProduct=Clone packaged product/service
CloneCombinationsProduct=Clone product variants
ProductIsUsed=This product is used
@@ -269,6 +271,7 @@ WarningSelectOneDocument=Please select at least one document
DefaultUnitToShow=Unit
NbOfQtyInProposals=Qty in proposals
ClinkOnALinkOfColumn=Click on a link of column %s to get a detailed view...
+ProductsOrServicesTranslations=Products or services translation
TranslatedLabel=Translated label
TranslatedDescription=Translated description
TranslatedNote=Translated notes
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
index 90ce90859f5..b655fddbbde 100644
--- a/htdocs/modulebuilder/index.php
+++ b/htdocs/modulebuilder/index.php
@@ -132,7 +132,7 @@ if ($dirins && $action == 'initmodule' && $modulename)
dol_delete_file($destdir.'/scripts/myobject.php');
dol_delete_file($destdir.'/img/object_myobject.png');
dol_delete_file($destdir.'/class/myobject.class.php');
- dol_delete_file($destdir.'/class/api_myobject.class.php');
+ dol_delete_file($destdir.'/class/api_mymodule.class.php');
}
// Edit PHP files
@@ -226,7 +226,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
'scripts/myobject.php'=>'scripts/'.strtolower($objectname).'.php',
'img/object_myobject.png'=>'img/object_'.strtolower($objectname).'.png',
'class/myobject.class.php'=>'class/'.strtolower($objectname).'.class.php',
- 'class/api_myobject.class.php'=>'class/api_'.strtolower($objectname).'.class.php'
+ 'class/api_mymodule.class.php'=>'class/api_'.strtolower($module).'.class.php'
);
foreach($filetogenerate as $srcfile => $destfile)
@@ -513,7 +513,7 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname)
'scripts/myobject.php'=>'scripts/'.strtolower($objectname).'.php',
'img/object_myobject.png'=>'img/object_'.strtolower($objectname).'.png',
'class/myobject.class.php'=>'class/'.strtolower($objectname).'.class.php',
- 'class/api_myobject.class.php'=>'class/api_'.strtolower($objectname).'.class.php'
+ 'class/api_myobject.class.php'=>'class/api_'.strtolower($module).'.class.php'
);
$resultko = 0;
@@ -1415,7 +1415,7 @@ elseif (! empty($module))
{
try {
$pathtoclass = strtolower($module).'/class/'.strtolower($tabobj).'.class.php';
- $pathtoapi = strtolower($module).'/class/api_'.strtolower($tabobj).'.class.php';
+ $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'.class.php';
$pathtoagenda = strtolower($module).'/'.strtolower($tabobj).'_agenda.php';
$pathtocard = strtolower($module).'/'.strtolower($tabobj).'_card.php';
$pathtodocument = strtolower($module).'/'.strtolower($tabobj).'_document.php';
diff --git a/htdocs/modulebuilder/template/class/api_myobject.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php
similarity index 90%
rename from htdocs/modulebuilder/template/class/api_myobject.class.php
rename to htdocs/modulebuilder/template/class/api_mymodule.class.php
index 29596df2d96..a068715b521 100644
--- a/htdocs/modulebuilder/template/class/api_myobject.class.php
+++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php
@@ -18,8 +18,12 @@
use Luracast\Restler\RestException;
+dol_include_once('/mymodule/class/myobject.class.php');
+
+
+
/**
- * \file htdocs/modulebuilder/template/class/api_myobject.class.php
+ * \file htdocs/modulebuilder/template/class/api_mymodule.class.php
* \ingroup mymodule
* \brief File for API management of myobject.
*/
@@ -31,7 +35,7 @@ use Luracast\Restler\RestException;
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
-class MyObjectApi extends DolibarrApi
+class MyModuleApi extends DolibarrApi
{
/**
* @var array $FIELDS Mandatory fields, checked when create and update object
@@ -40,6 +44,7 @@ class MyObjectApi extends DolibarrApi
'name'
);
+
/**
* @var MyObject $myobject {@type MyObject}
*/
@@ -48,7 +53,7 @@ class MyObjectApi extends DolibarrApi
/**
* Constructor
*
- * @url GET myobject/
+ * @url GET /
*
*/
function __construct()
@@ -66,7 +71,7 @@ class MyObjectApi extends DolibarrApi
* @param int $id ID of myobject
* @return array|mixed data without useless information
*
- * @url GET myobject/{id}
+ * @url GET myobjects/{id}
* @throws RestException
*/
function get($id)
@@ -87,22 +92,24 @@ class MyObjectApi extends DolibarrApi
return $this->_cleanObjectDatas($this->myobject);
}
+
/**
* List myobjects
*
* Get a list of myobjects
*
- * @param int $mode Use this param to filter list
- * @param string $sortfield Sort field
- * @param string $sortorder Sort order
- * @param int $limit Limit for list
- * @param int $page Page number
- * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101') or (t.import_key:=:'20160101')"
- * @return array Array of myobject objects
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+ * @return array Array of order objects
+ *
+ * @throws RestException
*
* @url GET /myobjects/
*/
- function index($mode, $sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
+ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
global $db, $conf;
$obj_ret = array();
@@ -183,7 +190,7 @@ class MyObjectApi extends DolibarrApi
* @param array $request_data Request datas
* @return int ID of myobject
*
- * @url POST myobject/
+ * @url POST myobjects/
*/
function post($request_data = NULL)
{
@@ -209,7 +216,7 @@ class MyObjectApi extends DolibarrApi
* @param array $request_data Datas
* @return int
*
- * @url PUT myobject/{id}
+ * @url PUT myobjects/{id}
*/
function put($id, $request_data = NULL)
{
diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
index 7acac2eb5fe..63a132699b7 100644
--- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
+++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
@@ -204,21 +204,21 @@ class modMyModule extends DolibarrModules
$r=0;
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
- $this->rights[$r][1] = 'Read objects of My Module'; // Permission label
+ $this->rights[$r][1] = 'Read myobject of MyModule'; // Permission label
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
$this->rights[$r][4] = 'read'; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2)
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2)
$r++;
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
- $this->rights[$r][1] = 'Create/Update objects of My Module'; // Permission label
+ $this->rights[$r][1] = 'Create/Update myobject of MyModule'; // Permission label
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
$this->rights[$r][4] = 'create'; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2)
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2)
$r++;
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
- $this->rights[$r][1] = 'Delete objects of My Module'; // Permission label
+ $this->rights[$r][1] = 'Delete myobject of MyModule'; // Permission label
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
$this->rights[$r][4] = 'delete'; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2)
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2)
diff --git a/htdocs/modulebuilder/template/lib/myobject.lib.php b/htdocs/modulebuilder/template/lib/myobject.lib.php
index 5ce7c4f7c97..d3665dff236 100644
--- a/htdocs/modulebuilder/template/lib/myobject.lib.php
+++ b/htdocs/modulebuilder/template/lib/myobject.lib.php
@@ -44,8 +44,8 @@ function myobjectPrepareHead($object)
if (isset($object->fields['note_public']) || isset($object->fields['note_private']))
{
$nbNote = 0;
- if(!empty($object->fields['note_private'])) $nbNote++;
- if(!empty($object->fields['note_public'])) $nbNote++;
+ if (!empty($object->note_private)) $nbNote++;
+ if (!empty($object->note_public)) $nbNote++;
$head[$h][0] = dol_buildpath('/mymodule/myobject_note.php', 1).'?id='.$object->id;
$head[$h][1] = $langs->trans('Notes');
if ($nbNote > 0) $head[$h][1].= '
'.$nbNote.' ';
diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php
index 8f5583ceed3..79e11d03cb9 100644
--- a/htdocs/modulebuilder/template/myobject_card.php
+++ b/htdocs/modulebuilder/template/myobject_card.php
@@ -198,6 +198,7 @@ if (($id || $ref) && $action == 'edit')
print load_fiche_titre($langs->trans("MyObject"));
print '
';
+ print ' ';
print ' ';
print ' ';
print ' ';
@@ -352,6 +353,10 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
{
print ''."\n";
}
+ else
+ {
+ print ''."\n";
+ }
/*
if ($user->rights->sellyoursaas->create)
@@ -371,6 +376,10 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
{
print ''."\n";
}
+ else
+ {
+ print ''."\n";
+ }
}
print ' '."\n";
}
diff --git a/htdocs/product/card.php b/htdocs/product/card.php
index 4d4cc401022..54b4ae33de8 100644
--- a/htdocs/product/card.php
+++ b/htdocs/product/card.php
@@ -8,7 +8,7 @@
* Copyright (C) 2010-2015 Juanjo Menent
* Copyright (C) 2013-2016 Marcos García
* Copyright (C) 2012-2013 Cédric Salvador
- * Copyright (C) 2011-2017 Alexandre Spangaro
+ * Copyright (C) 2011-2017 Alexandre Spangaro
* Copyright (C) 2014 Cédric Gross
* Copyright (C) 2014-2015 Ferran Marcet
* Copyright (C) 2015 Jean-François Ferry
@@ -306,9 +306,13 @@ if (empty($reshook))
$object->fk_unit = GETPOST('units');
$accountancy_code_sell = GETPOST('accountancy_code_sell');
+ $accountancy_code_sell_intra = GETPOST('accountancy_code_sell_intra');
+ $accountancy_code_sell_export = GETPOST('accountancy_code_sell_export');
$accountancy_code_buy = GETPOST('accountancy_code_buy');
if ($accountancy_code_sell <= 0) { $object->accountancy_code_sell = ''; } else { $object->accountancy_code_sell = $accountancy_code_sell; }
+ if ($accountancy_code_sell_intra <= 0) { $object->accountancy_code_sell_intra = ''; } else { $object->accountancy_code_sell_intra = $accountancy_code_sell_intra; }
+ if ($accountancy_code_sell_export <= 0) { $object->accountancy_code_sell_export = ''; } else { $object->accountancy_code_sell_export = $accountancy_code_sell_export; }
if ($accountancy_code_buy <= 0) { $object->accountancy_code_buy = ''; } else { $object->accountancy_code_buy = $accountancy_code_buy; }
// MultiPrix
@@ -430,9 +434,13 @@ if (empty($reshook))
$object->barcode_type_label = $stdobject->barcode_type_label;
$accountancy_code_sell = GETPOST('accountancy_code_sell');
+ $accountancy_code_sell_intra = GETPOST('accountancy_code_sell_intra');
+ $accountancy_code_sell_export = GETPOST('accountancy_code_sell_export');
$accountancy_code_buy = GETPOST('accountancy_code_buy');
if ($accountancy_code_sell <= 0) { $object->accountancy_code_sell = ''; } else { $object->accountancy_code_sell = $accountancy_code_sell; }
+ if ($accountancy_code_sell_intra <= 0) { $object->accountancy_code_sell_intra = ''; } else { $object->accountancy_code_sell_intra = $accountancy_code_sell_intra; }
+ if ($accountancy_code_sell_export <= 0) { $object->accountancy_code_sell_export = ''; } else { $object->accountancy_code_sell_export = $accountancy_code_sell_export; }
if ($accountancy_code_buy <= 0) { $object->accountancy_code_buy = ''; } else { $object->accountancy_code_buy = $accountancy_code_buy; }
// Fill array 'array_options' with data from add form
@@ -1154,42 +1162,76 @@ else
if (! empty($conf->accounting->enabled))
{
- // Accountancy_code_sell
- print ''.$langs->trans("ProductAccountancySellCode").' ';
- print '';
- print $formaccounting->select_account(GETPOST('accountancy_code_sell'), 'accountancy_code_sell', 1, null, 1, 1, '');
- print ' ';
+ // Accountancy_code_sell
+ print ''.$langs->trans("ProductAccountancySellCode").' ';
+ print '';
+ print $formaccounting->select_account(GETPOST('accountancy_code_sell'), 'accountancy_code_sell', 1, null, 1, 1, '');
+ print ' ';
- // Accountancy_code_buy
- print ''.$langs->trans("ProductAccountancyBuyCode").' ';
- print '';
+ if ($conf->global->MAIN_FEATURES_LEVEL)
+ {
+ // Accountancy_code_sell_intra
+ if ($mysoc->isInEEC())
+ {
+ print ' '.$langs->trans("ProductAccountancySellIntraCode").' ';
+ print '';
+ print $formaccounting->select_account(GETPOST('accountancy_code_sell_intra'), 'accountancy_code_sell_intra', 1, null, 1, 1, '');
+ print ' ';
+ }
+
+ // Accountancy_code_sell_export
+ print ''.$langs->trans("ProductAccountancySellExportCode").' ';
+ print '';
+ print $formaccounting->select_account(GETPOST('accountancy_code_sell_export'), 'accountancy_code_sell_export', 1, null, 1, 1, '');
+ print ' ';
+ }
+
+ // Accountancy_code_buy
+ print ''.$langs->trans("ProductAccountancyBuyCode").' ';
+ print '';
print $formaccounting->select_account(GETPOST('accountancy_code_buy'), 'accountancy_code_buy', 1, null, 1, 1, '');
- print ' ';
+ print ' ';
}
else // For external software
{
- // Accountancy_code_sell
- print ''.$langs->trans("ProductAccountancySellCode").' ';
- print ' ';
- print ' ';
+ // Accountancy_code_sell
+ print ''.$langs->trans("ProductAccountancySellCode").' ';
+ print ' ';
+ print ' ';
- // Accountancy_code_buy
- print ''.$langs->trans("ProductAccountancyBuyCode").' ';
- print ' ';
- print ' ';
- }
+ if ($conf->global->MAIN_FEATURES_LEVEL)
+ {
+ // Accountancy_code_sell_intra
+ if ($mysoc->isInEEC())
+ {
+ print ''.$langs->trans("ProductAccountancySellIntraCode").' ';
+ print ' ';
+ print ' ';
+ }
+
+ // Accountancy_code_sell_export
+ print ''.$langs->trans("ProductAccountancySellExportCode").' ';
+ print ' ';
+ print ' ';
+ }
+
+ // Accountancy_code_buy
+ print ''.$langs->trans("ProductAccountancyBuyCode").' ';
+ print ' ';
+ print ' ';
+ }
print '
';
- dol_fiche_end();
+ dol_fiche_end();
print '';
print ' ';
- print ' ';
+ print ' ';
print ' ';
print '
';
- print '';
- }
+ print '';
+ }
/*
* Product card
@@ -1448,42 +1490,76 @@ else
if (! empty($conf->accounting->enabled))
{
- // Accountancy_code_sell
- print ' '.$langs->trans("ProductAccountancySellCode").' ';
- print '';
+ // Accountancy_code_sell
+ print ' '.$langs->trans("ProductAccountancySellCode").' ';
+ print '';
print $formaccounting->select_account($object->accountancy_code_sell, 'accountancy_code_sell', 1, '', 1, 1);
- print ' ';
+ print '';
- // Accountancy_code_buy
- print ''.$langs->trans("ProductAccountancyBuyCode").' ';
- print '';
+ if ($conf->global->MAIN_FEATURES_LEVEL)
+ {
+ // Accountancy_code_sell_intra
+ if ($mysoc->isInEEC())
+ {
+ print ' '.$langs->trans("ProductAccountancySellIntraCode").' ';
+ print '';
+ print $formaccounting->select_account($object->accountancy_code_sell_intra, 'accountancy_code_sell_intra', 1, '', 1, 1);
+ print ' ';
+ }
+
+ // Accountancy_code_sell_export
+ print ''.$langs->trans("ProductAccountancySellExportCode").' ';
+ print '';
+ print $formaccounting->select_account($object->accountancy_code_sell_export, 'accountancy_code_sell_export', 1, '', 1, 1);
+ print ' ';
+ }
+
+ // Accountancy_code_buy
+ print ''.$langs->trans("ProductAccountancyBuyCode").' ';
+ print '';
print $formaccounting->select_account($object->accountancy_code_buy, 'accountancy_code_buy', 1, '', 1, 1);
- print ' ';
+ print '';
}
else // For external software
{
- // Accountancy_code_sell
- print ''.$langs->trans("ProductAccountancySellCode").' ';
- print ' ';
- print ' ';
+ // Accountancy_code_sell
+ print ''.$langs->trans("ProductAccountancySellCode").' ';
+ print ' ';
+ print ' ';
- // Accountancy_code_buy
- print ''.$langs->trans("ProductAccountancyBuyCode").' ';
- print ' ';
- print ' ';
- }
+ if ($conf->global->MAIN_FEATURES_LEVEL)
+ {
+ // Accountancy_code_sell_intra
+ if ($mysoc->isInEEC())
+ {
+ print ''.$langs->trans("ProductAccountancySellIntraCode").' ';
+ print ' ';
+ print ' ';
+ }
+
+ // Accountancy_code_sell_export
+ print ''.$langs->trans("ProductAccountancySellExportCode").' ';
+ print ' ';
+ print ' ';
+ }
+
+ // Accountancy_code_buy
+ print ''.$langs->trans("ProductAccountancyBuyCode").' ';
+ print ' ';
+ print ' ';
+ }
print '
';
- dol_fiche_end();
+ dol_fiche_end();
- print ' '."\n";
}
- // Accountancy sell code
+ // Accountancy sell code
print '