';
+ // Piece number
+ if (!empty($arrayfields['t.piece_num']['checked']))
+ {
+ print '';
+ $object->id = $line->id;
+ $object->piece_num = $line->piece_num;
+ print $object->getNomUrl(1, '', 0, '', 1);
+ print ' ';
+ if (!$i) $totalarray['nbfield']++;
+ }
+
// Journal code
if (!empty($arrayfields['t.code_journal']['checked']))
{
@@ -654,17 +665,6 @@ while ($i < min($num, $limit))
if (!$i) $totalarray['nbfield']++;
}
- // Piece number
- if (!empty($arrayfields['t.piece_num']['checked']))
- {
- print '';
- $object->id = $line->id;
- $object->piece_num = $line->piece_num;
- print $object->getNomUrl(1, '', 0, '', 1);
- print ' ';
- if (!$i) $totalarray['nbfield']++;
- }
-
// Document ref
if (!empty($arrayfields['t.doc_ref']['checked']))
{
diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php
index 2adcbe9f360..04b59fc7816 100644
--- a/htdocs/accountancy/bookkeeping/listbysubaccount.php
+++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php
@@ -135,8 +135,8 @@ if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('searc
$arrayfields = array(
// 't.subledger_account'=>array('label'=>$langs->trans("SubledgerAccount"), 'checked'=>1),
- 't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1),
't.piece_num'=>array('label'=>$langs->trans("TransactionNumShort"), 'checked'=>1),
+ 't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1),
't.doc_date'=>array('label'=>$langs->trans("Docdate"), 'checked'=>1),
't.doc_ref'=>array('label'=>$langs->trans("Piece"), 'checked'=>1),
't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1),
@@ -442,8 +442,8 @@ $parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
$newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param);
- $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php', '', 1, array('morecss' => 'marginleftonly'));
- $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php', '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
+ $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly'));
+ $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create');
}
@@ -502,6 +502,11 @@ print '';
// Filters lines
print '';
+// Movement number
+if (!empty($arrayfields['t.piece_num']['checked']))
+{
+ print ' ';
+}
// Code journal
if (!empty($arrayfields['t.code_journal']['checked'])) {
print '';
@@ -519,10 +524,6 @@ if (!empty($arrayfields['t.doc_date']['checked'])) {
print '';
print ' ';
}
-// Movement number
-if (!empty($arrayfields['t.piece_num']['checked'])) {
- print ' ';
-}
// Ref document
if (!empty($arrayfields['t.doc_ref']['checked'])) {
print ' ';
@@ -571,15 +572,15 @@ print '';
print " \n";
print '';
+if (!empty($arrayfields['t.piece_num']['checked'])) {
+ print_liste_field_titre($arrayfields['t.piece_num']['label'], $_SERVER['PHP_SELF'], "t.piece_num", "", $param, '', $sortfield, $sortorder);
+}
if (!empty($arrayfields['t.code_journal']['checked'])) {
print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.doc_date']['checked'])) {
print_liste_field_titre($arrayfields['t.doc_date']['label'], $_SERVER['PHP_SELF'], "t.doc_date", "", $param, '', $sortfield, $sortorder, 'center ');
}
-if (!empty($arrayfields['t.piece_num']['checked'])) {
- print_liste_field_titre($arrayfields['t.piece_num']['label'], $_SERVER['PHP_SELF'], "t.piece_num", "", $param, '', $sortfield, $sortorder);
-}
if (!empty($arrayfields['t.doc_ref']['checked'])) {
print_liste_field_titre($arrayfields['t.doc_ref']['label'], $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder);
}
@@ -673,8 +674,10 @@ while ($i < min($num, $limit)) {
print ''.$langs->trans("Unknown");
if ($line->subledger_label) {
print ' ('.$line->subledger_label.')';
+ $htmltext = 'EmptyStringForSubledgerAccountButSubledgerLabelDefined';
+ } else {
+ $htmltext = 'EmptyStringForSubledgerAccountAndSubledgerLabel';
}
- $htmltext = 'EmptyStringForSubledgerAccountButSubledgerLabelDefined';
print $form->textwithpicto('', $htmltext);
print ' ';
}
@@ -691,6 +694,17 @@ while ($i < min($num, $limit)) {
print ' ';
+ // Piece number
+ if (!empty($arrayfields['t.piece_num']['checked']))
+ {
+ print '';
+ $object->id = $line->id;
+ $object->piece_num = $line->piece_num;
+ print $object->getNomUrl(1, '', 0, '', 1);
+ print ' ';
+ if (!$i) $totalarray['nbfield']++;
+ }
+
// Journal code
if (!empty($arrayfields['t.code_journal']['checked'])) {
$accountingjournal = new AccountingJournal($db);
@@ -710,18 +724,6 @@ while ($i < min($num, $limit)) {
}
}
- // Piece number
- if (!empty($arrayfields['t.piece_num']['checked'])) {
- print '';
- $object->id = $line->id;
- $object->piece_num = $line->piece_num;
- print $object->getNomUrl(1, '', 0, '', 1);
- print ' ';
- if (!$i) {
- $totalarray['nbfield']++;
- }
- }
-
// Document ref
if (!empty($arrayfields['t.doc_ref']['checked'])) {
if ($line->doc_type == 'customer_invoice') {
diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php
index 201e3cac95a..b936f99925a 100644
--- a/htdocs/accountancy/class/accountancyexport.class.php
+++ b/htdocs/accountancy/class/accountancyexport.class.php
@@ -820,6 +820,8 @@ class AccountancyExport
*/
public function exportFEC($objectLines)
{
+ global $langs;
+
$separator = "\t";
$end_line = "\r\n";
@@ -855,55 +857,55 @@ class AccountancyExport
$date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d');
// FEC:JournalCode
- print $line->code_journal.$separator;
+ print $line->code_journal . $separator;
// FEC:JournalLib
- print $line->journal_label.$separator;
+ print dol_string_unaccent($langs->transnoentities($line->journal_label)) . $separator;
// FEC:EcritureNum
- print $line->piece_num.$separator;
+ print $line->piece_num . $separator;
// FEC:EcritureDate
- print $date_document.$separator;
+ print $date_document . $separator;
// FEC:CompteNum
- print length_accountg($line->numero_compte).$separator;
+ print $line->numero_compte . $separator;
// FEC:CompteLib
- print dol_string_unaccent($line->label_compte).$separator;
+ print dol_string_unaccent($line->label_compte) . $separator;
// FEC:CompAuxNum
- print length_accounta($line->subledger_account).$separator;
+ print $line->subledger_account . $separator;
// FEC:CompAuxLib
- print dol_string_unaccent($line->subledger_label).$separator;
+ print dol_string_unaccent($line->subledger_label) . $separator;
// FEC:PieceRef
- print $line->doc_ref.$separator;
+ print $line->doc_ref . $separator;
// FEC:PieceDate
- print $date_creation.$separator;
+ print dol_string_unaccent($date_creation) . $separator;
// FEC:EcritureLib
- print dol_string_unaccent($line->label_operation).$separator;
+ print dol_string_unaccent($line->label_operation) . $separator;
// FEC:Debit
- print price2fec($line->debit).$separator;
+ print price2fec($line->debit) . $separator;
// FEC:Credit
- print price2fec($line->credit).$separator;
+ print price2fec($line->credit) . $separator;
// FEC:EcritureLet
- print $line->lettering_code.$separator;
+ print $line->lettering_code . $separator;
// FEC:DateLet
- print $date_lettering.$separator;
+ print $date_lettering . $separator;
// FEC:ValidDate
- print $date_validation.$separator;
+ print $date_validation . $separator;
// FEC:Montantdevise
- print $line->multicurrency_amount.$separator;
+ print $line->multicurrency_amount . $separator;
// FEC:Idevise
print $line->multicurrency_code.$separator;
@@ -924,6 +926,8 @@ class AccountancyExport
*/
public function exportFEC2($objectLines)
{
+ global $langs;
+
$separator = "\t";
$end_line = "\r\n";
@@ -962,7 +966,7 @@ class AccountancyExport
print $line->code_journal . $separator;
// FEC:JournalLib
- print $line->journal_label . $separator;
+ print dol_string_unaccent($langs->transnoentities($line->journal_label)) . $separator;
// FEC:EcritureNum
print $line->piece_num . $separator;
@@ -1644,15 +1648,15 @@ class AccountancyExport
($line->doc_type == 'supplier_invoice' && !isset($supplier_invoices_infos[$line->fk_doc]))) {
if ($line->doc_type == 'customer_invoice') {
// Get new customer invoice ref and company name
- $sql = 'SELECT f.facnumber, s.nom FROM ' . MAIN_DB_PREFIX . 'facture as f';
+ $sql = 'SELECT f.ref, s.nom FROM ' . MAIN_DB_PREFIX . 'facture as f';
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'societe AS s ON f.fk_soc = s.rowid';
$sql .= ' WHERE f.rowid = ' . $line->fk_doc;
$resql = $this->db->query($sql);
if ($resql) {
if ($obj = $this->db->fetch_object($resql)) {
// Save invoice infos
- $invoices_infos[$line->fk_doc] = array('ref' => $obj->facnumber, 'company_name' => $obj->nom);
- $invoice_ref = $obj->facnumber;
+ $invoices_infos[$line->fk_doc] = array('ref' => $obj->ref, 'company_name' => $obj->nom);
+ $invoice_ref = $obj->ref;
$company_name = $obj->nom;
}
}
diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php
index a76be081471..6ee8a03d8ff 100644
--- a/htdocs/accountancy/class/accountingjournal.class.php
+++ b/htdocs/accountancy/class/accountingjournal.class.php
@@ -126,7 +126,7 @@ class AccountingJournal extends CommonObject
$this->rowid = $obj->rowid;
$this->code = $obj->code;
- $this->ref = $obj->code;
+ $this->ref = $obj->code;
$this->label = $obj->label;
$this->nature = $obj->nature;
$this->active = $obj->active;
diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
index fe73ab9f376..f21d88bc363 100644
--- a/htdocs/accountancy/class/bookkeeping.class.php
+++ b/htdocs/accountancy/class/bookkeeping.class.php
@@ -831,7 +831,11 @@ class BookKeeping extends CommonObject
} elseif ($key == 't.reconciled_option') {
$sqlwhere[] = 't.lettering_code IS NULL';
} elseif ($key == 't.code_journal' && !empty($value)) {
- $sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
+ if (is_array($value)) {
+ $sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
+ } else {
+ $sqlwhere[] = natural_search("t.code_journal", $value, 3, 1);
+ }
} else {
$sqlwhere[] = natural_search($key, $value, 0, 1);
}
diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php
index cb47e436cbd..2975c7de3c0 100644
--- a/htdocs/accountancy/customer/list.php
+++ b/htdocs/accountancy/customer/list.php
@@ -532,10 +532,12 @@ if ($result) {
}
// Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding)
- if (!empty($objp->company_code_sell)) {
- $objp->code_sell_t = $objp->company_code_sell;
- $objp->aarowid_suggest = $objp->aarowid_thirdparty;
- $suggestedaccountingaccountfor = '';
+ if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
+ if (!empty($objp->company_code_sell)) {
+ $objp->code_sell_t = $objp->company_code_sell;
+ $objp->aarowid_suggest = $objp->aarowid_thirdparty;
+ $suggestedaccountingaccountfor = '';
+ }
}
// Manage Deposit
@@ -616,25 +618,32 @@ if ($result) {
{
print ' ';
$s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
- $shelp = '';
+ $shelp = ''; $ttype = 'help';
if ($suggestedaccountingaccountfor == 'eec') $shelp = $langs->trans("SaleEEC");
elseif ($suggestedaccountingaccountfor == 'eecwithvat') $shelp = $langs->trans("SaleEECWithVAT");
- elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') $shelp = $langs->trans("SaleEECWithoutVATNumber");
+ elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') {
+ $shelp = $langs->trans("SaleEECWithoutVATNumber");
+ $ttype = 'warning';
+ }
elseif ($suggestedaccountingaccountfor == 'export') $shelp = $langs->trans("SaleExport");
$s .= (empty($objp->code_sell_p) ? ''.$langs->trans("NotDefined").' ' : length_accountg($objp->code_sell_p));
- print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
+ print $form->textwithpicto($s, $shelp, 1, $ttype, '', 0, 2, '', 1);
} else {
+ if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
+ print ' ';
+ $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
+ $shelp = '';
+ $s .= $langs->trans("NotDefined");
+ print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
+ }
+ }
+ if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
print ' ';
- $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
+ $s = '3. '.(($objp->type_l == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': ';
$shelp = '';
- $s .= $langs->trans("NotDefined");
+ $s .= ($objp->code_sell_t > 0 ? length_accountg($objp->code_sell_t) : ''.$langs->trans("NotDefined").' ');
print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
}
- print ' ';
- $s = '3. '.(($objp->type_l == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': ';
- $shelp = '';
- $s .= ($objp->code_sell_t > 0 ? length_accountg($objp->code_sell_t) : ''.$langs->trans("NotDefined").' ');
- print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
print '';
// Suggested accounting account
diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
index d353041234f..c47255647cb 100644
--- a/htdocs/accountancy/journal/bankjournal.php
+++ b/htdocs/accountancy/journal/bankjournal.php
@@ -549,7 +549,7 @@ if (!$error && $action == 'writebookkeeping') {
$bookkeeping->debit = ($mt >= 0 ? $mt : 0);
$bookkeeping->credit = ($mt < 0 ? -$mt : 0);
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->date_creation = $now;
@@ -605,7 +605,7 @@ if (!$error && $action == 'writebookkeeping') {
$bookkeeping->debit = ($mt < 0 ? -$mt : 0);
$bookkeeping->credit = ($mt >= 0) ? $mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->date_creation = $now;
@@ -737,7 +737,7 @@ if (!$error && $action == 'writebookkeeping') {
$bookkeeping->debit = ($mt < 0 ? -$mt : 0);
$bookkeeping->credit = ($mt >= 0) ? $mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->date_creation = $now;
$bookkeeping->label_compte = '';
diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php
index 26e2b4cdf77..70ec097cd27 100644
--- a/htdocs/accountancy/journal/expensereportsjournal.php
+++ b/htdocs/accountancy/journal/expensereportsjournal.php
@@ -223,7 +223,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
$bookkeeping->credit = ($mt > 0) ? $mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
@@ -271,7 +271,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt > 0) ? $mt : 0;
$bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
@@ -329,7 +329,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt > 0) ? $mt : 0;
$bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php
index 94f878527dd..611dde36af5 100644
--- a/htdocs/accountancy/journal/purchasesjournal.php
+++ b/htdocs/accountancy/journal/purchasesjournal.php
@@ -322,7 +322,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
$bookkeeping->credit = ($mt > 0) ? $mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
@@ -372,7 +372,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt > 0) ? $mt : 0;
$bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
@@ -433,7 +433,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt > 0) ? $mt : 0;
$bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
@@ -484,7 +484,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt > 0) ? $mt : 0;
$bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
index 9f44e02aafa..62d2238a116 100644
--- a/htdocs/accountancy/journal/sellsjournal.php
+++ b/htdocs/accountancy/journal/sellsjournal.php
@@ -333,7 +333,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt >= 0) ? $mt : 0;
$bookkeeping->credit = ($mt < 0) ? -$mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
@@ -383,7 +383,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt < 0) ? -$mt : 0;
$bookkeeping->credit = ($mt >= 0) ? $mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
@@ -443,7 +443,7 @@ if ($action == 'writebookkeeping') {
$bookkeeping->debit = ($mt < 0) ? -$mt : 0;
$bookkeeping->credit = ($mt >= 0) ? $mt : 0;
$bookkeeping->code_journal = $journal;
- $bookkeeping->journal_label = $journal_label;
+ $bookkeeping->journal_label = $langs->transnoentities($journal_label);
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
diff --git a/htdocs/admin/system/perf.php b/htdocs/admin/system/perf.php
index 6d9e3574789..e589db3ca26 100644
--- a/htdocs/admin/system/perf.php
+++ b/htdocs/admin/system/perf.php
@@ -473,7 +473,7 @@ $sql .= " FROM ".MAIN_DB_PREFIX."product as p";
$resql = $db->query($sql);
if ($resql)
{
- $limitforoptim = 10000;
+ $limitforoptim = 100000;
$num = $db->num_rows($resql);
$obj = $db->fetch_object($resql);
$nb = $obj->nb;
diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php
new file mode 100755
index 00000000000..502a573e98b
--- /dev/null
+++ b/htdocs/admin/workstation.php
@@ -0,0 +1,513 @@
+
+ * Copyright (C) 2020 Gauthier VERDOL
+ *
+ * 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 .
+ */
+
+/**
+ * \file workstation/admin/setup.php
+ * \ingroup workstation
+ * \brief Workstation setup page.
+ */
+
+// Load Dolibarr environment
+require "../main.inc.php";
+
+// Libraries
+require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
+require_once DOL_DOCUMENT_ROOT . '/workstation/lib/workstation.lib.php';
+//require_once "../class/myclass.class.php";
+
+// Translations
+$langs->loadLangs(array("admin", "workstation@workstation"));
+
+// Access control
+if (!$user->admin) accessforbidden();
+
+// Parameters
+$action = GETPOST('action', 'aZ09');
+$backtopage = GETPOST('backtopage', 'alpha');
+
+$value = GETPOST('value', 'alpha');
+
+/*$arrayofparameters = array(
+ 'WORKSTATION_MYPARAM1'=>array('css'=>'minwidth200', 'enabled'=>1),
+ 'WORKSTATION_MYPARAM2'=>array('css'=>'minwidth500', 'enabled'=>1)
+);*/
+
+$error = 0;
+$setupnotempty = 0;
+
+
+/*
+ * Actions
+ */
+
+if ((float) DOL_VERSION >= 6)
+{
+ include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
+}
+
+if ($action == 'updateMask')
+{
+ $maskconstorder = GETPOST('maskconstWorkstation', 'alpha');
+ $maskorder = GETPOST('maskWorkstation', 'alpha');
+
+ if ($maskconstorder) $res = dolibarr_set_const($db, $maskconstorder, $maskorder, 'chaine', 0, '', $conf->entity);
+
+ if (!$res > 0) $error++;
+
+ if (!$error)
+ {
+ setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+ } else {
+ setEventMessages($langs->trans("Error"), null, 'errors');
+ }
+} elseif ($action == 'specimen')
+{
+ $modele = GETPOST('module', 'alpha');
+ $tmpobjectkey = GETPOST('object');
+
+ $tmpobject = new $tmpobjectkey($db);
+ $tmpobject->initAsSpecimen();
+
+ // Search template files
+ $file = ''; $classname = ''; $filefound = 0;
+ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+ foreach ($dirmodels as $reldir)
+ {
+ $file = dol_buildpath($reldir."core/modules/workstation/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0);
+ if (file_exists($file))
+ {
+ $filefound = 1;
+ $classname = "pdf_".$modele;
+ break;
+ }
+ }
+
+ if ($filefound)
+ {
+ require_once $file;
+
+ $module = new $classname($db);
+
+ if ($module->write_file($tmpobject, $langs) > 0)
+ {
+ header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf");
+ return;
+ } else {
+ setEventMessages($module->error, null, 'errors');
+ dol_syslog($module->error, LOG_ERR);
+ }
+ } else {
+ setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
+ dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
+ }
+}
+
+// Activate a model
+elseif ($action == 'set')
+{
+ $ret = addDocumentModel($value, $type, $label, $scandir);
+} elseif ($action == 'del')
+{
+ $tmpobjectkey = GETPOST('object');
+
+ $ret = delDocumentModel($value, $type);
+ if ($ret > 0)
+ {
+ $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF';
+ if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity);
+ }
+}
+
+// Set default model
+elseif ($action == 'setdoc')
+{
+ $tmpobjectkey = GETPOST('object');
+ $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF';
+ if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity))
+ {
+ // The constant that was read before the new set
+ // We therefore requires a variable to have a coherent view
+ $conf->global->$constforval = $value;
+ }
+
+ // On active le modele
+ $ret = delDocumentModel($value, $type);
+ if ($ret > 0)
+ {
+ $ret = addDocumentModel($value, $type, $label, $scandir);
+ }
+} elseif ($action == 'setmod')
+{
+ // TODO Check if numbering module chosen can be activated
+ // by calling method canBeActivated
+ $tmpobjectkey = GETPOST('object');
+ $constforval = 'WORKSTATION_'.strtoupper($tmpobjectkey)."_ADDON";
+ dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity);
+}
+
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+
+$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
+$page_name = "WorkstationSetup";
+llxHeader('', $langs->trans($page_name));
+
+// Subheader
+$linkback = ''.$langs->trans("BackToModuleList").' ';
+
+print load_fiche_titre($langs->trans($page_name), $linkback, 'object_workstation@workstation');
+
+// Configuration header
+$head = workstationAdminPrepareHead();
+print dol_get_fiche_head($head, 'settings', '', -1, "workstation@workstation");
+
+// Setup page goes here
+//echo ''.$langs->trans("WorkstationSetupPage").' ';
+
+
+if ($action == 'edit')
+{
+ print '';
+ print ' ';
+} else {
+ if (!empty($arrayofparameters))
+ {
+ print '';
+ print ''.$langs->trans("Parameter").' '.$langs->trans("Value").' ';
+
+ foreach ($arrayofparameters as $key => $val)
+ {
+ $setupnotempty++;
+
+ print '';
+ $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
+ print $form->textwithpicto($langs->trans($key), $tooltiphelp);
+ print ' '.$conf->global->$key.' ';
+ }
+
+ print '
';
+
+ print '';
+ }/* else {
+ print ' '.$langs->trans("NothingToSetup");
+ }*/
+}
+
+
+$moduledir = 'workstation';
+$myTmpObjects = array();
+$myTmpObjects['workstation'] = array('includerefgeneration'=>1, 'includedocgeneration'=>0);
+
+
+foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
+ if ($myTmpObjectKey == 'MyObject') continue;
+ if ($myTmpObjectArray['includerefgeneration']) {
+ /*
+ * Orders Numbering model
+ */
+ $setupnotempty++;
+
+ print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', '');
+
+ print '';
+ print '';
+ print ''.$langs->trans("Name").' ';
+ print ''.$langs->trans("Description").' ';
+ print ''.$langs->trans("Example").' ';
+ print ''.$langs->trans("Status").' ';
+ print ''.$langs->trans("ShortInfo").' ';
+ print ' '."\n";
+
+ clearstatcache();
+
+ foreach ($dirmodels as $reldir)
+ {
+ $dir = dol_buildpath($reldir."core/modules/".$moduledir);
+
+ if (is_dir($dir))
+ {
+ $handle = opendir($dir);
+ if (is_resource($handle))
+ {
+ while (($file = readdir($handle)) !== false)
+ {
+ if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php')
+ {
+ $file = substr($file, 0, dol_strlen($file) - 4);
+
+ require_once $dir.'/'.$file.'.php';
+
+ $module = new $file($db);
+
+ // Show modules according to features level
+ if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
+ if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
+
+ if ($module->isEnabled())
+ {
+ dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
+
+ print ''.$module->name." \n";
+ print $module->info();
+ print ' ';
+
+ // Show example of numbering model
+ print '';
+ $tmp = $module->getExample();
+ if (preg_match('/^Error/', $tmp)) {
+ $langs->load("errors");
+ print ''.$langs->trans($tmp).'
';
+ } elseif ($tmp == 'NotConfigured') print $langs->trans($tmp);
+ else print $tmp;
+ print ' '."\n";
+
+ print '';
+ $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON';
+ if ($conf->global->$constforvar == $file)
+ {
+ print img_picto($langs->trans("Activated"), 'switch_on');
+ } else {
+ print '';
+ print img_picto($langs->trans("Disabled"), 'switch_off');
+ print ' ';
+ }
+ print ' ';
+
+ $mytmpinstance = new $myTmpObjectKey($db);
+ $mytmpinstance->initAsSpecimen();
+
+ // Info
+ $htmltooltip = '';
+ $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().' ';
+
+ $nextval = $module->getNextValue($mytmpinstance);
+ if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
+ $htmltooltip .= ''.$langs->trans("NextValue").': ';
+ if ($nextval) {
+ if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured')
+ $nextval = $langs->trans($nextval);
+ $htmltooltip .= $nextval.' ';
+ } else {
+ $htmltooltip .= $langs->trans($module->error).' ';
+ }
+ }
+
+ print '';
+ print $form->textwithpicto('', $htmltooltip, 1, 0);
+ print ' ';
+
+ print " \n";
+ }
+ }
+ }
+ closedir($handle);
+ }
+ }
+ }
+ print "
\n";
+ }
+
+ if ($myTmpObjectArray['includedocgeneration']) {
+ /*
+ * Document templates generators
+ */
+ $setupnotempty++;
+ $type = strtolower($myTmpObjectKey);
+
+ print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', '');
+
+ // Load array def with activated templates
+ $def = array();
+ $sql = "SELECT nom";
+ $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
+ $sql .= " WHERE type = '".$db->escape($type)."'";
+ $sql .= " AND entity = ".$conf->entity;
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $i = 0;
+ $num_rows = $db->num_rows($resql);
+ while ($i < $num_rows)
+ {
+ $array = $db->fetch_array($resql);
+ array_push($def, $array[0]);
+ $i++;
+ }
+ } else {
+ dol_print_error($db);
+ }
+
+ print "\n";
+ print "\n";
+ print ''.$langs->trans("Name").' ';
+ print ''.$langs->trans("Description").' ';
+ print ''.$langs->trans("Status")." \n";
+ print ''.$langs->trans("Default")." \n";
+ print ''.$langs->trans("ShortInfo").' ';
+ print ''.$langs->trans("Preview").' ';
+ print " \n";
+
+ clearstatcache();
+
+ foreach ($dirmodels as $reldir)
+ {
+ foreach (array('', '/doc') as $valdir)
+ {
+ $realpath = $reldir."core/modules/".$moduledir.$valdir;
+ $dir = dol_buildpath($realpath);
+
+ if (is_dir($dir))
+ {
+ $handle = opendir($dir);
+ if (is_resource($handle))
+ {
+ while (($file = readdir($handle)) !== false)
+ {
+ $filelist[] = $file;
+ }
+ closedir($handle);
+ arsort($filelist);
+
+ foreach ($filelist as $file)
+ {
+ if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file))
+ {
+ if (file_exists($dir.'/'.$file))
+ {
+ $name = substr($file, 4, dol_strlen($file) - 16);
+ $classname = substr($file, 0, dol_strlen($file) - 12);
+
+ require_once $dir.'/'.$file;
+ $module = new $classname($db);
+
+ $modulequalified = 1;
+ if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified = 0;
+ if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0;
+
+ if ($modulequalified)
+ {
+ print '';
+ print (empty($module->name) ? $name : $module->name);
+ print " \n";
+ if (method_exists($module, 'info')) print $module->info($langs);
+ else print $module->description;
+ print ' ';
+
+ // Active
+ if (in_array($name, $def))
+ {
+ print ''."\n";
+ print '';
+ print img_picto($langs->trans("Enabled"), 'switch_on');
+ print ' ';
+ print ' ';
+ } else {
+ print ''."\n";
+ print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').' ';
+ print " ";
+ }
+
+ // Default
+ print '';
+ $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON';
+ if ($conf->global->$constforvar == $name)
+ {
+ print img_picto($langs->trans("Default"), 'on');
+ } else {
+ print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').' ';
+ }
+ print ' ';
+
+ // Info
+ $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
+ $htmltooltip .= ' '.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
+ if ($module->type == 'pdf')
+ {
+ $htmltooltip .= ' '.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
+ }
+ $htmltooltip .= ' '.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
+
+ $htmltooltip .= ''.$langs->trans("FeaturesSupported").': ';
+ $htmltooltip .= ' '.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
+ $htmltooltip .= ' '.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
+
+ print '';
+ print $form->textwithpicto('', $htmltooltip, 1, 0);
+ print ' ';
+
+ // Preview
+ print '';
+ if ($module->type == 'pdf')
+ {
+ print ''.img_object($langs->trans("Preview"), 'generic').' ';
+ } else {
+ print img_object($langs->trans("PreviewNotAvailable"), 'generic');
+ }
+ print ' ';
+
+ print " \n";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ print '
';
+ }
+}
+
+/*if (empty($setupnotempty)) {
+ print ' '.$langs->trans("NothingToSetup");
+}*/
+
+// Page end
+print dol_get_fiche_end();
+
+llxFooter();
+$db->close();
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index dc0ada64eb3..016201be0f3 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -454,6 +454,15 @@ $viewmode .= ' ';
+// Add more views from hooks
+$parameters = array(); $object = null;
+$reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
+if (empty($reshook)) {
+ $viewmode .= $hookmanager->resPrint;
+} elseif ($reshook > 1) {
+ $viewmode = $hookmanager->resPrint;
+}
+
$newcardbutton = '';
if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create)
diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php
index 7fc58b73c9f..16c2a315cdd 100644
--- a/htdocs/comm/action/list.php
+++ b/htdocs/comm/action/list.php
@@ -474,11 +474,9 @@ if ($resql)
// Calendars from hooks
$parameters = array(); $object = null;
$reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action);
- if (empty($reshook))
- {
+ if (empty($reshook)) {
$s .= $hookmanager->resPrint;
- } elseif ($reshook > 1)
- {
+ } elseif ($reshook > 1) {
$s = $hookmanager->resPrint;
}
@@ -515,6 +513,15 @@ if ($resql)
$viewmode .= ' ';
+ // Add more views from hooks
+ $parameters = array(); $object = null;
+ $reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
+ if (empty($reshook)) {
+ $viewmode .= $hookmanager->resPrint;
+ } elseif ($reshook > 1) {
+ $viewmode = $hookmanager->resPrint;
+ }
+
$tmpforcreatebutton = dol_getdate(dol_now(), true);
$newparam .= '&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$tmpforcreatebutton['year'];
diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php
index 29b86b96868..f956b5ae5f7 100644
--- a/htdocs/comm/action/pertype.php
+++ b/htdocs/comm/action/pertype.php
@@ -384,6 +384,15 @@ $viewmode .= ' ';
+// Add more views from hooks
+$parameters = array(); $object = null;
+$reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
+if (empty($reshook)) {
+ $viewmode .= $hookmanager->resPrint;
+} elseif ($reshook > 1) {
+ $viewmode = $hookmanager->resPrint;
+}
+
$newcardbutton = '';
if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create)
diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php
index 55e6725ba8d..2dc62a52e91 100644
--- a/htdocs/comm/action/peruser.php
+++ b/htdocs/comm/action/peruser.php
@@ -389,6 +389,15 @@ $viewmode .= ' ';
+// Add more views from hooks
+$parameters = array(); $object = null;
+$reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
+if (empty($reshook)) {
+ $viewmode .= $hookmanager->resPrint;
+} elseif ($reshook > 1) {
+ $viewmode = $hookmanager->resPrint;
+}
+
$newcardbutton = '';
if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create)
diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
index 23c960d3a4b..b81ac502552 100644
--- a/htdocs/comm/propal/card.php
+++ b/htdocs/comm/propal/card.php
@@ -1581,7 +1581,7 @@ if ($action == 'create')
// Date
print ''.$langs->trans('Date').' ';
- print img_picto('', 'object_calendarday').' '.$form->selectDate('', '', '', '', '', "addprop", 1, 1);
+ print $form->selectDate('', '', '', '', '', "addprop", 1, 1);
print ' ';
// Validaty duration
@@ -1644,7 +1644,6 @@ if ($action == 'create')
// Delivery date (or manufacturing)
print ''.$langs->trans("DeliveryDate").' ';
print '';
- print img_picto('', 'object_calendarday').' ';
if ($conf->global->DATE_LIVRAISON_WEEK_DELAY != "") {
$tmpdte = time() + ((7 * $conf->global->DATE_LIVRAISON_WEEK_DELAY) * 24 * 60 * 60);
$syear = date("Y", $tmpdte);
@@ -1662,8 +1661,7 @@ if ($action == 'create')
$langs->load("projects");
print ' ';
print ''.$langs->trans("Project").' ';
- print img_picto('', 'project');
- $numprojet = $formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth500');
+ print img_picto('', 'project').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
print ' id).'"> ';
print ' ';
print ' ';
@@ -1685,7 +1683,8 @@ if ($action == 'create')
print '';
print img_picto('', 'pdf').' ';
$liste = ModelePDFPropales::liste_modeles($db);
- print $form->selectarray('model', $liste, ($conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT ? $conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT : $conf->global->PROPALE_ADDON_PDF));
+ $preselected = ($conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT ? $conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT : $conf->global->PROPALE_ADDON_PDF);
+ print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', '', 1);
print " ";
// Multicurrency
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index 6dd6fc6911a..66105e06fff 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -1616,14 +1616,14 @@ if ($action == 'create' && $usercancreate)
// Date
print ''.$langs->trans('Date').' ';
- print img_picto('', 'object_calendarday').' '.$form->selectDate('', 're', '', '', '', "crea_commande", 1, 1); // Always autofill date with current date
+ print $form->selectDate('', 're', '', '', '', "crea_commande", 1, 1); // Always autofill date with current date
print ' ';
// Date delivery planned
print ''.$langs->trans("DateDeliveryPlanned").' ';
print '';
$date_delivery = ($date_delivery ? $date_delivery : $object->date_delivery);
- print img_picto('', 'object_calendarday').' '.$form->selectDate($date_delivery ? $date_delivery : -1, 'date_delivery', 1, 1, 1);
+ print $form->selectDate($date_delivery ? $date_delivery : -1, 'date_delivery', 1, 1, 1);
print " \n";
print ' ';
@@ -1731,7 +1731,8 @@ if ($action == 'create' && $usercancreate)
print img_picto('', 'pdf').' ';
include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
$liste = ModelePDFCommandes::liste_modeles($db);
- print $form->selectarray('model', $liste, $conf->global->COMMANDE_ADDON_PDF);
+ $preselected = $conf->global->COMMANDE_ADDON_PDF;
+ print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', '', 1);
print "";
// Multicurrency
diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index 248a45c629a..bbd189239c9 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -2893,19 +2893,20 @@ class Commande extends CommonOrder
* Classify the order as invoiced
*
* @param User $user Object user making the change
- * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
- * @return int <0 if KO, >0 if OK
+ * @param int $notrigger 1=Does not execute triggers, 0=execute triggers
+ * @return int <0 if KO, 0 if already billed, >0 if OK
*/
public function classifyBilled(User $user, $notrigger = 0)
{
$error = 0;
- $this->db->begin();
if ($this->billed)
{
return 0;
}
+ $this->db->begin();
+
$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande SET facture = 1';
$sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT;
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 7250d673494..16a472d878c 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -2956,7 +2956,7 @@ if ($action == 'create')
} else {
print ''.$langs->trans('Customer').' ';
print '';
- print $form->select_company($soc->id, 'socid', '((s.client = 1 OR s.client = 3) AND s.status=1)', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
+ print img_picto('', 'company').$form->select_company($soc->id, 'socid', '((s.client = 1 OR s.client = 3) AND s.status=1)', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
// Option to reload page to retrieve customer informations.
if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED))
{
@@ -3444,11 +3444,11 @@ if ($action == 'create')
if (!empty($conf->banque->enabled))
{
if (GETPOSTISSET('fk_account')) {
- $fk_account = GETPOST('fk_account');
+ $fk_account = GETPOST('fk_account', 'int');
}
print ' '.$langs->trans('BankAccount').' ';
- $form->select_comptes($fk_account, 'fk_account', 0, '', 1);
+ print img_picto('', 'bank_account', 'class="paddingrightonly"').$form->select_comptes($fk_account, 'fk_account', 0, '', 1, '', 0, '', 1);
print ' ';
}
@@ -3457,7 +3457,7 @@ if ($action == 'create')
{
$langs->load('projects');
print ''.$langs->trans('Project').' ';
- $numprojet = $formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth500');
+ print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
print ' id.($fac_rec ? '&fac_rec='.$fac_rec : '')).'"> ';
print ' ';
}
@@ -3504,11 +3504,11 @@ if ($action == 'create')
if (!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) {
// Hidden conf
$paramkey = 'FACTURE_ADDON_PDF_'.$object->type;
- $curent = !empty($conf->global->$paramkey) ? $conf->global->$paramkey : $conf->global->FACTURE_ADDON_PDF;
+ $preselected = !empty($conf->global->$paramkey) ? $conf->global->$paramkey : $conf->global->FACTURE_ADDON_PDF;
} else {
- $curent = $conf->global->FACTURE_ADDON_PDF;
+ $preselected = $conf->global->FACTURE_ADDON_PDF;
}
- print $form->selectarray('model', $liste, $curent);
+ print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', '', 1);
print "";
// Multicurrency
@@ -4144,7 +4144,7 @@ if ($action == 'create')
$result = $tmptemplate->fetch($object->fk_fac_rec_source);
if ($result > 0) {
print ' ';
- print $langs->transnoentities("GeneratedFromTemplate", ''.dol_escape_htmltag($tmptemplate->ref).' ');
+ print $langs->transnoentities("GeneratedFromTemplate", ''.dol_escape_htmltag($tmptemplate->ref).' ');
print ' ';
}
}
@@ -4285,7 +4285,7 @@ if ($action == 'create')
print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0);
print '';
if ($usercancreate && $action != 'editmulticurrencyrate' && !empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency)
- print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).' ';
+ print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).' ';
print '
';
print '';
if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php
index 29e78f90af8..1a50fadcc9c 100644
--- a/htdocs/compta/facture/class/facture-rec.class.php
+++ b/htdocs/compta/facture/class/facture-rec.class.php
@@ -2072,6 +2072,8 @@ class FactureLigneRec extends CommonInvoiceLine
$sql .= ", fk_contract_line=".($this->fk_contract_line ? $this->fk_contract_line : "null");
$sql .= " WHERE rowid = ".$this->id;
+ $this->db->begin();
+
dol_syslog(get_class($this)."::updateline", LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
@@ -2091,13 +2093,18 @@ class FactureLigneRec extends CommonInvoiceLine
$result = $this->call_trigger('LINEBILLREC_UPDATE', $user);
if ($result < 0)
{
- $this->db->rollback();
- return -2;
+ $error++;
}
// End call triggers
}
- $this->db->commit();
- return 1;
+
+ if ($error) {
+ $this->db->rollback();
+ return -2;
+ } else {
+ $this->db->commit();
+ return 1;
+ }
} else {
$this->error = $this->db->lasterror();
$this->db->rollback();
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 6b7f1612836..2c897968320 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -401,6 +401,7 @@ class Paiement extends CommonObject
if ($result < 0)
{
$this->error = $invoice->error;
+ $this->errors = $invoice->errors;
$error++;
}
}
@@ -578,9 +579,10 @@ class Paiement extends CommonObject
* @param string $emetteur_nom Name of transmitter
* @param string $emetteur_banque Name of bank
* @param int $notrigger No trigger
+ * @param string $accountancycode When we record a free bank entry, we must provide accounting account if accountancy module is on.
* @return int <0 if KO, bank_line_id if OK
*/
- public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0)
+ public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0, $accountancycode = '')
{
global $conf, $langs, $user;
@@ -625,7 +627,8 @@ class Paiement extends CommonObject
'',
$user,
$emetteur_nom,
- $emetteur_banque
+ $emetteur_banque,
+ $accountancycode
);
// Mise a jour fk_bank dans llx_paiement
diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php
index 929d35d9730..1bea255bda2 100644
--- a/htdocs/core/actions_sendmails.inc.php
+++ b/htdocs/core/actions_sendmails.inc.php
@@ -227,7 +227,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST
}
if (count($receivercc) > 0) {
foreach ($receivercc as $key => $val) {
- if ($val == 'thirdparty') { // Key selected means currentthird party (may be usd for current member or current user too)
+ if ($val == 'thirdparty') { // Key selected means current thirdparty (may be usd for current member or current user too)
// Recipient was provided from combo list
$tmparray[] = dol_string_nospecial($thirdparty->name, ' ', array(",")).' <'.$thirdparty->email.'>';
} elseif ($val == 'contact') { // Key selected means current contact
@@ -399,7 +399,6 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST
$error++;
}
// End call triggers
-
if ($error) {
setEventMessages($object->error, $object->errors, 'errors');
}
diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php
index 0be9d7bbd6f..1858a308756 100644
--- a/htdocs/core/boxes/box_factures_fourn.php
+++ b/htdocs/core/boxes/box_factures_fourn.php
@@ -133,7 +133,7 @@ class box_factures_fourn extends ModeleBoxes
$thirdpartystatic->id = $objp->socid;
$thirdpartystatic->name = $objp->name;
- //$thirdpartystatic->name_alias = $objp->name_alias;
+ $thirdpartystatic->name_alias = $objp->name_alias;
$thirdpartystatic->code_fournisseur = $objp->code_fournisseur;
$thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur;
$thirdpartystatic->fournisseur = $objp->fournisseur;
diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php
index b957e5bf0c1..d345f3d33b0 100644
--- a/htdocs/core/boxes/box_factures_fourn_imp.php
+++ b/htdocs/core/boxes/box_factures_fourn_imp.php
@@ -130,7 +130,7 @@ class box_factures_fourn_imp extends ModeleBoxes
$thirdpartystatic->id = $objp->socid;
$thirdpartystatic->name = $objp->name;
- //$thirdpartystatic->name_alias = $objp->name_alias;
+ $thirdpartystatic->name_alias = $objp->name_alias;
$thirdpartystatic->code_fournisseur = $objp->code_fournisseur;
$thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur;
$thirdpartystatic->fournisseur = $objp->fournisseur;
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index c7634a6d638..1462fa327eb 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -14,6 +14,7 @@
* Copyright (C) 2017 Rui Strecht
* Copyright (C) 2018-2020 Frédéric France
* Copyright (C) 2018 Josep LluÃs Amador
+ * Copyright (C) 2021 Gauthier VERDOL
*
* 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
@@ -3660,6 +3661,56 @@ abstract class CommonObject
}
}
+ /**
+ * Function used to get an array with all items linked to an object id in association table
+ *
+ * @param int $fk_object_where id of object we need to get linked items
+ * @param string $field_select name of field we need to get a list
+ * @param string $field_where name of field of object we need to get linked items
+ * @param string $table_element name of association table
+ * @return array
+ */
+ static public function getAllItemsLinkedByObjectID($fk_object_where, $field_select, $field_where, $table_element)
+ {
+ if (empty($fk_object_where) || empty($field_where) || empty($table_element)) return -1;
+
+ global $db;
+
+ $sql = 'SELECT '.$field_select.' FROM '.MAIN_DB_PREFIX.$table_element.' WHERE '.$field_where.' = '.$fk_object_where;
+ $resql = $db->query($sql);
+
+ $TRes = array();
+ if (!empty($resql)) {
+ while ($res = $db->fetch_object($resql)) {
+ $TRes[] = $res->{$field_select};
+ }
+ }
+
+ return $TRes;
+ }
+
+ /**
+ * Function used to remove all items linked to an object id in association table
+ *
+ * @param int $fk_object_where id of object we need to remove linked items
+ * @param string $field_where name of field of object we need to delete linked items
+ * @param string $table_element name of association table
+ * @return int
+ */
+ static public function deleteAllItemsLinkedByObjectID($fk_object_where, $field_where, $table_element)
+ {
+ if (empty($fk_object_where) || empty($field_where) || empty($table_element)) return -1;
+
+ global $db;
+
+ $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$table_element.' WHERE '.$field_where.' = '.$fk_object_where;
+ $resql = $db->query($sql);
+
+ if (empty($resql)) return 0;
+
+ return 1;
+ }
+
/**
* Set status of an object
*
diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php
index 89b5a79df4b..d610203b3ad 100644
--- a/htdocs/core/class/hookmanager.class.php
+++ b/htdocs/core/class/hookmanager.class.php
@@ -156,6 +156,7 @@ class HookManager
$method,
array(
'addCalendarChoice',
+ 'addCalendarView',
'addMoreActionsButtons',
'addMoreMassActions',
'addSearchEntry',
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index e1b12cd9bf7..502cb9d920e 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -2169,8 +2169,8 @@ class Form
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid))
{
$sql .= ', pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
- $sql .= ' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
- $selectFields .= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx";
+ $sql .= ' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx, pcp.ref_customer as custref';
+ $selectFields .= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx, custref";
}
// Units
if (!empty($conf->global->PRODUCT_USE_UNITS)) {
@@ -2280,6 +2280,7 @@ class Form
if ($i > 0) $sql .= " AND ";
$sql .= "(p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%'";
if (!empty($conf->global->MAIN_MULTILANGS)) $sql .= " OR pl.label LIKE '".$this->db->escape($prefix.$crit)."%'";
+ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && ! empty($socid)) $sql .= " OR pcp.ref_customer LIKE '".$this->db->escape($prefix.$crit)."%'";
if (!empty($conf->global->PRODUCT_AJAX_SEARCH_ON_DESCRIPTION))
{
$sql .= " OR p.description LIKE '".$this->db->escape($prefix.$crit)."%'";
@@ -2469,6 +2470,7 @@ class Form
$outkey = $objp->rowid;
$outref = $objp->ref;
+ $outrefcust = empty($objp->custref) ? '' : $objp->custref;
$outlabel = $objp->label;
$outdesc = $objp->description;
if (!empty($conf->global->MAIN_MULTILANGS))
@@ -2543,11 +2545,13 @@ class Form
}
$opt .= '>';
$opt .= $objp->ref;
+ if (! empty($objp->custref)) $opt.= ' (' . $objp->custref . ')';
if ($outbarcode) $opt .= ' ('.$outbarcode.')';
$opt .= ' - '.dol_trunc($label, $maxlengtharticle);
if ($outorigin && !empty($conf->global->PRODUCT_SHOW_ORIGIN_IN_COMBO)) $opt .= ' ('.getCountry($outorigin, 1).')';
$objRef = $objp->ref;
+ if (! empty($objp->custref)) $objRef .= ' (' . $objp->custref . ')';
if (!empty($filterkey) && $filterkey != '') $objRef = preg_replace('/('.preg_quote($filterkey, '/').')/i', '$1 ', $objRef, 1);
$outval .= $objRef;
if ($outbarcode) $outval .= ' ('.$outbarcode.')';
@@ -2727,7 +2731,8 @@ class Form
'duration_unit'=>$outdurationunit,
'pbq'=>$outpbq,
'labeltrans'=>$outlabel_translated,
- 'desctrans'=>$outdesc_translated
+ 'desctrans'=>$outdesc_translated,
+ 'ref_customer'=>$outrefcust
);
}
@@ -5702,14 +5707,17 @@ class Form
$retstring .= ' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
$retstring .= '>';
- // Icone calendrier
- if (!$disabled)
- {
- $retstring .= 'trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');"';
- $retstring .= '>'.img_object($langs->trans("SelectDate"), 'calendarday', 'class="datecallink"').' ';
- } else $retstring .= ''.img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"').' ';
+ $retstringbuttom .= ' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');"';
+ $retstringbuttom .= '>'.img_object($langs->trans("SelectDate"), 'calendarday', 'class="datecallink"').'';
+ } else {
+ $retstringbuttom = ''.img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"').' ';
+ }
+ $retstring = $retstringbuttom.$retstring;
$retstring .= ' '."\n";
$retstring .= ' '."\n";
@@ -5739,7 +5747,7 @@ class Form
if (empty($conf->global->MAIN_POPUP_CALENDAR_ON_FOCUS))
{
$retstring .= "
- showOn: 'button',
+ showOn: 'button', /* both has problem with autocompletion */
buttonImage: '".DOL_URL_ROOT."/theme/".$conf->theme."/img/object_calendarday.png',
buttonImageOnly: true";
}
@@ -5749,7 +5757,7 @@ class Form
}
// Zone de saisie manuelle de la date
- $retstring .= '';
+ $retstring .= '
';
$retstring .= ' ";*/
} else {
- $retstring .= ''.img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"').' ';
+ $retstringbutton = ''.img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"').' ';
+ $retsring = $retstringbutton.$retstring;
}
$retstring .= '
';
@@ -6492,8 +6501,7 @@ class Form
$value = $tmpvalue;
$disabled = ''; $style = '';
}
- if (!empty($disablebademail))
- {
+ if (!empty($disablebademail)) {
if (($disablebademail == 1 && !preg_match('/<.+@.+>/', $value))
|| ($disablebademail == 2 && preg_match('/---/', $value)))
{
@@ -6502,8 +6510,7 @@ class Form
}
}
- if ($key_in_label)
- {
+ if ($key_in_label) {
if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen ?dol_trunc($value, $maxlen) : $value));
else $selectOptionValue = $key.' - '.($maxlen ?dol_trunc($value, $maxlen) : $value);
} else {
diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php
index 512e38072d0..b95f73506b9 100644
--- a/htdocs/core/class/html.formaccounting.class.php
+++ b/htdocs/core/class/html.formaccounting.class.php
@@ -427,7 +427,7 @@ class FormAccounting extends Form
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
- * Return list of auxilary thirdparty accounts
+ * Return list of auxilary accounts. Cumulate list from customers, suppliers and users.
*
* @param string $selectid Preselected pcg_type
* @param string $htmlname Name of field in html form
@@ -435,24 +435,27 @@ class FormAccounting extends Form
* @param string $morecss More css
* @return string String with HTML select
*/
- public function select_auxaccount($selectid, $htmlname = 'account_num_aux', $showempty = 0, $morecss = 'maxwidth200')
+ public function select_auxaccount($selectid, $htmlname = 'account_num_aux', $showempty = 0, $morecss = 'maxwidth250')
{
// phpcs:enable
$aux_account = array();
- // Auxiliary customer account
- $sql = "SELECT DISTINCT code_compta, nom ";
+ // Auxiliary thirdparties account
+ $sql = "SELECT code_compta, code_compta_fournisseur, nom as name";
$sql .= " FROM ".MAIN_DB_PREFIX."societe";
$sql .= " WHERE entity IN (".getEntity('societe').")";
- $sql .= " ORDER BY code_compta";
+ $sql .= " AND client IN (1,3) OR fournisseur = 1";
dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
while ($obj = $this->db->fetch_object($resql)) {
if (!empty($obj->code_compta)) {
- $aux_account[$obj->code_compta] = $obj->code_compta.' ('.$obj->nom.')';
+ $aux_account[$obj->code_compta] = $obj->code_compta.'
('.$obj->name.') ';
+ }
+ if (!empty($obj->code_compta_fournisseur)) {
+ $aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur.'
('.$obj->name.') ';
}
}
} else {
@@ -460,26 +463,9 @@ class FormAccounting extends Form
dol_syslog(get_class($this)."::select_auxaccount ".$this->error, LOG_ERR);
return -1;
}
- $this->db->free($resql);
- // Auxiliary supplier account
- $sql = "SELECT DISTINCT code_compta_fournisseur, nom ";
- $sql .= " FROM ".MAIN_DB_PREFIX."societe";
- $sql .= " WHERE entity IN (".getEntity('societe').")";
- $sql .= " ORDER BY code_compta_fournisseur";
- dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
- $resql = $this->db->query($sql);
- if ($resql) {
- while ($obj = $this->db->fetch_object($resql)) {
- if ($obj->code_compta_fournisseur != "") {
- $aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur.' ('.$obj->nom.')';
- }
- }
- } else {
- $this->error = "Error ".$this->db->lasterror();
- dol_syslog(get_class($this)."::select_auxaccount ".$this->error, LOG_ERR);
- return -1;
- }
+ ksort($aux_account);
+
$this->db->free($resql);
// Auxiliary user account
@@ -492,7 +478,7 @@ class FormAccounting extends Form
if ($resql) {
while ($obj = $this->db->fetch_object($resql)) {
if (!empty($obj->accountancy_code)) {
- $aux_account[$obj->accountancy_code] = $obj->accountancy_code.' ('.dolGetFirstLastname($obj->firstname, $obj->lastname).')';
+ $aux_account[$obj->accountancy_code] = $obj->accountancy_code.'
('.dolGetFirstLastname($obj->firstname, $obj->lastname).') ';
}
}
} else {
diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php
index 26e184eb614..d9d0442e49e 100644
--- a/htdocs/core/class/html.formcompany.class.php
+++ b/htdocs/core/class/html.formcompany.class.php
@@ -829,7 +829,7 @@ class FormCompany extends Form
*
* @param string $selected Preselected value
* @param string $htmlname HTML select name
- * @param string $fields Fields
+ * @param array $fields Array with key of fields to refresh after selection
* @param int $fieldsize Field size
* @param int $disableautocomplete 1 To disable ajax autocomplete features (browser autocomplete may still occurs)
* @param string $moreattrib Add more attribute on HTML input field
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index 3d8f3e72d9e..6c052a3999c 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -391,7 +391,9 @@ class FormMail extends Form
// Define output language
$outputlangs = $langs;
$newlang = '';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $this->param['langsmodels'];
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
+ $newlang = $this->param['langsmodels'];
+ }
if (!empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
@@ -423,13 +425,13 @@ class FormMail extends Form
}
}
- if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
+ if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
$listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
}
- if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
+ if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
$listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
}
- if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
+ if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
$listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
}
@@ -449,7 +451,7 @@ class FormMail extends Form
$out .= '
';
}
}
- foreach ($this->param as $key=>$value) {
+ foreach ($this->param as $key => $value) {
if (is_array($value)) {
$out .= "\n";
} else {
@@ -475,8 +477,12 @@ class FormMail extends Form
// We escape the $labeltouse to store it into $modelmail_array.
$modelmail_array[$line->id] = dol_escape_htmltag($labeltouse);
- if ($line->lang) $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang);
- if ($line->private) $modelmail_array[$line->id] .= ' -
'.dol_escape_htmltag($langs->trans("Private")).' ';
+ if ($line->lang) {
+ $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang);
+ }
+ if ($line->private) {
+ $modelmail_array[$line->id] .= ' -
'.dol_escape_htmltag($langs->trans("Private")).' ';
+ }
}
}
@@ -486,7 +492,9 @@ class FormMail extends Form
$out .= '
'."\n";
$out .= '
'.$langs->trans('SelectMailModel').': ';
$out .= $this->selectarray('modelmailselected', $modelmail_array, 0, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1);
- if ($user->admin) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
+ if ($user->admin) {
+ $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
+ }
$out .= ' ';
$out .= '
';
$out .= ' ';
@@ -499,7 +507,9 @@ class FormMail extends Form
// If list of template is empty
$out .= '
'."\n";
$out .= $langs->trans('SelectMailModel').':
'.$langs->trans("NoTemplateDefined").' '; // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy.
- if ($user->admin) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
+ if ($user->admin) {
+ $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
+ }
$out .= ' ';
$out .= '
';
$out .= ' ';
@@ -513,24 +523,24 @@ class FormMail extends Form
// Substitution array/string
$helpforsubstitution = '';
- if (is_array($this->substit) && count($this->substit)) $helpforsubstitution .= $langs->trans('AvailableVariables').' :
'."\n";
+ if (is_array($this->substit) && count($this->substit)) {
+ $helpforsubstitution .= $langs->trans('AvailableVariables').' :
'."\n";
+ }
foreach ($this->substit as $key => $val) {
$helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText($val))).'
';
}
- if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this.
+ if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this.
$out .= '
';
//$out.='';
- if (is_numeric($this->withsubstit)) $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage
- else $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage
+ if (is_numeric($this->withsubstit)) {
+ $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage
+ } else {
+ $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage
+ }
$out .= "
\n";
//$out.='
';
}
- /*var_dump(! empty($this->withfromreadonly));
- var_dump($this->withfrom);
- var_dump($this->fromtype);
- var_dump($this->fromname);*/
-
// From
if (!empty($this->withfrom)) {
if (!empty($this->withfromreadonly)) {
@@ -609,7 +619,9 @@ class FormMail extends Form
if ($listaliasval) {
$listaliasval = preg_replace('/', '<', $listaliasval);
$listaliasval = preg_replace('/>/', '>', $listaliasval);
- if (!preg_match('/</', $listaliasval)) $listaliasval = '<'.$listaliasval.'>';
+ if (!preg_match('/</', $listaliasval)) {
+ $listaliasval = '<'.$listaliasval.'>';
+ }
$liste[$typealias.'_'.$posalias] = $listaliasval;
}
}
@@ -621,7 +633,9 @@ class FormMail extends Form
if (empty($reshook)) {
$defaultfrom = $this->fromtype;
}
- if (!empty($hookmanager->resArray['defaultfrom'])) $defaultfrom = $hookmanager->resArray['defaultfrom'];
+ if (!empty($hookmanager->resArray['defaultfrom'])) {
+ $defaultfrom = $hookmanager->resArray['defaultfrom'];
+ }
// Using combo here make the '
' no more visible on list.
//$out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
@@ -639,11 +653,13 @@ class FormMail extends Form
}
// To
- if (!empty($this->withto) || is_array($this->withto))
- {
+ if (!empty($this->withto) || is_array($this->withto)) {
$out .= '';
- if ($this->withtofree) $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
- else $out .= $langs->trans("MailTo");
+ if ($this->withtofree) {
+ $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
+ } else {
+ $out .= $langs->trans("MailTo");
+ }
$out .= ' ';
if ($this->withtoreadonly) {
if (!empty($this->toname) && !empty($this->tomail)) {
@@ -675,7 +691,9 @@ class FormMail extends Form
}
// The select combo
if (!empty($this->withto) && is_array($this->withto)) {
- if (!empty($this->withtofree)) $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
+ if (!empty($this->withtofree)) {
+ $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
+ }
// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
$tmparray = $this->withto;
foreach ($tmparray as $key => $val) {
@@ -805,7 +823,8 @@ class FormMail extends Form
$out .= ' ';
- if ($this->withmaindocfile) { // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
+ if ($this->withmaindocfile) {
+ // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
if (GETPOSTISSET('sendmail')) {
$this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
} elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
@@ -836,9 +855,16 @@ class FormMail extends Form
$out .= ''."\n";
if (count($listofpaths)) {
foreach ($listofpaths as $key => $val) {
+ $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val)));
+ if ($conf->entity > 1) {
+ $relativepathtofile = str_replace($conf->entity.'/', '', $relativepathtofile);
+ }
+ // Try to extract data from full path
+ $formfile_params = array();
+ preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params);
+
$out .= '';
// Preview of attachment
- preg_match('#^(/)(\w+)(/)(.+)$#', substr($val, (strlen(DOL_DATA_ROOT) - strlen($val))), $formfile_params);
$out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
$out .= $formfile->showPreview(array(), $formfile_params[2], $formfile_params[4]);
if (!$this->withfilereadonly) {
@@ -847,12 +873,17 @@ class FormMail extends Form
}
$out .= '
';
}
- } elseif (empty($this->withmaindocfile)) { // Do not show message if we asked to show the checkbox
+ } elseif (empty($this->withmaindocfile)) {
+ // Do not show message if we asked to show the checkbox
$out .= $langs->trans("NoAttachedFiles").' ';
}
- if ($this->withfile == 2) { // Can add other files
- if (!empty($conf->global->FROM_MAIL_USE_INPUT_FILE_MULTIPLE)) $out .= ' ';
- else $out .= ' ';
+ if ($this->withfile == 2) {
+ // Can add other files
+ if (!empty($conf->global->FROM_MAIL_USE_INPUT_FILE_MULTIPLE)) {
+ $out .= ' ';
+ } else {
+ $out .= ' ';
+ }
$out .= ' ';
$out .= ' ';
}
@@ -972,8 +1003,11 @@ class FormMail extends Form
// Editor wysiwyg
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
if ($this->withfckeditor == -1) {
- if (!empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $this->withfckeditor = 1;
- else $this->withfckeditor = 0;
+ if (!empty($conf->global->FCKEDITOR_ENABLE_MAIL)) {
+ $this->withfckeditor = 1;
+ } else {
+ $this->withfckeditor = 0;
+ }
}
$doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%');
@@ -1118,10 +1152,18 @@ class FormMail extends Form
$out .= yn($this->withdeliveryreceipt);
} else {
$defaultvaluefordeliveryreceipt = 0;
- if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') $defaultvaluefordeliveryreceipt = 1;
- if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $defaultvaluefordeliveryreceipt = 1;
- if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && !empty($this->param['models']) && $this->param['models'] == 'order_send') $defaultvaluefordeliveryreceipt = 1;
- if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') $defaultvaluefordeliveryreceipt = 1;
+ if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
+ $defaultvaluefordeliveryreceipt = 1;
+ }
+ if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
+ $defaultvaluefordeliveryreceipt = 1;
+ }
+ if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
+ $defaultvaluefordeliveryreceipt = 1;
+ }
+ if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
+ $defaultvaluefordeliveryreceipt = 1;
+ }
$out .= $form->selectyesno('deliveryreceipt', (GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt), 1);
}
$out .= " \n";
@@ -1200,11 +1242,21 @@ class FormMail extends Form
$sql .= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')";
$sql .= " AND entity IN (".getEntity('c_email_templates').")";
$sql .= " AND (private = 0 OR fk_user = ".$user->id.")"; // Get all public or private owned
- if ($active >= 0) $sql .= " AND active = ".$active;
- if ($label) $sql .= " AND label ='".$db->escape($label)."'";
- if (!($id > 0) && $languagetosearch) $sql .= " AND (lang = '".$db->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$db->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')";
- if ($id > 0) $sql .= " AND rowid=".$id;
- if ($id == -1) $sql .= " AND position=0";
+ if ($active >= 0) {
+ $sql .= " AND active = ".$active;
+ }
+ if ($label) {
+ $sql .= " AND label ='".$db->escape($label)."'";
+ }
+ if (!($id > 0) && $languagetosearch) {
+ $sql .= " AND (lang = '".$db->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$db->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')";
+ }
+ if ($id > 0) {
+ $sql .= " AND rowid=".$id;
+ }
+ if ($id == -1) {
+ $sql .= " AND position=0";
+ }
if ($languagetosearch) {
$sql .= $db->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or ''
} else {
@@ -1229,7 +1281,8 @@ class FormMail extends Form
} elseif ($id == -2) {
// Not found with the provided label
return -1;
- } else { // If there is no template at all
+ } else {
+ // If there is no template at all
$defaultmessage = '';
if ($type_template == 'body') {
@@ -1460,7 +1513,7 @@ class FormMail extends Form
$tmparray['__USER_SIGNATURE__'] = 'TagSignature';
$tmparray['__CHECK_READ__'] = 'TagCheckMail';
$tmparray['__UNSUBSCRIBE__'] = 'TagUnsubscribe';
- //,'__PERSONALIZED__' => 'Personalized' // Hidden because not used yet in mass emailing
+ //,'__PERSONALIZED__' => 'Personalized' // Hidden because not used yet in mass emailing
$onlinepaymentenabled = 0;
if (!empty($conf->paypal->enabled)) $onlinepaymentenabled++;
@@ -1469,10 +1522,18 @@ class FormMail extends Form
if ($onlinepaymentenabled && !empty($conf->global->PAYMENT_SECURITY_TOKEN)) {
$tmparray['__SECUREKEYPAYMENT__'] = $conf->global->PAYMENT_SECURITY_TOKEN;
if (!empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) {
- if ($conf->adherent->enabled) $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember';
- if ($conf->facture->enabled) $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice';
- if ($conf->commande->enabled) $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder';
- if ($conf->contrat->enabled) $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine';
+ if ($conf->adherent->enabled) {
+ $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember';
+ }
+ if ($conf->facture->enabled) {
+ $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice';
+ }
+ if ($conf->commande->enabled) {
+ $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder';
+ }
+ if ($conf->contrat->enabled) {
+ $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine';
+ }
}
} else {
/* No need to show into tooltip help, option is not enabled
diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php
index 19965250727..534d6b5803e 100644
--- a/htdocs/core/class/interfaces.class.php
+++ b/htdocs/core/class/interfaces.class.php
@@ -179,20 +179,29 @@ class Interfaces
$objMod = new $modName($this->db);
if ($objMod)
{
+ $dblevelbefore = $this->db->transaction_opened;
+
$result = 0;
- if (method_exists($objMod, 'runTrigger')) // New method to implement
- {
+ if (method_exists($objMod, 'runTrigger')) { // New method to implement
//dol_syslog(get_class($this)."::run_triggers action=".$action." Launch runTrigger for file '".$files[$key]."'", LOG_DEBUG);
$result = $objMod->runTrigger($action, $object, $user, $langs, $conf);
- } elseif (method_exists($objMod, 'run_trigger')) // Deprecated method
- {
+ } elseif (method_exists($objMod, 'run_trigger')) { // Deprecated method
dol_syslog(get_class($this)."::run_triggers action=".$action." Launch old method run_trigger (rename your trigger into runTrigger) for file '".$files[$key]."'", LOG_WARNING);
$result = $objMod->run_trigger($action, $object, $user, $langs, $conf);
} else {
dol_syslog(get_class($this)."::run_triggers action=".$action." A trigger was declared for class ".get_class($objMod)." but method runTrigger was not found", LOG_ERR);
}
+ $dblevelafter = $this->db->transaction_opened;
+
+ if ($dblevelbefore != $dblevelafter) {
+ $errormessage = "Error, the balance begin/close of db transactions has been broken into trigger ".$modName." with action=".$action." before=".$dblevelbefore." after=".$dblevelafter;
+ $this->errors[] = $errormessage;
+ dol_syslog($errormessage, LOG_ERR);
+ $result = -1;
+ }
+
if ($result > 0)
{
// Action OK
diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php
index de19f674659..9f4e69dcadf 100644
--- a/htdocs/core/js/lib_foot.js.php
+++ b/htdocs/core/js/lib_foot.js.php
@@ -65,7 +65,7 @@ print "jQuery(document).ready(function () {\n";
if (empty($conf->dol_no_mouse_hover)) {
print 'jQuery(".classfortooltip").tooltip({
- show: { collision: "flipfit", effect:"toggle", delay:75, duration:150 },
+ show: { collision: "flipfit", effect:"toggle", delay:50, duration: 20 },
hide: { delay: 250, duration: 20 },
tooltipClass: "mytooltip",
content: function () {
diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
index de4e5bcf783..92748f8e26f 100644
--- a/htdocs/core/lib/ajax.lib.php
+++ b/htdocs/core/lib/ajax.lib.php
@@ -139,7 +139,8 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
type: item.type, qty: item.qty, discount: item.discount,
pricebasetype: item.pricebasetype, price_ht: item.price_ht,
price_ttc: item.price_ttc,
- up: item.up, description : item.description}
+ up: item.up, description : item.description,
+ ref_customer: item.ref_customer }
}));
}
else console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
@@ -157,6 +158,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
$("#'.$htmlname.'").attr("data-discount", ui.item.discount);
$("#'.$htmlname.'").attr("data-qty", ui.item.qty);
$("#'.$htmlname.'").attr("data-description", ui.item.description);
+ $("#'.$htmlname.'").attr("data-ref-customer", ui.item.ref_customer);
//For customer price
';
@@ -251,7 +253,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
* This use the jQuery "autocomplete" function.
*
* @param string $htmlname HTML name of input field
- * @param string $fields Other fields to autocomplete
+ * @param array $fields Array of key of fields to autocomplete
* @param string $url URL for ajax request : /chemin/fichier.php
* @param string $option More parameters on URL request
* @param int $minLength Minimum number of chars to trigger that Ajax search
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 8318291753f..6a549c6e95b 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -672,20 +672,28 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options =
if (preg_match('/[^a-z0-9_\-\.,]+/i', $out)) $out = '';
}
break;
- case 'nohtml':
+ case 'nohtml': // No html
$out = dol_string_nohtmltag($out, 0);
break;
- case 'alpha': // No html and no " and no ../
+ case 'alpha': // No html and no ../ and "
case 'alphanohtml': // Recommended for most scalar parameters and search parameters
if (!is_array($out)) {
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
- $out = str_replace(array('"', '"'), "''", trim($out));
+ $out = str_replace(array('"', '"'), '', trim($out));
$out = str_replace(array('../'), '', $out);
// keep lines feed
$out = dol_string_nohtmltag($out, 0);
}
break;
+ case 'alphawithlgt': // No " and no ../ but we keep < > tags. Can be used for email string like "Name "
+ if (!is_array($out)) {
+ // '"' is dangerous because param in url can close the href= or src= and add javascript functions.
+ // '../' is dangerous because it allows dir transversals
+ $out = str_replace(array('"', '"'), '', trim($out));
+ $out = str_replace(array('../'), '', $out);
+ }
+ break;
case 'restricthtml': // Recommended for most html textarea
$out = dol_string_onlythesehtmltags($out, 0, 1, 1);
break;
@@ -5480,6 +5488,10 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer,
$isacompany = $thirdparty_buyer->isACompany();
if ($isacompany)
{
+ if (!empty($conf->global->MAIN_USE_VAT_OF_PRODUCT_FOR_COMPANIES_IN_EEC_WITH_INVALID_VAT_ID) && !isValidVATID($thirdparty_buyer)) {
+ //print 'VATRULE 6';
+ return get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice);
+ }
//print 'VATRULE 3';
return 0;
} else {
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 6e4cc60ce53..613a68b56d8 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -1236,6 +1236,10 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0,
} else {
include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
$prodser = new Product($db);
+
+ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
+ include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+ }
}
if ($idprod)
@@ -1375,6 +1379,32 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0,
}
} else {
$ref_prodserv = $prodser->ref; // Show local ref only
+
+ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
+ $productCustomerPriceStatic = new Productcustomerprice($db);
+ $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
+
+ $nbCustomerPrices = $productCustomerPriceStatic->fetch_all('', '', 1, 0, $filter);
+
+ if ($nbCustomerPrices > 0) {
+ $productCustomerPrice = $productCustomerPriceStatic->lines[0];
+
+ if (! empty($productCustomerPrice->ref_customer)) {
+ switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
+ case 1:
+ $ref_prodserv = $productCustomerPrice->ref_customer;
+ break;
+
+ case 2:
+ $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
+ break;
+
+ default:
+ $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
+ }
+ }
+ }
+ }
}
if (!empty($libelleproduitservice) && !empty($ref_prodserv)) $ref_prodserv .= " - ";
diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php
new file mode 100755
index 00000000000..5f55e2b2207
--- /dev/null
+++ b/htdocs/core/modules/modWorkstation.class.php
@@ -0,0 +1,520 @@
+
+ * Copyright (C) 2018-2019 Nicolas ZABOURI
+ * Copyright (C) 2019-2020 Frédéric France
+ * Copyright (C) 2020 Gauthier VERDOL
+ *
+ * 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 .
+ */
+
+/**
+ * \defgroup workstation Module Workstation
+ * \brief Workstation module descriptor.
+ *
+ * \file htdocs/workstation/core/modules/modWorkstation.class.php
+ * \ingroup workstation
+ * \brief Description and activation file for module Workstation
+ */
+include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
+
+/**
+ * Description and activation class for module Workstation
+ */
+class modWorkstation extends DolibarrModules
+{
+ /**
+ * Constructor. Define names, constants, directories, boxes, permissions
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $langs, $conf;
+ $this->db = $db;
+
+ // Id for module (must be unique).
+ // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
+ $this->numero = 500000; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve an id number for your module
+ // Key text used to identify module (for permissions, menus, etc...)
+ $this->rights_class = 'workstation';
+ // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
+ // It is used to group modules by family in module setup page
+ $this->family = "other";
+ // Module position in the family on 2 digits ('01', '10', '20', ...)
+ $this->module_position = '90';
+ // Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
+ //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
+ // Module label (no space allowed), used if translation string 'ModuleWorkstationName' not found (Workstation is name of module).
+ $this->name = preg_replace('/^mod/i', '', get_class($this));
+ // Module description, used if translation string 'ModuleWorkstationDesc' not found (Workstation is name of module).
+ $this->description = "WorkstationsDescription";
+ // Used only if file README.md and README-LL.md not found.
+ $this->descriptionlong = "WorkstationsDescription";
+ // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
+ $this->version = 'development';
+ // Url to the file with your last numberversion of this module
+ //$this->url_last_version = 'http://www.example.com/versionmodule.txt';
+
+ // Key used in llx_const table to save module status enabled/disabled (where WORKSTATION is value of property name of module in uppercase)
+ $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
+ // Name of image file used for this module.
+ // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
+ // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
+ $this->picto = 'mrp';
+ // Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
+ $this->module_parts = array(
+ // Set this to 1 if module has its own trigger directory (core/triggers)
+ 'triggers' => 0,
+ // Set this to 1 if module has its own login method file (core/login)
+ 'login' => 0,
+ // Set this to 1 if module has its own substitution function file (core/substitutions)
+ 'substitutions' => 0,
+ // Set this to 1 if module has its own menus handler directory (core/menus)
+ 'menus' => 0,
+ // Set this to 1 if module overwrite template dir (core/tpl)
+ 'tpl' => 0,
+ // Set this to 1 if module has its own barcode directory (core/modules/barcode)
+ 'barcode' => 0,
+ // Set this to 1 if module has its own models directory (core/modules/xxx)
+ 'models' => 1,
+ // Set this to 1 if module has its own printing directory (core/modules/printing)
+ 'printing' => 0,
+ // Set this to 1 if module has its own theme directory (theme)
+ 'theme' => 0,
+ // Set this to relative path of css file if module has its own css file
+ 'css' => array(
+ // '/workstation/css/workstation.css.php',
+ ),
+ // Set this to relative path of js file if module must load a js on all pages
+ 'js' => array(
+ // '/workstation/js/workstation.js.php',
+ ),
+ // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context to 'all'
+ 'hooks' => array(
+ // 'data' => array(
+ // 'hookcontext1',
+ // 'hookcontext2',
+ // ),
+ // 'entity' => '0',
+ ),
+ // Set this to 1 if features of module are opened to external users
+ 'moduleforexternal' => 0,
+ );
+ // Data directories to create when module is enabled.
+ // Example: this->dirs = array("/workstation/temp","/workstation/subdir");
+ $this->dirs = array("/workstation/temp");
+ // Config pages. Put here list of php page, stored into workstation/admin directory, to use to setup module.
+ $this->config_page_url = array("workstation.php");
+ // Dependencies
+ // A condition to hide module
+ $this->hidden = false;
+ // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...)
+ $this->depends = array();
+ $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
+ $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...)
+ $this->langfiles = array("mrp");
+ $this->phpmin = array(5, 5); // Minimum version of PHP required by module
+ $this->need_dolibarr_version = array(11, -3); // Minimum version of Dolibarr required by module
+ $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
+ $this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
+ //$this->automatic_activation = array('FR'=>'WorkstationWasAutomaticallyActivatedBecauseOfYourCountryChoice');
+ //$this->always_enabled = true; // If true, can't be disabled
+
+ // Constants
+ // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
+ // Example: $this->const=array(1 => array('WORKSTATION_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1),
+ // 2 => array('WORKSTATION_MYNEWCONST2', 'chaine', 'myvalue', 'This is another constant to add', 0, 'current', 1)
+ // );
+ $this->const = array();
+
+ // Some keys to add into the overwriting translation tables
+ /*$this->overwrite_translation = array(
+ 'en_US:ParentCompany'=>'Parent company or reseller',
+ 'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
+ )*/
+
+ if (!isset($conf->workstation) || !isset($conf->workstation->enabled)) {
+ $conf->workstation = new stdClass();
+ $conf->workstation->enabled = 0;
+ }
+
+ // Array to add new pages in new tabs
+ $this->tabs = array();
+ // Example:
+ // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@workstation:$user->rights->workstation->read:/workstation/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1
+ // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@workstation:$user->rights->othermodule->read:/workstation/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
+ // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname
+ //
+ // Where objecttype can be
+ // 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
+ // 'contact' to add a tab in contact view
+ // 'contract' to add a tab in contract view
+ // 'group' to add a tab in group view
+ // 'intervention' to add a tab in intervention view
+ // 'invoice' to add a tab in customer invoice view
+ // 'invoice_supplier' to add a tab in supplier invoice view
+ // 'member' to add a tab in fundation member view
+ // 'opensurveypoll' to add a tab in opensurvey poll view
+ // 'order' to add a tab in customer order view
+ // 'order_supplier' to add a tab in supplier order view
+ // 'payment' to add a tab in payment view
+ // 'payment_supplier' to add a tab in supplier payment view
+ // 'product' to add a tab in product view
+ // 'propal' to add a tab in propal view
+ // 'project' to add a tab in project view
+ // 'stock' to add a tab in stock view
+ // 'thirdparty' to add a tab in third party view
+ // 'user' to add a tab in user view
+
+ // Dictionaries
+ $this->dictionaries = array();
+ /* Example:
+ $this->dictionaries=array(
+ 'langs'=>'workstation@workstation',
+ // List of tables we want to see into dictonnary editor
+ 'tabname'=>array(MAIN_DB_PREFIX."table1", MAIN_DB_PREFIX."table2", MAIN_DB_PREFIX."table3"),
+ // Label of tables
+ 'tablib'=>array("Table1", "Table2", "Table3"),
+ // Request to select fields
+ 'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),
+ // Sort order
+ 'tabsqlsort'=>array("label ASC", "label ASC", "label ASC"),
+ // List of fields (result of select to show dictionary)
+ 'tabfield'=>array("code,label", "code,label", "code,label"),
+ // List of fields (list of fields to edit a record)
+ 'tabfieldvalue'=>array("code,label", "code,label", "code,label"),
+ // List of fields (list of fields for insert)
+ 'tabfieldinsert'=>array("code,label", "code,label", "code,label"),
+ // Name of columns with primary key (try to always name it 'rowid')
+ 'tabrowid'=>array("rowid", "rowid", "rowid"),
+ // Condition to show each dictionary
+ 'tabcond'=>array($conf->workstation->enabled, $conf->workstation->enabled, $conf->workstation->enabled)
+ );
+ */
+
+ // Boxes/Widgets
+ // Add here list of php file(s) stored in workstation/core/boxes that contains a class to show a widget.
+ $this->boxes = array(
+ // 0 => array(
+ // 'file' => 'workstationwidget1.php@workstation',
+ // 'note' => 'Widget provided by Workstation',
+ // 'enabledbydefaulton' => 'Home',
+ // ),
+ // ...
+ );
+
+ // Cronjobs (List of cron jobs entries to add when module is enabled)
+ // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
+ $this->cronjobs = array(
+ // 0 => array(
+ // 'label' => 'MyJob label',
+ // 'jobtype' => 'method',
+ // 'class' => '/workstation/class/workstation.class.php',
+ // 'objectname' => 'Workstation',
+ // 'method' => 'doScheduledJob',
+ // 'parameters' => '',
+ // 'comment' => 'Comment',
+ // 'frequency' => 2,
+ // 'unitfrequency' => 3600,
+ // 'status' => 0,
+ // 'test' => '$conf->workstation->enabled',
+ // 'priority' => 50,
+ // ),
+ );
+ // Example: $this->cronjobs=array(
+ // 0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->workstation->enabled', 'priority'=>50),
+ // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->workstation->enabled', 'priority'=>50)
+ // );
+
+ // Permissions provided by this module
+ $this->rights = array();
+ $r = 0;
+ // Add here entries to declare new permissions
+ /* BEGIN MODULEBUILDER PERMISSIONS */
+ $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
+ $this->rights[$r][1] = 'Read objects of Workstation'; // Permission label
+ $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->workstation->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 Workstation'; // Permission label
+ $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $r++;
+ $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
+ $this->rights[$r][1] = 'Delete objects of Workstation'; // Permission label
+ $this->rights[$r][4] = 'workstation'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->workstation->level1->level2)
+ $r++;
+ /* END MODULEBUILDER PERMISSIONS */
+
+ // Main menu entries to add
+ $this->menu = array();
+ $r = 0;
+ // Add here entries to declare new menus
+ /* BEGIN MODULEBUILDER TOPMENU */
+ /*$this->menu[$r++] = array(
+ 'fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'top', // This is a Top menu entry
+ 'titre'=>$langs->trans('GPAO'),
+ 'mainmenu'=>'gpao',
+ 'leftmenu'=>'',
+ 'url'=>'/workstation/workstationindex.php',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000 + $r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'1', // Use 'perms'=>'$user->rights->workstation->workstation->read' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );*/
+ /* END MODULEBUILDER TOPMENU */
+ /* BEGIN MODULEBUILDER LEFTMENU WORKSTATION
+ $this->menu[$r++]=array(
+ 'fk_menu'=>'fk_mainmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'left', // This is a Top menu entry
+ 'titre'=>'Workstation',
+ 'mainmenu'=>'workstation',
+ 'leftmenu'=>'workstation',
+ 'url'=>'/workstation/workstationindex.php',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000+$r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'$user->rights->workstation->workstation->read', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );
+ $this->menu[$r++]=array(
+ 'fk_menu'=>'fk_mainmenu=workstation,fk_leftmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'left', // This is a Left menu entry
+ 'titre'=>'List_Workstation',
+ 'mainmenu'=>'workstation',
+ 'leftmenu'=>'workstation_workstation_list',
+ 'url'=>'/workstation/workstation_list.php',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000+$r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'perms'=>'$user->rights->workstation->workstation->read', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );
+ $this->menu[$r++]=array(
+ 'fk_menu'=>'fk_mainmenu=workstation,fk_leftmenu=workstation', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'type'=>'left', // This is a Left menu entry
+ 'titre'=>'New_Workstation',
+ 'mainmenu'=>'workstation',
+ 'leftmenu'=>'workstation_workstation_new',
+ 'url'=>'/workstation/workstation_card.php?action=create',
+ 'langs'=>'workstation@workstation', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>1000+$r,
+ 'enabled'=>'$conf->workstation->enabled', // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'perms'=>'$user->rights->workstation->workstation->write', // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
+ );
+ */
+
+ $this->menu[$r++]=array(
+ // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'fk_menu'=>'fk_mainmenu=mrp',
+ // This is a Left menu entry
+ 'type'=>'left',
+ 'titre'=>$langs->trans('Workstations'),
+ 'mainmenu'=>'mrp',
+ 'leftmenu'=>'workstation_workstation',
+ 'url'=>'',
+ // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'langs'=>'mrp',
+ 'position'=>1100+$r,
+ // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'enabled'=>'$conf->workstation->enabled',
+ // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'perms'=>'$user->rights->workstation->workstation->read',
+ 'target'=>'',
+ // 0=Menu for internal users, 1=external users, 2=both
+ 'user'=>2,
+ );
+ $this->menu[$r++]=array(
+ // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'fk_menu'=>'fk_mainmenu=mrp,fk_leftmenu=workstation_workstation',
+ // This is a Left menu entry
+ 'type'=>'left',
+ 'titre'=>$langs->trans('WorkstationCreate'),
+ 'mainmenu'=>'mrp',
+ 'leftmenu'=>'workstation_workstation_left_create',
+ 'url'=>'/workstation/workstation_card.php?action=create',
+ // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'langs'=>'mrp',
+ 'position'=>1100+$r,
+ // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'enabled'=>'$conf->workstation->enabled',
+ // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'perms'=>'$user->rights->workstation->workstation->write',
+ 'target'=>'',
+ // 0=Menu for internal users, 1=external users, 2=both
+ 'user'=>2
+ );
+ $this->menu[$r++]=array(
+ // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+ 'fk_menu'=>'fk_mainmenu=mrp,fk_leftmenu=workstation_workstation',
+ // This is a Left menu entry
+ 'type'=>'left',
+ 'titre'=>$langs->trans('List'),
+ 'mainmenu'=>'mrp',
+ 'leftmenu'=>'workstation_workstation_left_list',
+ 'url'=>'/workstation/workstation_list.php',
+ // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'langs'=>'mrp',
+ 'position'=>1101+$r,
+ // Define condition to show or hide menu entry. Use '$conf->workstation->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'enabled'=>'$conf->workstation->enabled',
+ // Use 'perms'=>'$user->rights->workstation->level1->level2' if you want your menu with a permission rules
+ 'perms'=>'$user->rights->workstation->workstation->read',
+ 'target'=>'',
+ // 0=Menu for internal users, 1=external users, 2=both
+ 'user'=>2
+ );
+
+ /* END MODULEBUILDER LEFTMENU WORKSTATION */
+ // Exports profiles provided by this module
+ $r = 1;
+ /* BEGIN MODULEBUILDER EXPORT WORKSTATION */
+ /*
+ $langs->load("workstation@workstation");
+ $this->export_code[$r]=$this->rights_class.'_'.$r;
+ $this->export_label[$r]='WorkstationLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_icon[$r]='workstation@workstation';
+ // Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
+ $keyforclass = 'Workstation'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ //$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
+ //unset($this->export_fields_array[$r]['t.fieldtoremove']);
+ //$keyforclass = 'WorkstationLine'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstationline@workstation'; $keyforalias='tl';
+ //include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ $keyforselect='workstation'; $keyforaliasextra='extra'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$keyforselect='workstationline'; $keyforaliasextra='extraline'; $keyforelement='workstationline@workstation';
+ //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$this->export_dependencies_array[$r] = array('workstationline'=>array('tl.rowid','tl.ref')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
+ //$this->export_special_array[$r] = array('t.field'=>'...');
+ //$this->export_examplevalues_array[$r] = array('t.field'=>'Example');
+ //$this->export_help_array[$r] = array('t.field'=>'FieldDescHelp');
+ $this->export_sql_start[$r]='SELECT DISTINCT ';
+ $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'workstation as t';
+ //$this->export_sql_end[$r] =' LEFT JOIN '.MAIN_DB_PREFIX.'workstation_line as tl ON tl.fk_workstation = t.rowid';
+ $this->export_sql_end[$r] .=' WHERE 1 = 1';
+ $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('workstation').')';
+ $r++; */
+ /* END MODULEBUILDER EXPORT WORKSTATION */
+
+ // Imports profiles provided by this module
+ $r = 1;
+ /* BEGIN MODULEBUILDER IMPORT WORKSTATION */
+ /*
+ $langs->load("workstation@workstation");
+ $this->export_code[$r]=$this->rights_class.'_'.$r;
+ $this->export_label[$r]='WorkstationLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_icon[$r]='workstation@workstation';
+ $keyforclass = 'Workstation'; $keyforclassfile='/workstation/class/workstation.class.php'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ $keyforselect='workstation'; $keyforaliasextra='extra'; $keyforelement='workstation@workstation';
+ include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
+ $this->export_sql_start[$r]='SELECT DISTINCT ';
+ $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'workstation as t';
+ $this->export_sql_end[$r] .=' WHERE 1 = 1';
+ $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('workstation').')';
+ $r++; */
+ /* END MODULEBUILDER IMPORT WORKSTATION */
+ }
+
+ /**
+ * Function called when module is enabled.
+ * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
+ * It also creates data directories
+ *
+ * @param string $options Options when enabling module ('', 'noboxes')
+ * @return int 1 if OK, 0 if KO
+ */
+ public function init($options = '')
+ {
+ global $conf, $langs;
+
+ $result = $this->_load_tables('/workstation/sql/');
+ if ($result < 0) return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default')
+
+ // Create extrafields during init
+ //include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+ //$extrafields = new ExtraFields($this->db);
+ //$result1=$extrafields->addExtraField('workstation_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result2=$extrafields->addExtraField('workstation_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result3=$extrafields->addExtraField('workstation_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result4=$extrafields->addExtraField('workstation_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+ //$result5=$extrafields->addExtraField('workstation_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'workstation@workstation', '$conf->workstation->enabled');
+
+ // Permissions
+ $this->remove($options);
+
+ $sql = array();
+
+ // Document templates
+ $moduledir = 'workstation';
+ $myTmpObjects = array();
+ $myTmpObjects['Workstation'] = array('includerefgeneration'=>0, 'includedocgeneration'=>0);
+
+ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
+ if ($myTmpObjectKey == 'Workstation') continue;
+ if ($myTmpObjectArray['includerefgeneration']) {
+ $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/workstation/template_workstations.odt';
+ $dirodt = DOL_DATA_ROOT.'/doctemplates/workstation';
+ $dest = $dirodt.'/template_workstations.odt';
+
+ if (file_exists($src) && !file_exists($dest))
+ {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+ dol_mkdir($dirodt);
+ $result = dol_copy($src, $dest, 0, 0);
+ if ($result < 0)
+ {
+ $langs->load("errors");
+ $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
+ return 0;
+ }
+ }
+
+ $sql = array_merge($sql, array(
+ "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'standard_".strtolower($myTmpObjectKey)."' AND type = '".strtolower($myTmpObjectKey)."' AND entity = ".$conf->entity,
+ "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('standard_".strtolower($myTmpObjectKey)."','".strtolower($myTmpObjectKey)."',".$conf->entity.")",
+ "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'generic_".strtolower($myTmpObjectKey)."_odt' AND type = '".strtolower($myTmpObjectKey)."' AND entity = ".$conf->entity,
+ "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('generic_".strtolower($myTmpObjectKey)."_odt', '".strtolower($myTmpObjectKey)."', ".$conf->entity.")"
+ ));
+ }
+ }
+
+ return $this->_init($sql, $options);
+ }
+
+ /**
+ * Function called when module is disabled.
+ * Remove from database constants, boxes and permissions from Dolibarr database.
+ * Data directories are not deleted
+ *
+ * @param string $options Options when enabling module ('', 'noboxes')
+ * @return int 1 if OK, 0 if KO
+ */
+ public function remove($options = '')
+ {
+ $sql = array();
+ return $this->_remove($sql, $options);
+ }
+}
diff --git a/htdocs/core/modules/workstation/mod_workstation_advanced.php b/htdocs/core/modules/workstation/mod_workstation_advanced.php
new file mode 100755
index 00000000000..cf9a1247e2b
--- /dev/null
+++ b/htdocs/core/modules/workstation/mod_workstation_advanced.php
@@ -0,0 +1,151 @@
+
+ * Copyright (C) 2004-2007 Laurent Destailleur
+ * Copyright (C) 2005-2009 Regis Houssin
+ * Copyright (C) 2008 Raphael Bertrand (Resultic)
+ * Copyright (C) 2019 Frédéric France
+ * Copyright (C) 2020 Gauthier VERDOL
+ *
+ * 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 .
+ * or see https://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/workstation/mod_workstation_advanced.php
+ * \ingroup workstation
+ * \brief File containing class for advanced numbering model of Workstation
+ */
+
+require_once DOL_DOCUMENT_ROOT . '/core/modules/workstation/modules_workstation.php';
+
+
+/**
+ * Class to manage customer Bom numbering rules advanced
+ */
+class mod_workstation_advanced extends ModeleNumRefWorkstation
+{
+ /**
+ * Dolibarr version of the loaded document
+ * @var string
+ */
+ public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
+
+ /**
+ * @var string Error message
+ */
+ public $error = '';
+
+ /**
+ * @var string name
+ */
+ public $name = 'advanced';
+
+
+ /**
+ * Returns the description of the numbering model
+ *
+ * @return string Texte descripif
+ */
+ public function info()
+ {
+ global $conf, $langs, $db;
+
+ $langs->load("bills");
+
+ $form = new Form($db);
+
+ $texte = $langs->trans('GenericNumRefModelDesc')." \n";
+ $texte .= '';
+
+ return $texte;
+ }
+
+ /**
+ * Return an example of numbering
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ global $conf, $db, $langs, $mysoc;
+
+ $object = new Workstation($db);
+ $object->initAsSpecimen();
+
+ /*$old_code_client = $mysoc->code_client;
+ $old_code_type = $mysoc->typent_code;
+ $mysoc->code_client = 'CCCCCCCCCC';
+ $mysoc->typent_code = 'TTTTTTTTTT';*/
+
+ $numExample = $this->getNextValue($object);
+
+ /*$mysoc->code_client = $old_code_client;
+ $mysoc->typent_code = $old_code_type;*/
+
+ if (!$numExample)
+ {
+ $numExample = $langs->trans('NotConfigured');
+ }
+ return $numExample;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ public function getNextValue($object)
+ {
+ global $db, $conf;
+
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+
+ // We get cursor rule
+ $mask = $conf->global->WORKSTATION_WORKSTATION_ADVANCED_MASK;
+
+ if (!$mask)
+ {
+ $this->error = 'NotConfigured';
+ return 0;
+ }
+
+ $date = $object->date;
+
+ $numFinal = get_next_value($db, $mask, 'workstation_workstation', 'ref', '', null, $date);
+
+ return $numFinal;
+ }
+}
diff --git a/htdocs/core/modules/workstation/mod_workstation_standard.php b/htdocs/core/modules/workstation/mod_workstation_standard.php
new file mode 100755
index 00000000000..0e793953f46
--- /dev/null
+++ b/htdocs/core/modules/workstation/mod_workstation_standard.php
@@ -0,0 +1,152 @@
+
+ * Copyright (C) 2005-2009 Regis Houssin
+ * Copyright (C) 2020 Gauthier VERDOL
+ *
+ * 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 .
+ * or see https://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/workstation/mod_workstation_standard.php
+ * \ingroup workstation
+ * \brief File of class to manage Workstation numbering rules standard
+ */
+require_once DOL_DOCUMENT_ROOT . '/core/modules/workstation/modules_workstation.php';
+
+/**
+ * Class to manage customer order numbering rules standard
+ */
+class mod_workstation_standard extends ModeleNumRefWorkstation
+{
+ /**
+ * Dolibarr version of the loaded document
+ * @var string
+ */
+ public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
+
+ public $prefix = 'WORKSTATION';
+
+ /**
+ * @var string Error code (or message)
+ */
+ public $error = '';
+
+ /**
+ * @var string name
+ */
+ public $name = 'standard';
+
+
+ /**
+ * Return description of numbering module
+ *
+ * @return string Text with description
+ */
+ public function info()
+ {
+ global $langs;
+ return $langs->trans("SimpleNumRefModelDesc", $this->prefix);
+ }
+
+
+ /**
+ * Return an example of numbering
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ return $this->prefix."0501-0001";
+ }
+
+
+ /**
+ * Checks if the numbers already in the database do not
+ * cause conflicts that would prevent this numbering working.
+ *
+ * @param Object $object Object we need next value for
+ * @return boolean false if conflict, true if ok
+ */
+ public function canBeActivated($object)
+ {
+ global $conf, $langs, $db;
+
+ $coyymm = ''; $max = '';
+
+ $posindice = strlen($this->prefix) + 6;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql .= " FROM ".MAIN_DB_PREFIX."workstation_workstation";
+ $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
+ if ($object->ismultientitymanaged == 1) {
+ $sql .= " AND entity = ".$conf->entity;
+ } elseif ($object->ismultientitymanaged == 2) {
+ // TODO
+ }
+
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $row = $db->fetch_row($resql);
+ if ($row) { $coyymm = substr($row[0], 0, 6); $max = $row[0]; }
+ }
+ if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm))
+ {
+ $langs->load("errors");
+ $this->error = $langs->trans('ErrorNumRefModel', $max);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ public function getNextValue($object)
+ {
+ global $db, $conf;
+
+ // First we get the max value
+ $posindice = strlen($this->prefix) + 6;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql .= " FROM ".MAIN_DB_PREFIX."workstation_workstation";
+ $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
+ //$sql .= " AND entity = ".$conf->entity;
+
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $obj = $db->fetch_object($resql);
+ if ($obj) $max = intval($obj->max);
+ else $max = 0;
+ } else {
+ dol_syslog("mod_workstation_standard::getNextValue", LOG_DEBUG);
+ return -1;
+ }
+
+ //$date=time();
+ $date = dol_now();
+ $yymm = strftime("%y%m", $date);
+
+ if ($max >= (pow(10, 4) - 1)) $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is
+ else $num = sprintf("%04s", $max + 1);
+
+ dol_syslog("mod_workstation_standard::getNextValue return ".$this->prefix.$yymm."-".$num);
+ return $this->prefix.$yymm."-".$num;
+ }
+}
diff --git a/htdocs/core/modules/workstation/modules_workstation.php b/htdocs/core/modules/workstation/modules_workstation.php
new file mode 100755
index 00000000000..ec6c2fc945b
--- /dev/null
+++ b/htdocs/core/modules/workstation/modules_workstation.php
@@ -0,0 +1,151 @@
+
+ * Copyright (C) 2004-2011 Laurent Destailleur
+ * Copyright (C) 2004 Eric Seigne
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2006 Andre Cianfarani
+ * Copyright (C) 2012 Juanjo Menent
+ * Copyright (C) 2014 Marcos GarcÃa
+ * Copyright (C) 2020 Gauthier VERDOL
+ *
+ * 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 .
+ * or see https://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/workstation/modules_workstation.php
+ * \ingroup workstation
+ * \brief File that contains parent class for workstations document models and parent class for workstations numbering models
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
+require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // required for use by classes that inherit
+
+
+/**
+ * Parent class for documents models
+ */
+abstract class ModelePDFWorkstation extends CommonDocGenerator
+{
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Return list of active generation modules
+ *
+ * @param DoliDB $db Database handler
+ * @param integer $maxfilenamelength Max length of value to show
+ * @return array List of templates
+ */
+ public static function liste_modeles($db, $maxfilenamelength = 0)
+ {
+ // phpcs:enable
+ global $conf;
+
+ $type = 'workstation';
+ $list = array();
+
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+ $list = getListOfModels($db, $type, $maxfilenamelength);
+
+ return $list;
+ }
+}
+
+
+
+/**
+ * Parent class to manage numbering of Workstation
+ */
+abstract class ModeleNumRefWorkstation
+{
+ /**
+ * @var string Error code (or message)
+ */
+ public $error = '';
+
+ /**
+ * Return if a module can be used or not
+ *
+ * @return boolean true if module can be used
+ */
+ public function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Returns the default description of the numbering template
+ *
+ * @return string Texte descripif
+ */
+ public function info()
+ {
+ global $langs;
+ $langs->load("workstation@workstation");
+ return $langs->trans("NoDescription");
+ }
+
+ /**
+ * Returns an example of numbering
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ global $langs;
+ $langs->load("workstation@workstation");
+ return $langs->trans("NoExample");
+ }
+
+ /**
+ * Checks if the numbers already in the database do not
+ * cause conflicts that would prevent this numbering working.
+ *
+ * @param Object $object Object we need next value for
+ * @return boolean false if conflict, true if ok
+ */
+ public function canBeActivated($object)
+ {
+ return true;
+ }
+
+ /**
+ * Returns next assigned value
+ *
+ * @param Object $object Object we need next value for
+ * @return string Valeur
+ */
+ public function getNextValue($object)
+ {
+ global $langs;
+ return $langs->trans("NotAvailable");
+ }
+
+ /**
+ * Returns version of numbering module
+ *
+ * @return string Valeur
+ */
+ public function getVersion()
+ {
+ global $langs;
+ $langs->load("admin");
+
+ if ($this->version == 'development') return $langs->trans("VersionDevelopment");
+ if ($this->version == 'experimental') return $langs->trans("VersionExperimental");
+ if ($this->version == 'dolibarr') return DOL_VERSION;
+ if ($this->version) return $this->version;
+ return $langs->trans("NotAvailable");
+ }
+}
diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php
index 92a767a23ea..5d3381b2719 100644
--- a/htdocs/core/tpl/card_presend.tpl.php
+++ b/htdocs/core/tpl/card_presend.tpl.php
@@ -196,7 +196,7 @@ if ($action == 'presend')
}
$formmail->withto = $liste;
- $formmail->withtofree = (GETPOSTISSET('sendto') ? (GETPOST('sendto') ? GETPOST('sendto') : '1') : '1');
+ $formmail->withtofree = (GETPOSTISSET('sendto') ? (GETPOST('sendto', 'alphawithlgt') ? GETPOST('sendto', 'alphawithlgt') : '1') : '1');
$formmail->withtocc = $liste;
$formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC;
$formmail->withtopic = $topicmail;
diff --git a/htdocs/core/tpl/commonfields_add.tpl.php b/htdocs/core/tpl/commonfields_add.tpl.php
index f21ff31f7a6..388b4b63926 100644
--- a/htdocs/core/tpl/commonfields_add.tpl.php
+++ b/htdocs/core/tpl/commonfields_add.tpl.php
@@ -55,6 +55,7 @@ foreach ($object->fields as $key => $val)
print '';
if (!empty($val['picto'])) { print img_picto('', $val['picto']); }
if (in_array($val['type'], array('int', 'integer'))) $value = GETPOST($key, 'int');
+ elseif ($val['type'] == 'double') $value = price2num(GETPOST($key, 'alphanohtml'));
elseif ($val['type'] == 'text' || $val['type'] == 'html') $value = GETPOST($key, 'restricthtml');
elseif ($val['type'] == 'date') $value = dol_mktime(12, 0, 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'));
elseif ($val['type'] == 'datetime') $value = dol_mktime(GETPOST($key.'hour', 'int'), GETPOST($key.'min', 'int'), 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'));
diff --git a/htdocs/core/tpl/commonfields_edit.tpl.php b/htdocs/core/tpl/commonfields_edit.tpl.php
index 946d8c0b504..76a9fafe417 100644
--- a/htdocs/core/tpl/commonfields_edit.tpl.php
+++ b/htdocs/core/tpl/commonfields_edit.tpl.php
@@ -53,6 +53,7 @@ foreach ($object->fields as $key => $val)
print ' ';
if (!empty($val['picto'])) { print img_picto('', $val['picto']); }
if (in_array($val['type'], array('int', 'integer'))) $value = GETPOSTISSET($key) ?GETPOST($key, 'int') : $object->$key;
+ elseif ($val['type'] == 'double') $value = GETPOSTISSET($key) ? price2num(GETPOST($key, 'alphanohtml')) : $object->$key;
elseif (preg_match('/^(text|html)/', $val['type'])) {
$tmparray = explode(':', $val['type']);
if (!empty($tmparray[1])) {
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index 5464116c1ed..ee8fa746107 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -891,11 +891,17 @@ class CommandeFournisseur extends CommonOrder
* Class invoiced the supplier order
*
* @param User $user Object user making the change
- * @return int <0 if KO, >0 if KO
+ * @return int <0 if KO, 0 if already billed, >0 if OK
*/
public function classifyBilled(User $user)
{
$error = 0;
+
+ if ($this->billed)
+ {
+ return 0;
+ }
+
$this->db->begin();
$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur SET billed = 1';
diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
index c3ed206c9c1..c00e1d2d6e2 100644
--- a/htdocs/fourn/commande/card.php
+++ b/htdocs/fourn/commande/card.php
@@ -1610,7 +1610,7 @@ if ($action == 'create')
print $societe->getNomUrl(1);
print ' ';
} else {
- print $form->select_company((empty($socid) ? '' : $socid), 'socid', 's.fournisseur=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
+ print img_picto('', 'company').$form->select_company((empty($socid) ? '' : $socid), 'socid', 's.fournisseur=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
// reload page to retrieve customer informations
if (!empty($conf->global->RELOAD_PAGE_ON_SUPPLIER_CHANGE))
{
@@ -1672,6 +1672,7 @@ if ($action == 'create')
{
$langs->load("bank");
print ' '.$langs->trans('BankAccount').' ';
+ print img_picto('', 'bank_account', 'class="paddingrightonly"');
$form->select_comptes($fk_account, 'fk_account', 0, '', 1);
print ' ';
}
@@ -1683,7 +1684,7 @@ if ($action == 'create')
$langs->load('projects');
print ''.$langs->trans('Project').' ';
- $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth500');
+ print img_picto('', 'project').$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
print ' id).'"> ';
print ' ';
}
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index 8b4e55a6872..24b35896498 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -656,10 +656,10 @@ if (empty($reshook))
if ($ret < 0) $error++;
$dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
- $datedue = dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear']);
+ $datedue = dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'));
// Replacement invoice
- if ($_POST['type'] == FactureFournisseur::TYPE_REPLACEMENT)
+ if (GETPOST('type') == FactureFournisseur::TYPE_REPLACEMENT)
{
if (empty($dateinvoice)) {
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
@@ -713,7 +713,7 @@ if (empty($reshook))
}
// Credit note invoice
- if ($_POST['type'] == FactureFournisseur::TYPE_CREDIT_NOTE)
+ if (GETPOST('type') == FactureFournisseur::TYPE_CREDIT_NOTE)
{
$sourceinvoice = GETPOST('fac_avoir', 'int');
if (!($sourceinvoice > 0) && empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE))
@@ -837,7 +837,7 @@ if (empty($reshook))
}
// Standard or deposit
- if ($_POST['type'] == FactureFournisseur::TYPE_STANDARD || $_POST['type'] == FactureFournisseur::TYPE_DEPOSIT)
+ if (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)
{
if (GETPOST('socid', 'int') < 1)
{
@@ -869,11 +869,12 @@ if (empty($reshook))
{
$tmpproject = GETPOST('projectid', 'int');
- // Creation facture
- $object->ref = $_POST['ref'];
- $object->ref_supplier = $_POST['ref_supplier'];
- $object->socid = $_POST['socid'];
- $object->libelle = $_POST['label'];
+ // Creation invoice
+ $object->ref = GETPOST('ref', 'nohtml');
+ $object->ref_supplier = GETPOST('ref_supplier', 'nohtml');
+ $object->socid = GETPOST('socid', 'int');
+ $object->libelle = GETPOST('label', 'nohtml'); // deprecated
+ $object->label = GETPOST('label', 'nohtml');
$object->date = $dateinvoice;
$object->date_echeance = $datedue;
$object->note_public = GETPOST('note_public', 'restricthtml');
@@ -894,7 +895,7 @@ if (empty($reshook))
$object->fetch_thirdparty();
// If creation from another object of another module
- if (!$error && $_POST['origin'] && $_POST['originid'])
+ if (!$error && GETPOST('origin', 'alpha') && GETPOST('originid'))
{
// Parse element/subelement (ex: project_task)
$element = $subelement = GETPOST('origin', 'alpha');
@@ -1385,7 +1386,9 @@ if (empty($reshook))
$fk_unit = GETPOST('units', 'alpha');
- $tva_tx = price2num($tva_tx); // When vat is text input field
+ if (!preg_match('/\((.*)\)/', $tva_tx)) {
+ $tva_tx = price2num($tva_tx); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1'
+ }
// Local Taxes
$localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
@@ -1805,7 +1808,7 @@ if ($action == 'create')
print $societe->getNomUrl(1);
print ' ';
} else {
- print $form->select_company($societe->id, 'socid', 's.fournisseur=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
+ print img_picto('', 'company').$form->select_company($societe->id, 'socid', 's.fournisseur=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
// reload page to retrieve supplier informations
if (!empty($conf->global->RELOAD_PAGE_ON_SUPPLIER_CHANGE))
{
@@ -2020,7 +2023,7 @@ if ($action == 'create')
print ''."\n";
@@ -2071,17 +2074,7 @@ if ($action == 'create')
if (!empty($conf->banque->enabled))
{
print ''.$langs->trans('BankAccount').' ';
- $form->select_comptes((GETPOSTISSET('fk_account') ?GETPOST('fk_account', 'alpha') : $fk_account), 'fk_account', 0, '', 1);
- print ' ';
- }
-
- // Multicurrency
- if (!empty($conf->multicurrency->enabled))
- {
- print '';
- print ''.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).' ';
- print '';
- print $form->selectMultiCurrency((GETPOSTISSET('multicurrency_code') ?GETPOST('multicurrency_code', 'alpha') : $currency_code), 'multicurrency_code');
+ print img_picto('', 'bank_account').$form->select_comptes((GETPOSTISSET('fk_account') ?GETPOST('fk_account', 'alpha') : $fk_account), 'fk_account', 0, '', 1, '', 0, '', 1);
print ' ';
}
@@ -2092,7 +2085,7 @@ if ($action == 'create')
$langs->load('projects');
print ''.$langs->trans('Project').' ';
- $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth500');
+ print img_picto('', 'project').$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
print ' ';
}
@@ -2106,6 +2099,16 @@ if ($action == 'create')
print ' ';
}
+ // Multicurrency
+ if (!empty($conf->multicurrency->enabled))
+ {
+ print '