diff --git a/ChangeLog b/ChangeLog index 14f59405eb9..c35ca9ba9b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,7 +39,7 @@ NEW: add export for various payments NEW: add Extrafields labels and values in mail on create ticket NEW: add Extrafields support on ECM module NEW: add filter rules "is answer" and "is not answer" in email collector -NEW: add focus when editing on product/stock/product.php Close #14548 +NEW: add focus when editing on product/stock/product.php -> close #14548 NEW: add free text on each terminal of cash desk NEW: add global search for customer payments and vendor payments NEW: add global search for miscellaneous payments @@ -74,7 +74,6 @@ NEW: Algeria data (VAT and forme_juridique) NEW: allow click on all header numbers on commerce area NEW: allow to reopen interventions (green button) NEW: allow zero quantity on supplier/vendor order line -NEW: appearance tab in TakePOS with more visual parameters NEW: better currency rate editor NEW: can build vendor invoice from vendor orders NEW: can change a product in lines of a recurring invoice or contract @@ -123,19 +122,18 @@ NEW: manage errors on update extra fields in ticket card NEW: mass-actions for the event list view NEW: more filter for "View change logs" NEW: multiselect type and date to date filter -NEW: Nature of product is now a dictionay NEW: new line template: hidden conf to fill service dates from the last service line NEW: PDF model storm for delivery NEW: possibilty to group payments by mode and show their subtotal -NEW: Print payment method and change in TakePOS NEW: Priority and transparency from external calendar events +NEW: Products - Nature of product is now a dictionary #13287 NEW: Products Import/Export 'default warehouse' and 'use batch number' fields NEW: Purchase price table: added filterable table columns NEW: rate editor for multicurrency NEW: ref_ext field for Commande lines, order lines, Attributes and Combinations, Invoice lines, payments, order lines NEW: remove new lines in mail on add ticket message NEW: Rule "email to" accept wildcard * -NEW: Save filter of the project homepage +NEW: save filter of the project homepage NEW: select-able columns on customer and supplier invoice paymnet list NEW: select-able columns on miscellaneous payments + more data columns NEW: select-able columns on social taxes list @@ -152,6 +150,7 @@ NEW: show tags and status in search list of website pages NEW: show user on external calender events (when found) NEW: subject title with company name instead of application title in ticket message NEW: Support for Samba4 AD +NEW: TakePOS appearance tab with more visual parameters NEW: TakePOS add alert before changing thirdparty NEW: TakePOS add third order printer NEW: TakePOS can change thirdparty with barcode scan @@ -160,14 +159,15 @@ NEW: TakePOS connector compatibility with RECEIPT PRINTERS module NEW: TakePOS Gift Receipt NEW: TakePOS multicurrency compatibility NEW: TakePOS multicurrency total +NEW: TakePOS print payment method and change NEW: TakePOS restrict thirdparty to customer -NEW: TakePOS show available stock in TakePOS +NEW: TakePOS show available stock NEW: TakePOS Weighing Scale compatibility with TakePOS connector #14725 -NEW: Third-Party Import new fields: mother company,outstanding debt limit,bank account,incoterms +NEW: Thirdparty Import new fields: mother company,outstanding debt limit,bank account,incoterms NEW: Thirdparty module : box on customer/supplier tab for invoice outsantding amount late -NEW: ticket classification on create from email collector +NEW: Ticket classification on create from email collector NEW: Ticket message notifications when edited from public interface -NEW: translate classification labels in ticket +NEW: Ticket translate classification labels in ticket NEW: VAT rate for Angola #15606 NEW: VAT and juridical status for Algeria NEW: VAT report - Invert constant to show by default zero VAT in reports diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index d0f43cfe3dd..21077dececd 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -224,9 +224,10 @@ if ($action == "confirm_update") { $action = 'create'; $error++; } - if (!GETPOST('next_num_mvt', 'alpha')) + if (!GETPOST('doc_ref', 'alpha')) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumPiece")), null, 'errors'); + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Piece")), null, 'errors'); + $action = 'create'; $error++; } @@ -371,7 +372,7 @@ if ($action == 'create') print ''; print ''; - print ''.$langs->trans("Piece").''; + print ''.$langs->trans("Piece").''; print ''; print ''; @@ -594,7 +595,8 @@ if ($action == 'create') print ''."\n"; print ''."\n"; - print ""; + print '
'; + if (count($object->linesmvt) > 0) { $total_debit = 0; $total_credit = 0; @@ -616,18 +618,21 @@ if ($action == 'create') $total_credit += $line->credit; if ($action == 'update' && $line->id == $id) { + print ''; print ''; print ''; print ''; print ''; @@ -671,18 +676,21 @@ if ($action == 'create') if ($action == "" || $action == 'add') { print ''; + print ''; print ''; print ''; print ''; print ''; diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 59ffdf2e899..92e407732e0 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -140,6 +140,7 @@ if (!in_array($action, array('export_file', 'delmouv', 'delmouvconfirm')) && !GE $arrayfields = array( '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.numero_compte'=>array('label'=>$langs->trans("AccountAccountingShort"), 'checked'=>1), @@ -148,7 +149,6 @@ $arrayfields = array( 't.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1), 't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1), 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), - 't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1), 't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0), 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), @@ -665,7 +665,7 @@ if (empty($reshook)) { $newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 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', '', 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')); $url = './card.php?action=create'; if (!empty($socid)) $url .= '&socid='.$socid; @@ -688,11 +688,17 @@ print '
'; print $formaccounting->select_account((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), 'accountingaccount_number', 1, array(), 1, 1, ''); print ''; - // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because it does not - // use setup of keypress to select thirdparty and this hang browser on large database. - if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) - { + // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because: + // It does not use the setup of "key pressed" to select a thirdparty and this hang browser on large databases. + // Also, it is not possible to use a value that is not in the list. + // Also, the label is not automatically filled when a value is selected. + if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1); } else { print 'subledger_account).'">'; } + // TODO Add also the label print 'label_operation).'">debit)).'">
'; print $formaccounting->select_account('', 'accountingaccount_number', 1, array(), 1, 1, ''); print ''; - // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because it does not - // use setup of keypress to select thirdparty and this hang browser on large database. - if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) - { + // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because: + // It does not use the setup of "key pressed" to select a thirdparty and this hang browser on large databases. + // Also, it is not possible to use a value that is not in the list. + // Also, the label is not automatically filled when a value is selected. + if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { print $formaccounting->select_auxaccount('', 'subledger_account', 1); } else { print ''; } + // TODO Add also the label print '
'; // Filters lines print ''; + // Movement number if (!empty($arrayfields['t.piece_num']['checked'])) { print ''; } +// Code journal +if (!empty($arrayfields['t.code_journal']['checked'])) +{ + print ''; +} // Date document if (!empty($arrayfields['t.doc_date']['checked'])) { @@ -781,13 +787,6 @@ if (!empty($arrayfields['t.lettering_code']['checked'])) print '
'.$langs->trans("NotReconciled").''; print ''; } -// Code journal -if (!empty($arrayfields['t.code_journal']['checked'])) -{ - print ''; -} // Fields from hook $parameters = array('arrayfields'=>$arrayfields); @@ -839,6 +838,7 @@ 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.doc_ref']['checked'])) print_liste_field_titre($arrayfields['t.doc_ref']['label'], $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); if (!empty($arrayfields['t.numero_compte']['checked'])) print_liste_field_titre($arrayfields['t.numero_compte']['label'], $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); @@ -847,7 +847,6 @@ if (!empty($arrayfields['t.label_operation']['checked'])) print_liste_field_tit if (!empty($arrayfields['t.debit']['checked'])) print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['t.credit']['checked'])) print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['t.lettering_code']['checked'])) print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, '', $sortfield, $sortorder, 'center '); -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 '); // Hook fields $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook @@ -913,6 +912,16 @@ while ($i < min($num, $limit)) if (!$i) $totalarray['nbfield']++; } + // Journal code + if (!empty($arrayfields['t.code_journal']['checked'])) + { + $accountingjournal = new AccountingJournal($db); + $result = $accountingjournal->fetch('', $line->code_journal); + $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal); + print ''; + if (!$i) $totalarray['nbfield']++; + } + // Document date if (!empty($arrayfields['t.doc_date']['checked'])) { @@ -1040,16 +1049,6 @@ while ($i < min($num, $limit)) if (!$i) $totalarray['nbfield']++; } - // Journal code - if (!empty($arrayfields['t.code_journal']['checked'])) - { - $accountingjournal = new AccountingJournal($db); - $result = $accountingjournal->fetch('', $line->code_journal); - $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal); - print ''; - if (!$i) $totalarray['nbfield']++; - } - // Fields from hook $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 9c7fef0232b..21b8c51380d 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -128,8 +128,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), @@ -428,7 +428,7 @@ $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $obj 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?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); - $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php', '', 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')); $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); } @@ -473,6 +473,11 @@ print '
'; - print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1); - print '
'.$journaltoshow.''.$journaltoshow.'
'; // Filters lines print ''; +// Movement number +if (!empty($arrayfields['t.piece_num']['checked'])) +{ + print ''; +} // Code journal if (!empty($arrayfields['t.code_journal']['checked'])) { print ''; } -// Movement number -if (!empty($arrayfields['t.piece_num']['checked'])) -{ - print ''; -} // Ref document if (!empty($arrayfields['t.doc_ref']['checked'])) { print ''; @@ -544,9 +544,9 @@ 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); if (!empty($arrayfields['t.label_operation']['checked'])) print_liste_field_titre($arrayfields['t.label_operation']['label'], $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder); if (!empty($arrayfields['t.debit']['checked'])) print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, '', $sortfield, $sortorder, 'right '); @@ -637,6 +637,17 @@ while ($i < min($num, $limit)) print ''; + // Piece number + if (!empty($arrayfields['t.piece_num']['checked'])) + { + 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 ''; - 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 '
'; @@ -490,11 +495,6 @@ if (!empty($arrayfields['t.doc_date']['checked'])) { print ''; print '
'; + $object->id = $line->id; + $object->piece_num = $line->piece_num; + print $object->getNomUrl(1, '', 0, '', 1); + print ''; - $object->id = $line->id; - $object->piece_num = $line->piece_num; - print $object->getNomUrl(1, '', 0, '', 1); - print '
'; // Filters lines print ''; +// Movement number +if (!empty($arrayfields['t.piece_num']['checked'])) +{ + print ''; +} // Code journal if (!empty($arrayfields['t.code_journal']['checked'])) { 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 ''; + 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 ''; - 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 ''; + print ''; + + print '
'; @@ -519,10 +524,6 @@ if (!empty($arrayfields['t.doc_date']['checked'])) { print ''; print '
'; + $object->id = $line->id; + $object->piece_num = $line->piece_num; + print $object->getNomUrl(1, '', 0, '', 1); + print ''; - $object->id = $line->id; - $object->piece_num = $line->piece_num; - print $object->getNomUrl(1, '', 0, '', 1); - print '
'; + print ''; + + foreach ($arrayofparameters as $key => $val) + { + print ''; + } + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print '
'; + + print '
'; + print ''; + print '
'; + + print ''; + print '
'; +} else { + if (!empty($arrayofparameters)) + { + print ''; + print ''; + + foreach ($arrayofparameters as $key => $val) + { + $setupnotempty++; + + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print ''.$conf->global->$key.'
'; + + print '
'; + print ''.$langs->trans("Modify").''; + 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 ''; + print ''; + print ''; + print ''; + print ''; + 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 ''; + + // Show example of numbering model + print ''."\n"; + + 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 "\n"; + } + } + } + closedir($handle); + } + } + } + print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + 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 '
'; + $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 ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + 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 ''; + print ''; + print '\n"; + print '\n"; + print ''; + print ''; + 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 ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } else { + print '"; + } + + // Default + 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 ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } + } + + print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name) ? $name : $module->name); + print "\n"; + if (method_exists($module, 'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"), 'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + 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 ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"), 'generic').''; + } else { + print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + } + 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 .= ''; - } else $retstring .= ''; + $retstringbuttom .= ' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');"'; + $retstringbuttom .= '>'.img_object($langs->trans("SelectDate"), 'calendarday', 'class="datecallink"').''; + } else { + $retstringbuttom = ''; + } + $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 .= ''.img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"').''; + $retstringbutton = ''; + $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').': '; // 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); - 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 .= '
'; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= ''; + + $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Workstation"), $langs->transnoentities("Workstation")); + $tooltip .= $langs->trans("GenericMaskCodes2"); + $tooltip .= $langs->trans("GenericMaskCodes3"); + $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("Workstation"), $langs->transnoentities("Workstation")); + $tooltip .= $langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte .= ''; + $texte .= ''; + + $texte .= ''; + + $texte .= ''; + + $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).' 
'; + $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 '
'; $tmp = ' '; $text = $tmp.$langs->trans("InvoiceAvoir").' '; - $text .= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') '; + $text .= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') '; $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3); print $desc; 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 ''; + print ''.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).''; + print ''; + print $form->selectMultiCurrency((GETPOSTISSET('multicurrency_code') ?GETPOST('multicurrency_code', 'alpha') : $currency_code), 'multicurrency_code'); + print ''; + } + // Intracomm report if (!empty($conf->intracommreport->enabled)) { diff --git a/htdocs/install/check.php b/htdocs/install/check.php index daab7a7296a..0a3e49c9600 100644 --- a/htdocs/install/check.php +++ b/htdocs/install/check.php @@ -122,7 +122,7 @@ if (!function_exists("imagecreate")) print 'Error '.$langs->trans("ErrorPHPDoesNotSupportGD")."
\n"; // $checksok = 0; // If ko, just warning. So check must still be 1 (otherwise no way to install) } else { - print 'Ok '.$langs->trans("PHPSupportGD")."
\n"; + print 'Ok '.$langs->trans("PHPSupport", "GD")."
\n"; } @@ -133,7 +133,7 @@ if (!function_exists("curl_init")) print 'Error '.$langs->trans("ErrorPHPDoesNotSupportCurl")."
\n"; // $checksok = 0; // If ko, just warning. So check must still be 1 (otherwise no way to install) } else { - print 'Ok '.$langs->trans("PHPSupportCurl")."
\n"; + print 'Ok '.$langs->trans("PHPSupport", "Curl")."
\n"; } // Check if PHP calendar extension is available @@ -141,7 +141,7 @@ if (!function_exists("easter_date")) { print 'Error '.$langs->trans("ErrorPHPDoesNotSupportCalendar")."
\n"; } else { - print 'Ok '.$langs->trans("PHPSupportCalendar")."
\n"; + print 'Ok '.$langs->trans("PHPSupport", "Calendar")."
\n"; } @@ -152,7 +152,7 @@ if (!function_exists("utf8_encode")) print 'Error '.$langs->trans("ErrorPHPDoesNotSupportUTF8")."
\n"; // $checksok = 0; // If ko, just warning. So check must still be 1 (otherwise no way to install) } else { - print 'Ok '.$langs->trans("PHPSupportUTF8")."
\n"; + print 'Ok '.$langs->trans("PHPSupport", "UTF8")."
\n"; } @@ -165,7 +165,7 @@ if (empty($_SERVER["SERVER_ADMIN"]) || $_SERVER["SERVER_ADMIN"] != 'doliwamp@loc print 'Error '.$langs->trans("ErrorPHPDoesNotSupportIntl")."
\n"; // $checksok = 0; // If ko, just warning. So check must still be 1 (otherwise no way to install) } else { - print 'Ok '.$langs->trans("PHPSupportIntl")."
\n"; + print 'Ok '.$langs->trans("PHPSupport", "Intl")."
\n"; } } diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql.orig b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql.orig new file mode 100644 index 00000000000..e9798083ea6 --- /dev/null +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql.orig @@ -0,0 +1,568 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 13.0.0 or higher. +-- +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; +-- To create a unique index ALTER TABLE llx_table ADD UNIQUE INDEX uk_table_field (field); +-- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table +-- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_table CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): +-- -- VPGSQL8.2 CREATE SEQUENCE llx_table_rowid_seq OWNED BY llx_table.rowid; +-- -- VPGSQL8.2 ALTER TABLE llx_table ADD PRIMARY KEY (rowid); +-- -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN rowid SET DEFAULT nextval('llx_table_rowid_seq'); +-- -- VPGSQL8.2 SELECT setval('llx_table_rowid_seq', MAX(rowid)) FROM llx_table; +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. + + +-- Missing in v12 or lower + +ALTER TABLE llx_payment_salary MODIFY COLUMN ref varchar(30) NULL; +ALTER TABLE llx_payment_various MODIFY COLUMN ref varchar(30) NULL; + +ALTER TABLE llx_prelevement_bons ADD COLUMN type varchar(16) DEFAULT 'debit-order'; + +ALTER TABLE llx_prelevement_facture CHANGE COLUMN fk_facture_foun fk_facture_fourn integer NULL; + +ALTER TABLE llx_prelevement_facture_demande ADD INDEX idx_prelevement_facture_demande_fk_facture (fk_facture); +ALTER TABLE llx_prelevement_facture_demande ADD INDEX idx_prelevement_facture_demande_fk_facture_fourn (fk_facture_fourn); + +ALTER TABLE llx_document_model MODIFY COLUMN type varchar(64); + +ALTER TABLE llx_bom_bom MODIFY COLUMN duration double(24,8); + +ALTER TABLE llx_bom_bom_extrafields ADD INDEX idx_bom_bom_extrafields_fk_object (fk_object); + +create table llx_mrp_mo_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_mrp_mo_extrafields DROP INDEX idx_fk_object; + +ALTER TABLE llx_mrp_mo_extrafields ADD INDEX idx_mrp_mo_fk_object(fk_object); + + +-- For v13 +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (111,11, '0','0','No Sales Tax',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (112,11, '4','0','Sales Tax 4%',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (113,11, '6','0','Sales Tax 6%',1); + +ALTER TABLE llx_bom_bom ADD COLUMN bomtype integer DEFAULT 0; + +UPDATE llx_emailcollector_emailcollector SET ref = 'Collect_Ticket_Requests' WHERE ref = 'Collect_Ticket_Requets'; +UPDATE llx_emailcollector_emailcollector SET ref = 'Collect_Responses_In' WHERE ref = 'Collect_Responses'; + + +UPDATE llx_document_model set nom = 'standard' where nom = 'Standard' and type ='stock'; +UPDATE llx_document_model set nom = 'stdmovement', type = 'movement' where nom = 'StdMouvement' and type ='mouvement'; + + +UPDATE llx_const SET value = 0 WHERE name = 'FACTURE_TVAOPTION' and value = 'franchise'; +UPDATE llx_const SET value = 1 WHERE name = 'FACTURE_TVAOPTION' and value <> 'franchise' AND value <> '0' AND value <> '1'; + +ALTER TABLE llx_commande MODIFY COLUMN date_livraison DATETIME; + +ALTER TABLE llx_website ADD COLUMN position integer DEFAULT 0; + +ALTER TABLE llx_establishment ADD COLUMN ref varchar(30); +ALTER TABLE llx_establishment ADD COLUMN label varchar(128); +UPDATE llx_establishment SET ref = rowid WHERE ref IS NULL; +ALTER TABLE llx_establishment MODIFY COLUMN ref varchar(30) NOT NULL; +ALTER TABLE llx_establishment MODIFY COLUMN label varchar(128); + +INSERT INTO llx_const (name, entity, value, type, visible) VALUES ('PRODUCT_PRICE_BASE_TYPE', 0, 'HT', 'string', 0); + +ALTER TABLE llx_subscription MODIFY COLUMN datef DATETIME; + +ALTER TABLE llx_loan_schedule ADD column fk_payment_loan INTEGER; + + +ALTER TABLE llx_user DROP COLUMN jabberid; +ALTER TABLE llx_user DROP COLUMN skype; +ALTER TABLE llx_user DROP COLUMN twitter; +ALTER TABLE llx_user DROP COLUMN facebook; +ALTER TABLE llx_user DROP COLUMN linkedin; +ALTER TABLE llx_user DROP COLUMN instagram; +ALTER TABLE llx_user DROP COLUMN snapchat; +ALTER TABLE llx_user DROP COLUMN googleplus; +ALTER TABLE llx_user DROP COLUMN youtube; +ALTER TABLE llx_user DROP COLUMN whatsapp; + +ALTER TABLE llx_user ADD COLUMN datelastpassvalidation datetime; +ALTER TABLE llx_user ADD COLUMN datestartvalidity datetime; +ALTER TABLE llx_user ADD COLUMN dateendvalidity datetime; + +ALTER TABLE llx_user ADD COLUMN idpers1 varchar(128); +ALTER TABLE llx_user ADD COLUMN idpers2 varchar(128); +ALTER TABLE llx_user ADD COLUMN idpers3 varchar(128); + + +-- Intracomm Report +CREATE TABLE llx_c_transport_mode ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer DEFAULT 1 NOT NULL, -- multi company id + code varchar(3) NOT NULL, + label varchar(255) NOT NULL, + active tinyint DEFAULT 1 NOT NULL +) ENGINE=innodb; + +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('MAR', 'Transport maritime (y compris camions ou wagons sur bateau)', 1); +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('TRA', 'Transport par chemin de fer (y compris camions sur wagon)', 1); +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('ROU', 'Transport par route', 1); +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('AIR', 'Transport par air', 1); +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('POS', 'Envois postaux', 1); +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('OLE', 'Installations de transport fixe (oléoduc)', 1); +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('NAV', 'Transport par navigation intérieure', 1); +INSERT INTO llx_c_transport_mode (code, label, active) VALUES ('PRO', 'Propulsion propre', 1); + +ALTER TABLE llx_facture ADD COLUMN fk_transport_mode integer after location_incoterms; +ALTER TABLE llx_facture_fourn ADD COLUMN fk_transport_mode integer after location_incoterms; + +ALTER TABLE llx_societe ADD COLUMN transport_mode tinyint after cond_reglement; +ALTER TABLE llx_societe ADD COLUMN transport_mode_supplier tinyint after cond_reglement_supplier; + +CREATE TABLE llx_intracommreport +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + + ref varchar(30) NOT NULL, -- report reference number + entity integer DEFAULT 1 NOT NULL, -- multi company id + type_declaration varchar(32), + periods varchar(32), + mode varchar(32), + content_xml text, + type_export varchar(10), + datec datetime, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +)ENGINE=innodb; + +ALTER TABLE llx_c_incoterms ADD COLUMN label varchar(100) NULL; + +CREATE TABLE llx_recruitment_recruitmentjobposition( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + entity INTEGER DEFAULT 1 NOT NULL, + label varchar(255) NOT NULL, + qty integer DEFAULT 1 NOT NULL, + fk_soc integer, + fk_project integer, + fk_user_recruiter integer, + fk_user_supervisor integer, + fk_establishment integer, + date_planned date, + remuneration_suggested varchar(255), + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + last_main_doc varchar(255), + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_ref (ref); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_fk_soc (fk_soc); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_fk_project (fk_project); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitment_recruitmentjobposition_fk_user_recruiter FOREIGN KEY (fk_user_recruiter) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitment_recruitmentjobposition_fk_user_supervisor FOREIGN KEY (fk_user_supervisor) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitment_recruitmentjobposition_fk_establishment FOREIGN KEY (fk_establishment) REFERENCES llx_establishment(rowid); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitment_recruitmentjobposition_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_status (status); + +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN email_recruiter varchar(255); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN entity INTEGER DEFAULT 1 NOT NULL; +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN remuneration_suggested varchar(255); + +create table llx_recruitment_recruitmentjobposition_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentjobposition_extrafields ADD INDEX idx_recruitmentjobposition_fk_object(fk_object); + + + +CREATE TABLE llx_recruitment_recruitmentcandidature( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + entity integer NOT NULL DEFAULT 1, + fk_recruitmentjobposition INTEGER NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL, + firstname varchar(128), + lastname varchar(128), + email varchar(255), + phone varchar(64), + date_birth date, + remuneration_requested integer, + remuneration_proposed integer, + email_msgid varchar(255), + fk_recruitment_origin INTEGER NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD COLUMN entity integer NOT NULL DEFAULT 1; +ALTER TABLE llx_recruitment_recruitmentcandidature ADD COLUMN email_msgid varchar(255); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD COLUMN fk_recruitment_origin INTEGER NULL; +ALTER TABLE llx_recruitment_recruitmentcandidature ADD COLUMN date_birth date; + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); + +create table llx_recruitment_recruitmentcandidature_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_recruitmentcandidature_fk_object(fk_object); + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD UNIQUE INDEX uk_recruitmentcandidature_email_msgid(email_msgid); + + +ALTER TABLE llx_product_attribute ADD COLUMN ref_ext VARCHAR(255) after ref; +ALTER TABLE llx_product_attribute_combination ADD COLUMN variation_ref_ext varchar(255) AFTER variation_weight; + + +CREATE TABLE llx_product_attribute_combination_price_level +( + rowid INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, + fk_product_attribute_combination INTEGER DEFAULT 1 NOT NULL, + fk_price_level INTEGER DEFAULT 1 NOT NULL, + variation_price DOUBLE(24,8) NOT NULL, + variation_price_percentage INTEGER NULL +)ENGINE=innodb; + +ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE( fk_product_attribute_combination, fk_price_level); + + + +-- Add dictionary for prospect level and action commercial on contacts (Using this is not recommanded) + +create table llx_c_prospectcontactlevel +( + code varchar(12) PRIMARY KEY, + label varchar(30), + sortorder smallint, + active smallint DEFAULT 1 NOT NULL, + module varchar(32) NULL +) ENGINE=innodb; +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_NONE', 'None', 1); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_LOW', 'Low', 2); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_MEDIUM', 'Medium', 3); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_HIGH', 'High', 4); + +create table llx_c_stcommcontact +( + id integer PRIMARY KEY, + code varchar(12) NOT NULL, + libelle varchar(30), + picto varchar(128), + active tinyint default 1 NOT NULL +)ENGINE=innodb; +ALTER TABLE llx_c_stcommcontact ADD UNIQUE INDEX uk_c_stcommcontact(code); + +insert into llx_c_stcommcontact (id,code,libelle) values (-1, 'ST_NO', 'Do not contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 0, 'ST_NEVER', 'Never contacted'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 1, 'ST_TODO', 'To contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 2, 'ST_PEND', 'Contact in progress'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Contacted'); + +ALTER TABLE llx_socpeople ADD COLUMN fk_prospectcontactlevel varchar(12) AFTER priv; +ALTER TABLE llx_socpeople ADD COLUMN fk_stcommcontact integer DEFAULT 0 NOT NULL AFTER fk_prospectcontactlevel; + +create table llx_c_recruitment_origin +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(32) NOT NULL, + label varchar(64) NOT NULL, + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; + + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD UNIQUE INDEX uk_recruitmentcandidature_email_msgid(email_msgid); + + +ALTER TABLE llx_product MODIFY COLUMN seuil_stock_alerte float; +ALTER TABLE llx_product MODIFY COLUMN desiredstock float; + +ALTER TABLE llx_product_warehouse_properties MODIFY COLUMN seuil_stock_alerte float; +ALTER TABLE llx_product_warehouse_properties MODIFY COLUMN desiredstock float; + +ALTER TABLE llx_product ADD COLUMN fk_state integer DEFAULT NULL; + +ALTER TABLE llx_projet ADD COLUMN email_msgid varchar(255); +ALTER TABLE llx_ticket ADD COLUMN email_msgid varchar(255); +ALTER TABLE llx_actioncomm ADD COLUMN reply_to varchar(255); + +ALTER TABLE llx_paiement ADD pos_change DOUBLE(24,8) DEFAULT 0 AFTER fk_export_compta; + +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_CREATE','Contact address created','Executed when a contact is created','contact',50); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_SENTBYMAIL','Mails sent from third party card','Executed when you send email from contact adress card','contact',51); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_DELETE','Contact address deleted','Executed when a contact is deleted','contact',52); + +ALTER TABLE llx_opensurvey_sondage CHANGE COLUMN tms tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE llx_ecm_directories CHANGE COLUMN date_m tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE llx_ecm_files CHANGE COLUMN date_m tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; + +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines,joinfiles) VALUES (0,'recruitment','recruitmentcandidature_send','',0,null,null,'(AnswerCandidature)' ,100,'$conf->recruitment->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourCandidature)__', '__(Hello)__ __CANDIDATE_FULLNAME__,

\n\n__(YourCandidatureAnswer)__
\n

\n__(Sincerely)__
__USER_SIGNATURE__',null, 0); + +ALTER TABLE llx_c_action_trigger MODIFY COLUMN code varchar(64) NOT NULL; + +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_CREATE','Job created','Executed when a job is created','recruitment',7500); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_MODIFY','Job modified','Executed when a job is modified','recruitment',7502); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_SENTBYMAIL','Mails sent from job record','Executed when you send email from job record','recruitment',7504); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_DELETE','Job deleted','Executed when a job is deleted','recruitment',7506); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTCANDIDATURE_CREATE','Candidature created','Executed when a candidature is created','recruitment',7510); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTCANDIDATURE_MODIFY','Candidature modified','Executed when a candidature is modified','recruitment',7512); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTCANDIDATURE_SENTBYMAIL','Mails sent from candidature record','Executed when you send email from candidature record','recruitment',7514); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTCANDIDATURE_DELETE','Candidature deleted','Executed when a candidature is deleted','recruitment',7516); + +ALTER TABLE llx_actioncomm_reminder ADD COLUMN entity integer NOT NULL DEFAULT 1; +ALTER TABLE llx_actioncomm_reminder ADD COLUMN fk_actioncomm integer NOT NULL; +ALTER TABLE llx_actioncomm_reminder ADD COLUMN fk_email_template integer; +ALTER TABLE llx_actioncomm_reminder ADD COLUMN lasterror varchar(128) NULL; + +ALTER TABLE llx_actioncomm_reminder DROP INDEX uk_actioncomm_reminder_unique; +ALTER TABLE llx_actioncomm_reminder ADD UNIQUE uk_actioncomm_reminder_unique (fk_user, typeremind, offsetvalue, offsetunit, fk_actioncomm); + +ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_status (status); + + +ALTER TABLE llx_inventorydet ADD UNIQUE uk_inventorydet(fk_inventory, fk_warehouse, fk_product, batch); + +ALTER TABLE llx_commandedet ADD COLUMN ref_ext varchar(255) AFTER label; +ALTER TABLE llx_facturedet ADD COLUMN ref_ext varchar(255) AFTER multicurrency_total_ttc; + +ALTER TABLE llx_c_ticket_category ADD COLUMN fk_parent integer DEFAULT 0 NOT NULL; +ALTER TABLE llx_c_ticket_category ADD COLUMN force_severity varchar(32) NULL; + +ALTER TABLE llx_c_ticket_severity CHANGE color color VARCHAR(10) NULL; + +ALTER TABLE llx_expensereport ADD COLUMN fk_user_creat integer NULL; + +ALTER TABLE llx_expensereport_ik ADD COLUMN ikoffset double DEFAULT 0 NOT NULL; + +ALTER TABLE llx_paiement ADD COLUMN ref_ext varchar(255) AFTER ref; + +ALTER TABLE llx_bank ADD COLUMN origin_id integer; +ALTER TABLE llx_bank ADD COLUMN origin_type varchar(64) NULL; +ALTER TABLE llx_bank ADD COLUMN import_key varchar(14); + +ALTER TABLE llx_menu MODIFY COLUMN enabled text; + +CREATE TABLE llx_ecm_files_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_ecm_files_extrafields ADD INDEX idx_ecm_files_extrafields (fk_object); +ALTER TABLE llx_ecm_files ADD COLUMN note_private text AFTER fk_user_m; +ALTER TABLE llx_ecm_files ADD COLUMN note_public text AFTER note_private; + +CREATE TABLE llx_ecm_directories_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_ecm_directories_extrafields ADD INDEX idx_ecm_directories_extrafields (fk_object); +ALTER TABLE llx_ecm_directories ADD COLUMN note_private text AFTER fk_user_m; +ALTER TABLE llx_ecm_directories ADD COLUMN note_public text AFTER note_private; + +ALTER TABLE llx_website_page ADD COLUMN allowed_in_frames integer DEFAULT 0; +ALTER TABLE llx_website_page ADD COLUMN object_type varchar(255); +ALTER TABLE llx_website_page ADD COLUMN fk_object varchar(255); + +DELETE FROM llx_const WHERE name in ('MAIN_INCLUDE_ZERO_VAT_IN_REPORTS'); + +UPDATE llx_projet_task_time SET tms = null WHERE tms = 0; +ALTER TABLE llx_projet_task_time MODIFY COLUMN tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; + +ALTER TABLE llx_projet_task_time MODIFY COLUMN datec datetime; + + +DELETE FROM llx_user_rights WHERE fk_id IN (SELECT id FROM llx_rights_def where module = 'holiday' and perms = 'lire_tous'); +DELETE FROM llx_rights_def where module = 'holiday' and perms = 'lire_tous'; +UPDATE llx_rights_def set perms = 'readall' WHERE perms = 'read_all' and module = 'holiday'; + +CREATE TABLE llx_c_product_nature ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code tinyint NOT NULL, + label varchar(100), + active tinyint DEFAULT 1 NOT NULL +) ENGINE=innodb; + +ALTER TABLE llx_c_product_nature ADD UNIQUE INDEX uk_c_product_nature(code, active); + +INSERT INTO llx_c_product_nature (code, label, active) VALUES (0, 'RowMaterial', 1); +INSERT INTO llx_c_product_nature (code, label, active) VALUES (1, 'Finished', 1); + +ALTER TABLE llx_product MODIFY COLUMN finished tinyint DEFAULT NULL; +ALTER TABLE llx_product ADD CONSTRAINT fk_product_finished FOREIGN KEY (finished) REFERENCES llx_c_product_nature (code); + +<<<<<<< HEAD + +ALTER TABLE llx_product_customer_price ADD COLUMN ref_customer varchar(30); +ALTER TABLE llx_product_customer_price_log ADD COLUMN ref_customer varchar(30); + +======= +>>>>>>> a93227ac2f04c80c76b517215d1d422168607fb1 +-- MIGRATION TO DO AFTER RENAMING AN OBJECT + +-- drop constraint +ALTER TABLE llx_livraison DROP FOREIGN KEY fk_livraison_fk_soc; +ALTER TABLE llx_livraison DROP FOREIGN KEY fk_livraison_fk_user_author; +ALTER TABLE llx_livraison DROP FOREIGN KEY fk_livraison_fk_user_valid; + +-- rename Table +ALTER TABLE llx_livraison RENAME TO llx_delivery; +ALTER TABLE llx_livraison_extrafields RENAME TO llx_delivery_extrafields; +ALTER TABLE llx_livraisondet RENAME TO llx_deliverydet; +ALTER TABLE llx_livraisondet_extrafields RENAME TO llx_deliverydet_extrafields; + +-- rename index +ALTER TABLE llx_delivery DROP INDEX idx_livraison_uk_ref; +ALTER TABLE llx_delivery ADD UNIQUE INDEX idx_delivery_uk_ref (ref, entity); +ALTER TABLE llx_delivery DROP INDEX idx_livraison_fk_soc; +ALTER TABLE llx_delivery ADD INDEX idx_delivery_fk_soc (fk_soc); +ALTER TABLE llx_delivery DROP INDEX idx_livraison_fk_user_author; +ALTER TABLE llx_delivery ADD INDEX idx_delivery_fk_user_author (fk_user_author); +ALTER TABLE llx_delivery DROP INDEX idx_livraison_fk_user_valid; +ALTER TABLE llx_delivery ADD INDEX idx_delivery_fk_user_valid (fk_user_valid); + +-- drop constraint +ALTER TABLE llx_delivery DROP FOREIGN KEY fk_livraison_fk_soc; +ALTER TABLE llx_delivery DROP FOREIGN KEY fk_livraison_fk_user_author; +ALTER TABLE llx_delivery DROP FOREIGN KEY fk_livraison_fk_user_valid; + +-- add constraint +ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); +ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); +ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); + +ALTER TABLE llx_deliverydet DROP FOREIGN KEY fk_livraisondet_fk_livraison; +ALTER TABLE llx_deliverydet DROP INDEX idx_livraisondet_fk_expedition; +ALTER TABLE llx_deliverydet CHANGE COLUMN fk_livraison fk_delivery integer; +ALTER TABLE llx_deliverydet ADD INDEX idx_deliverydet_fk_delivery (fk_delivery); +ALTER TABLE llx_deliverydet ADD CONSTRAINT fk_deliverydet_fk_delivery FOREIGN KEY (fk_delivery) REFERENCES llx_delivery (rowid); + +UPDATE llx_extrafields SET elementtype = 'delivery' WHERE elementtype = 'livraison'; +UPDATE llx_extrafields SET elementtype = 'deliverydet' WHERE elementtype = 'livraisondet'; + +-- update llx_ecm_files +UPDATE llx_ecm_files SET src_object_type = 'delivery' WHERE src_object_type = 'livraison'; + +-- update llx_links +UPDATE llx_links SET objecttype = 'delivery' WHERE objecttype = 'livraison'; + +-- update llx_document_model +UPDATE llx_document_model SET type = 'delivery' WHERE type = 'livraison'; + +-- update llx_object_lang +UPDATE llx_object_lang SET type_object = 'delivery' WHERE type_object = 'livraison'; + +-- update llx_c_type_contact +UPDATE llx_c_type_contact SET element = 'delivery' WHERE element = 'livraison'; + +-- update llx_c_email_template +UPDATE llx_c_email_template SET type_template = 'delivery' WHERE type_template = 'livraison'; + +-- update llx_element_element +UPDATE llx_element_element SET sourcetype = 'delivery' WHERE sourcetype = 'livraison'; +UPDATE llx_element_element SET targettype = 'delivery' WHERE targettype = 'livraison'; + +-- update llx_actioncomm +UPDATE llx_actioncomm SET element_type = 'delivery' WHERE element_type = 'livraison'; + +-- update llx_const +UPDATE llx_const set name = 'DELIVERY_ADDON_NUMBER' WHERE name = 'LIVRAISON_ADDON_NUMBER'; +UPDATE llx_const set value = 'mod_delivery_jade' WHERE value = 'mod_livraison_jade' AND name = 'DELIVERY_ADDON_NUMBER'; +UPDATE llx_const set value = 'mod_delivery_saphir' WHERE value = 'mod_livraison_saphir' AND name = 'DELIVERY_ADDON_NUMBER'; + +-- update llx_rights_def +UPDATE llx_rights_def set perms = 'delivery' WHERE perms = 'livraison' and module = 'expedition'; +UPDATE llx_rights_def set perms = 'delivery_advance' WHERE perms = 'livraison_advance' and module = 'expedition'; + + +ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_commande (fk_commande); +ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_product (fk_product); + + +CREATE TABLE llx_zapier_hook( + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer DEFAULT 1 NOT NULL, + url varchar(255), + event varchar(255), + module varchar(128), + action varchar(128), + status integer, + date_creation datetime NOT NULL, + fk_user integer NOT NULL, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + import_key varchar(14) +) ENGINE=innodb; + + +CREATE TABLE llx_session( + session_id varchar(50) PRIMARY KEY, + session_variable text, + last_accessed datetime NOT NULL, + fk_user integer NOT NULL, + remote_ip varchar(64) NULL, + user_agent varchar(128) NULL +) ENGINE=innodb; + +INSERT INTO llx_c_socialnetworks (entity, code, label, url, icon, active) VALUES(1, 'github', 'Github', 'https://github.com/{socialid}', 'fa-github', 1); + +-- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_funnel_of_prospection.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_funnel_of_prospection.php' AND entity = 1); +-- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_customers_outstanding_bill_reached.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_customers_outstanding_bill_reached.php' AND entity = 1); +-- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_scheduled_jobs.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_scheduled_jobs.php' AND entity = 1); + +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64); + +ALTER TABLE llx_projet ADD COLUMN fk_opp_status_end integer DEFAULT NULL; + diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index f8ca2b41c7a..ce5bd939f18 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -51,7 +51,52 @@ ALTER TABLE llx_website ADD COLUMN lastaccess datetime NULL; ALTER TABLE llx_website ADD COLUMN pageviews_month BIGINT UNSIGNED DEFAULT 0; ALTER TABLE llx_website ADD COLUMN pageviews_total BIGINT UNSIGNED DEFAULT 0; + +CREATE TABLE llx_workstation_workstation( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + type varchar(7), + note_public text, + entity int DEFAULT 1, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + status smallint NOT NULL, + nb_operators_required integer, + thm_operator_estimated double, + thm_machine_estimated double + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_rowid (rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_ref (ref); +ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_status (status); + +CREATE TABLE llx_workstation_workstation_resource( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_resource integer, + fk_workstation integer +) ENGINE=innodb; + +CREATE TABLE llx_workstation_workstation_usergroup( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_usergroup integer, + fk_workstation integer +) ENGINE=innodb; + + ALTER TABLE llx_propal ADD COLUMN fk_warehouse integer DEFAULT NULL AFTER fk_shipping_method; ALTER TABLE llx_propal ADD CONSTRAINT llx_propal_fk_warehouse FOREIGN KEY (fk_warehouse) REFERENCES llx_entrepot(rowid); ALTER TABLE llx_propal ADD INDEX idx_propal_fk_warehouse(fk_warehouse); + +ALTER TABLE llx_product_customer_price ADD COLUMN ref_customer varchar(30); +ALTER TABLE llx_product_customer_price_log ADD COLUMN ref_customer varchar(30); diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql index 3a612623298..dae9eb79c42 100644 --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql @@ -51,6 +51,6 @@ CREATE TABLE llx_accounting_bookkeeping journal_label varchar(255), -- FEC:JournalLib date_validated datetime, -- FEC:ValidDate | if empty: movement not validated / if not empty: movement validated (No deleting / No modification) date_export datetime DEFAULT NULL, -- - import_key varchar(14), + import_key varchar(14), -- ID of import when data was inserted by a mass import extraparams varchar(255) -- for other parameters with json format ) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_customer_price.sql b/htdocs/install/mysql/tables/llx_product_customer_price.sql index 7cd481c3c75..f0d5edf9c2f 100644 --- a/htdocs/install/mysql/tables/llx_product_customer_price.sql +++ b/htdocs/install/mysql/tables/llx_product_customer_price.sql @@ -27,7 +27,8 @@ create table llx_product_customer_price datec datetime, tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_product integer NOT NULL, - fk_soc integer NOT NULL, + fk_soc integer NOT NULL, + ref_customer varchar(30), price double(24,8) DEFAULT 0, price_ttc double(24,8) DEFAULT 0, price_min double(24,8) DEFAULT 0, diff --git a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql index 4d79353e884..29906fe7ff2 100644 --- a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql +++ b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql @@ -26,7 +26,8 @@ create table llx_product_customer_price_log entity integer DEFAULT 1 NOT NULL, -- multi company id datec datetime, fk_product integer NOT NULL, - fk_soc integer DEFAULT 0 NOT NULL, + fk_soc integer DEFAULT 0 NOT NULL, + ref_customer varchar(30), price double(24,8) DEFAULT 0, price_ttc double(24,8) DEFAULT 0, price_min double(24,8) DEFAULT 0, diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql new file mode 100755 index 00000000000..6bdf16aa6d7 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation.key.sql @@ -0,0 +1,27 @@ +-- 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 https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_rowid (rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_ref (ref); +ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_workstation_workstation ADD INDEX idx_workstation_workstation_status (status); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_workstation_workstation ADD UNIQUE INDEX uk_workstation_workstation_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_workstation_workstation ADD CONSTRAINT llx_workstation_workstation_fk_field FOREIGN KEY (fk_field) REFERENCES llx_workstation_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation.sql b/htdocs/install/mysql/tables/llx_workstation_workstation.sql new file mode 100755 index 00000000000..a4d9fd4dbc8 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation.sql @@ -0,0 +1,36 @@ +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_workstation_workstation( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + type varchar(7), + note_public text, + entity int DEFAULT 1, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + status smallint NOT NULL, + nb_operators_required integer, + thm_operator_estimated double, + thm_machine_estimated double + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql new file mode 100755 index 00000000000..92463ade696 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation_resource.sql @@ -0,0 +1,22 @@ +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_workstation_workstation_resource( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_resource integer, + fk_workstation integer +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql new file mode 100755 index 00000000000..9ecccc88d82 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql @@ -0,0 +1,22 @@ +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_workstation_workstation_usergroup( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + tms timestamp, + fk_usergroup integer, + fk_workstation integer +) ENGINE=innodb; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index cf35c4c0f83..e3646eb8112 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1308,7 +1308,7 @@ YouUseBestDriver=You use driver %s which is the best driver currently available. YouDoNotUseBestDriver=You use driver %s but driver %s is recommended. NbOfObjectIsLowerThanNoPb=You have only %s %s in the database. This does not require any particular optimization. SearchOptim=Search optimization -YouHaveXObjectUseSearchOptim=You have %s %s in the database. You should add the constant %s to 1 in Home-Setup-Other. Limit the search to the beginning of strings which makes it possible for the database to use indexes and you should get an immediate response. +YouHaveXObjectUseSearchOptim=You have %s %s in the database. You can add the constant %s to 1 in Home-Setup-Other. Limit the search to the beginning of strings which makes it possible for the database to use indexes and you should get an immediate response. YouHaveXObjectAndSearchOptimOn=You have %s %s in the database and constant %s is set to 1 in Home-Setup-Other. BrowserIsOK=You are using the %s web browser. This browser is ok for security and performance. BrowserIsKO=You are using the %s web browser. This browser is known to be a bad choice for security, performance and reliability. We recommend using Firefox, Chrome, Opera or Safari. diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index 451da31cb5f..99dad8aa95a 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -96,8 +96,8 @@ LastXMonthRolling=The latest %s month rolling ChooseBoxToAdd=Add widget to your dashboard BoxAdded=Widget was added in your dashboard BoxTitleUserBirthdaysOfMonth=Birthdays of this month (users) -BoxLastManualEntries=Last manual entries in accountancy -BoxTitleLastManualEntries=%s latest manual entries +BoxLastManualEntries=Latest record in accountancy entered manually or without source document +BoxTitleLastManualEntries=%s latest record entered manually or without source document NoRecordedManualEntries=No manual entries record in accountancy BoxSuspenseAccount=Count accountancy operation with suspense account BoxTitleSuspenseAccount=Number of unallocated lines diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index cf7a828164b..5cdb042f933 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -224,6 +224,7 @@ Value=Value PersonalValue=Personal value NewObject=New %s NewValue=New value +OldValue=Old value %s CurrentValue=Current value Code=Code Type=Type @@ -655,6 +656,7 @@ SupplierPreview=Vendor preview ShowCustomerPreview=Show customer preview ShowSupplierPreview=Show vendor preview RefCustomer=Ref. customer +InternalRef=Internal ref. Currency=Currency InfoAdmin=Information for administrators Undo=Undo diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index 902f167d819..ec999a473a4 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -77,4 +77,28 @@ UnitCost=Unit cost TotalCost=Total cost BOMTotalCost=The cost to produce this BOM based on cost of each quantity and product to consume (use Cost price if defined, else Average Weighted Price if defined, else the Best purchase price) GoOnTabProductionToProduceFirst=You must first have started the production to close a Manufacturing Order (See tab '%s'). But you can Cancel it. -ErrorAVirtualProductCantBeUsedIntoABomOrMo=A kit can't be used into a BOM or a MO \ No newline at end of file +ErrorAVirtualProductCantBeUsedIntoABomOrMo=A kit can't be used into a BOM or a MO +Workstation=Workstation +Workstations=Workstations +WorkstationsDescription=Workstations management +WorkstationSetup = Workstations setup +WorkstationSetupPage = Workstations setup page +WorkstationAbout = About Workstation +WorkstationAboutPage = Workstations about page +WorkstationList=Workstation list +WorkstationCreate=Add new workstation +ConfirmEnableWorkstation=Are you sure you want to enable workstation %s ? +EnableAWorkstation=Enable a workstation +ConfirmDisableWorkstation=Are you sure you want to disable workstation %s ? +DisableAWorkstation=Disable a workstation +DeleteWorkstation=Supprimer +NbOperatorsRequired=Number of operators required +THMOperatorEstimated=Estimated operator THM +THMMachineEstimated=Estimated machine THM +WorkstationType=Workstation type +Human=Human +Machine=Machine +HumanMachine=Human / Machine +WorkstationArea=Workstation area +Machines=Machines +THMEstimatedHelp=This rate makes it possible to define a forecast cost of the item diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index a8521c09de1..447928225cd 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -875,7 +875,7 @@ Permission773=Supprimer les notes de frais Permission774=Lire toutes les notes de frais (même pour les utilisateurs en dehors de ma hierarchie) Permission775=Approuver les notes de frais Permission776=Payer les notes de frais -Permission777=Lisez les notes de frais de tout le monde +Permission777=Lire les notes de frais de tout le monde Permission778=Créer / modifier les notes de frais de tout le monde Permission779=Exporter les notes de frais Permission1001=Consulter les stocks diff --git a/htdocs/langs/fr_FR/boxes.lang b/htdocs/langs/fr_FR/boxes.lang index c889696c75e..3f94cdb2202 100644 --- a/htdocs/langs/fr_FR/boxes.lang +++ b/htdocs/langs/fr_FR/boxes.lang @@ -95,8 +95,8 @@ LastXMonthRolling=Les %s derniers mois tournant ChooseBoxToAdd=Ajouter le widget au tableau de bord BoxAdded=Le widget a été ajouté dans votre tableau de bord BoxTitleUserBirthdaysOfMonth=Anniversaires de ce mois (utilisateurs) -BoxLastManualEntries=Dernières entrées manuelles en comptabilité -BoxTitleLastManualEntries=%s dernières entrées manuelles +BoxLastManualEntries=Dernières entrées manuelles ou sans pièce source en comptabilité +BoxTitleLastManualEntries=Les %s dernières entrées manuelles ou sans pièce source NoRecordedManualEntries=Pas d'entrées manuelles en comptabilité BoxSuspenseAccount=Comptage des opérations de comptabilité avec compte d'attente BoxTitleSuspenseAccount=Nombre de lignes non allouées diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 5c3fd8ee46b..85f5d775929 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -412,7 +412,7 @@ if (!defined('NOTOKENRENEWAL')) //$dolibarr_nocsrfcheck=1; // Check token if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)) - || defined('CSRFCHECK_WITH_TOKEN')) // Check validity of token, only if option MAIN_SECURITY_CSRF_WITH_TOKEN enabled or if constant CSRFCHECK_WITH_TOKEN is set + || defined('CSRFCHECK_WITH_TOKEN')) // Check validity of token, only if option MAIN_SECURITY_CSRF_WITH_TOKEN enabled or if constant CSRFCHECK_WITH_TOKEN is set into page { // Check all cases that need a token (all POST actions, all actions and mass actions on pages with CSRFCHECK_WITH_TOKEN set, all sensitive GET actions) if ($_SERVER['REQUEST_METHOD'] == 'POST' || @@ -428,8 +428,12 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->gl die; } else { dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." refused by CSRFCHECK_WITH_TOKEN protection. Token not provided."); - print "Access to this page this way (POST method or page with CSRFCHECK_WITH_TOKEN on or having a sensible value for action parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n"; - print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0 into setup).\n"; + if (defined('CSRFCHECK_WITH_TOKEN')) { + print "Access to a page that needs a token (constant CSRFCHECK_WITH_TOKEN is defined) is refused by CSRF protection in main.inc.php. Token not provided.\n"; + } else { + print "Access to this page this way (POST method or GET with a sensible value for 'action' parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n"; + print "If you access your server behind a proxy using url rewriting and the parameter is provided by caller, you might check that all HTTP header are propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0 into setup).\n"; + } die; } } diff --git a/htdocs/modulebuilder/template/README.md b/htdocs/modulebuilder/template/README.md index c3afa63e1b7..45c5e4b51eb 100644 --- a/htdocs/modulebuilder/template/README.md +++ b/htdocs/modulebuilder/template/README.md @@ -2,17 +2,17 @@ ## Features -Description... +Description of the module... -Other modules are available on [Dolistore.com](https://www.dolistore.com). +Other external modules are available on [Dolistore.com](https://www.dolistore.com). ## Translations -Translations can be define manually by editing files into directories *langs*. +Translations can be completed manually by editing files into directories *langs*.