Merge branch '15.0' of git@github.com:Dolibarr/dolibarr.git into 15.0
This commit is contained in:
commit
0fa6329947
97
ChangeLog
97
ChangeLog
@ -3,6 +3,103 @@ English Dolibarr ChangeLog
|
|||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
***** ChangeLog for 15.0.2 compared to 15.0.1 *****
|
||||||
|
|
||||||
|
FIX: #19777 #20281
|
||||||
|
FIX: #20140 #20301
|
||||||
|
FIX: #20279 Accountancy - PostGreSQL - Error on mass update lines already binded
|
||||||
|
FIX: #20476 migration postgresql 14.0.x to 15.0.x packaging type
|
||||||
|
FIX: #20733 Inventory: Do not use batch qty even if present if batch module is disabled.
|
||||||
|
FIX: action comm list: holiday last day not included + handle duration with halfdays
|
||||||
|
FIX: Add missing entity on salary's payment
|
||||||
|
FIX: Add 'recruitment' into check array
|
||||||
|
FIX: add tools to fix bad bank amount in accounting with multicurrency
|
||||||
|
FIX: assign member cateogry to a member
|
||||||
|
FIX: backport
|
||||||
|
FIX: bad bank amount in accounting with multicurrency
|
||||||
|
FIX: Bad condition on remx
|
||||||
|
FIX: Bad filter on date on salary list
|
||||||
|
FIX: bad link to add a customer price (token duplicated)
|
||||||
|
FIX: bad status of member on widget by type and status
|
||||||
|
FIX: better error management at product selling price update
|
||||||
|
FIX: Can't edit bank record
|
||||||
|
FIX: check mandatory thirdparty fields for mass action
|
||||||
|
FIX: check thirdparty object loaded and properties exist
|
||||||
|
FIX: comment
|
||||||
|
FIX: compatibility for ticket number sharing
|
||||||
|
FIX: compatibility with multicompany sharings
|
||||||
|
FIX: contact card: single extrafield update failed
|
||||||
|
FIX: country not visible into list of states
|
||||||
|
FIX: Delete an extrafield where type is double
|
||||||
|
FIX: deprecated module are not more viewed as external modules
|
||||||
|
FIX: Disable customer type by default if type prospect/customer is disabled
|
||||||
|
FIX: each time we create a supplier order, we need to give it a ref_supplier
|
||||||
|
FIX: Error management
|
||||||
|
FIX: fatal error for $db usage in tpl
|
||||||
|
FIX: filter into the list of product lots
|
||||||
|
FIX: Filter on Object Referent page give CRSF page
|
||||||
|
FIX: Fix default options ($hidedetails, $hidedesc, $hideref) with globales when generate PDF in mass actions
|
||||||
|
FIX: Fix search by filters
|
||||||
|
FIX: Fix the adding of lines in the create invoice functions
|
||||||
|
FIX: forgotten form confirm before various payment delete
|
||||||
|
FIX: holiday/leave requests: write status change emails in HTML
|
||||||
|
FIX: include discount price for PMP after a reception (Issue #20029)
|
||||||
|
FIX: incrementation
|
||||||
|
FIX: in salary stats and payment list, we must check right perms as well as salary list
|
||||||
|
FIX: intervention entity missing
|
||||||
|
FIX: label tax cat trad
|
||||||
|
FIX: Mass action ship orders
|
||||||
|
FIX: missing advanced perms
|
||||||
|
FIX: missing call to executeHooks()
|
||||||
|
FIX: Missing entity on adding new VAT
|
||||||
|
FIX: missing hook for row ordering
|
||||||
|
FIX: missing hook parameter ($possiblelinks)
|
||||||
|
FIX: missing parenthesis
|
||||||
|
FIX: missing picto in combo of mass actions of thirdparties.
|
||||||
|
FIX: missing signature library when ODT model is used
|
||||||
|
FIX: Missing unset fields after updateline expensereport
|
||||||
|
FIX: ModuileBuilder - Fix getLinesArray() error reporting
|
||||||
|
FIX: Move delete task time trigger position
|
||||||
|
FIX: Navigation between invoices
|
||||||
|
FIX: No empty line inserted into accounting_bookkeeping
|
||||||
|
FIX: Numbering of sepa files
|
||||||
|
FIX: object cloning: set unique extrafield values to null to prevent duplicates
|
||||||
|
FIX: on update with action reminder in future there is user key error
|
||||||
|
FIX: originproductline array td identification data-id
|
||||||
|
FIX: out of memory when more than 100 000 invoices.
|
||||||
|
FIX: permit access to medias when logged in a different entity
|
||||||
|
FIX: phpcs
|
||||||
|
FIX: project creation prevented if PROJECTLEADER contact role renamed, de-activated or deleted
|
||||||
|
FIX: project timesheet by week: cleanup unused code
|
||||||
|
FIX: project timesheet: public holidays offset by 1 day
|
||||||
|
FIX: project timesheets: assume Saturday and Sunday as default weekend days when working days conf is empty or badly formed
|
||||||
|
FIX: propal list: bad error management when setting "not signed" mass action
|
||||||
|
FIX: propal list mass action translations and error management (v14 edition)
|
||||||
|
FIX: propal list: missing not signed massaction translation keys for transifex
|
||||||
|
FIX: PR returns
|
||||||
|
FIX: ref_client doesn't exists on supplier invoice, then ref_fourn needs to have a default value when we want to bill several supplier orders
|
||||||
|
FIX: replenish and manage product stock by warhouse
|
||||||
|
FIX: sending email on payment of registration of event
|
||||||
|
FIX: SEPA ICS is not mandatory for bank transfer
|
||||||
|
FIX: Set datec when add time spent on a project task
|
||||||
|
FIX: status filter on supplierOrder stats doesn't work
|
||||||
|
FIX: stickler-ci
|
||||||
|
FIX: still prevent project creation if PROJECTLEADER role unavailable, but with a specific error message
|
||||||
|
FIX: Supplier order stats
|
||||||
|
FIX: Tabulation must be allowed for HTML content
|
||||||
|
FIX: tool to fix bank account not in main currency for vendor invoice
|
||||||
|
FIX: translations
|
||||||
|
FIX: Travis + Update dev
|
||||||
|
FIX: truncate Customer Reference too long on PDF header (PR #20718)
|
||||||
|
FIX: uniformize code
|
||||||
|
FIX: Update of sale price (log not correctly updated)
|
||||||
|
FIX: user actions rights when mulit-company transverse mode is enabled
|
||||||
|
FIX: user employee tab: offset in open days messes up holiday length calculation
|
||||||
|
FIX: We need to have a different default_ref_supplier for each new fourn invoice
|
||||||
|
FIX: "WHERE" clause missing on resource export
|
||||||
|
FIX: #yogosha9754
|
||||||
|
|
||||||
|
|
||||||
***** ChangeLog for 15.0.1 compared to 15.0.0 *****
|
***** ChangeLog for 15.0.1 compared to 15.0.0 *****
|
||||||
FIX: #19777 #20281
|
FIX: #19777 #20281
|
||||||
FIX: bad position of extrafields for interventions
|
FIX: bad position of extrafields for interventions
|
||||||
|
|||||||
@ -431,12 +431,12 @@ if ($action == 'create') {
|
|||||||
// Account movement
|
// Account movement
|
||||||
print '<tr>';
|
print '<tr>';
|
||||||
print '<td class="titlefield">'.$langs->trans("NumMvts").'</td>';
|
print '<td class="titlefield">'.$langs->trans("NumMvts").'</td>';
|
||||||
print '<td>'.$object->piece_num.'</td>';
|
print '<td>'.($mode == '_tmp' ? '<span class="opacitymedium" title="Id tmp '.$object->piece_num.'">'.$langs->trans("Draft").'</span>' : $object->piece_num).'</td>';
|
||||||
print '</tr>';
|
print '</tr>';
|
||||||
|
|
||||||
// Date
|
// Date
|
||||||
print '<tr><td>';
|
print '<tr><td>';
|
||||||
print '<table class="nobordernopadding" width="100%"><tr><td>';
|
print '<table class="nobordernopadding centpercent"><tr><td>';
|
||||||
print $langs->trans('Docdate');
|
print $langs->trans('Docdate');
|
||||||
print '</td>';
|
print '</td>';
|
||||||
if ($action != 'editdate') {
|
if ($action != 'editdate') {
|
||||||
|
|||||||
@ -1851,6 +1851,19 @@ class BookKeeping extends CommonObject
|
|||||||
if ($next_piecenum < 0) {
|
if ($next_piecenum < 0) {
|
||||||
$error++;
|
$error++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$error) {
|
||||||
|
// Delete if there is an empty line
|
||||||
|
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity)." AND numero_compte IS NULL AND debit = 0 AND credit = 0";
|
||||||
|
$resql = $this->db->query($sql);
|
||||||
|
if (!$resql) {
|
||||||
|
$error++;
|
||||||
|
$this->errors[] = 'Error '.$this->db->lasterror();
|
||||||
|
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$error) {
|
||||||
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.' (doc_date, doc_type,';
|
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.' (doc_date, doc_type,';
|
||||||
$sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,';
|
$sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,';
|
||||||
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
|
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
|
||||||
@ -1866,6 +1879,9 @@ class BookKeeping extends CommonObject
|
|||||||
$this->errors[] = 'Error '.$this->db->lasterror();
|
$this->errors[] = 'Error '.$this->db->lasterror();
|
||||||
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$error) {
|
||||||
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
|
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
if (!$resql) {
|
if (!$resql) {
|
||||||
@ -1873,7 +1889,9 @@ class BookKeeping extends CommonObject
|
|||||||
$this->errors[] = 'Error '.$this->db->lasterror();
|
$this->errors[] = 'Error '.$this->db->lasterror();
|
||||||
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} elseif ($direction == 1) {
|
} elseif ($direction == 1) {
|
||||||
|
if (!$error) {
|
||||||
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
|
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
if (!$resql) {
|
if (!$resql) {
|
||||||
@ -1881,6 +1899,9 @@ class BookKeeping extends CommonObject
|
|||||||
$this->errors[] = 'Error '.$this->db->lasterror();
|
$this->errors[] = 'Error '.$this->db->lasterror();
|
||||||
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$error) {
|
||||||
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'_tmp (doc_date, doc_type,';
|
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'_tmp (doc_date, doc_type,';
|
||||||
$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
|
$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
|
||||||
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
|
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
|
||||||
@ -1896,6 +1917,9 @@ class BookKeeping extends CommonObject
|
|||||||
$this->errors[] = 'Error '.$this->db->lasterror();
|
$this->errors[] = 'Error '.$this->db->lasterror();
|
||||||
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$error) {
|
||||||
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
|
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
if (!$resql) {
|
if (!$resql) {
|
||||||
@ -1904,6 +1928,7 @@ class BookKeeping extends CommonObject
|
|||||||
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!$error) {
|
if (!$error) {
|
||||||
$this->db->commit();
|
$this->db->commit();
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@ -52,11 +52,12 @@ if (!empty($conf->salaries->enabled)) {
|
|||||||
|
|
||||||
|
|
||||||
$id = GETPOST('rowid', 'int');
|
$id = GETPOST('rowid', 'int');
|
||||||
$accountid = (GETPOST('id', 'int') ? GETPOST('id', 'int') : GETPOST('account', 'int'));
|
$rowid = GETPOST("rowid", 'int');
|
||||||
|
$accountoldid = GETPOST('account', 'int'); // GETPOST('account') is old account id
|
||||||
|
$accountid = GETPOST('accountid', 'int'); // GETPOST('accountid') is new account id
|
||||||
$ref = GETPOST('ref', 'alpha');
|
$ref = GETPOST('ref', 'alpha');
|
||||||
$action = GETPOST('action', 'aZ09');
|
$action = GETPOST('action', 'aZ09');
|
||||||
$confirm = GETPOST('confirm', 'alpha');
|
$confirm = GETPOST('confirm', 'alpha');
|
||||||
$rowid = GETPOST("rowid", 'int');
|
|
||||||
$orig_account = GETPOST("orig_account");
|
$orig_account = GETPOST("orig_account");
|
||||||
$backtopage = GETPOST('backtopage', 'alpha');
|
$backtopage = GETPOST('backtopage', 'alpha');
|
||||||
$cancel = GETPOST('cancel', 'alpha');
|
$cancel = GETPOST('cancel', 'alpha');
|
||||||
@ -69,7 +70,7 @@ if ($user->socid) {
|
|||||||
$socid = $user->socid;
|
$socid = $user->socid;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = restrictedArea($user, 'banque', $accountid, 'bank_account');
|
$result = restrictedArea($user, 'banque', $accountoldid, 'bank_account');
|
||||||
if (empty($user->rights->banque->lire) && empty($user->rights->banque->consolidate)) {
|
if (empty($user->rights->banque->lire) && empty($user->rights->banque->consolidate)) {
|
||||||
accessforbidden();
|
accessforbidden();
|
||||||
}
|
}
|
||||||
@ -124,18 +125,26 @@ if ($user->rights->banque->modifier && $action == "update") {
|
|||||||
$error = 0;
|
$error = 0;
|
||||||
|
|
||||||
$acline = new AccountLine($db);
|
$acline = new AccountLine($db);
|
||||||
$acline->fetch($rowid);
|
$result = $acline->fetch($rowid);
|
||||||
|
if ($result <= 0) {
|
||||||
|
dol_syslog('Failed to read bank line with id '.$rowid, LOG_WARNING); // This happens due to old bug that has set fk_account to null.
|
||||||
|
$acline->id = $rowid;
|
||||||
|
}
|
||||||
|
|
||||||
$acsource = new Account($db);
|
$acsource = new Account($db);
|
||||||
$acsource->fetch($id);
|
$acsource->fetch($accountoldid);
|
||||||
|
|
||||||
$actarget = new Account($db);
|
$actarget = new Account($db);
|
||||||
if (GETPOST('accountid', 'int') > 0 && !$acline->rappro && !$acline->getVentilExportCompta()) { // We ask to change bank account
|
if (GETPOST('accountid', 'int') > 0 && !$acline->rappro && !$acline->getVentilExportCompta()) { // We ask to change bank account
|
||||||
$actarget->fetch(GETPOST('accountid', 'int'));
|
$actarget->fetch(GETPOST('accountid', 'int'));
|
||||||
} else {
|
} else {
|
||||||
$actarget->fetch($id);
|
$actarget->fetch($accountoldid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!($actarget->id > 0)) {
|
||||||
|
setEventMessages($langs->trans("ErrorFailedToLoadBankAccount"), null, 'errors');
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
if ($actarget->courant == Account::TYPE_CASH && GETPOST('value', 'alpha') != 'LIQ') {
|
if ($actarget->courant == Account::TYPE_CASH && GETPOST('value', 'alpha') != 'LIQ') {
|
||||||
setEventMessages($langs->trans("ErrorCashAccountAcceptsOnlyCashMoney"), null, 'errors');
|
setEventMessages($langs->trans("ErrorCashAccountAcceptsOnlyCashMoney"), null, 'errors');
|
||||||
$error++;
|
$error++;
|
||||||
@ -307,7 +316,6 @@ if ($result) {
|
|||||||
print '<input type="hidden" name="action" value="update">';
|
print '<input type="hidden" name="action" value="update">';
|
||||||
print '<input type="hidden" name="orig_account" value="'.$orig_account.'">';
|
print '<input type="hidden" name="orig_account" value="'.$orig_account.'">';
|
||||||
print '<input type="hidden" name="account" value="'.$acct->id.'">';
|
print '<input type="hidden" name="account" value="'.$acct->id.'">';
|
||||||
print '<input type="hidden" name="id" value="'.$acct->id.'">';
|
|
||||||
|
|
||||||
print dol_get_fiche_head($head, 'bankline', $langs->trans('LineRecord'), 0, 'accountline', 0);
|
print dol_get_fiche_head($head, 'bankline', $langs->trans('LineRecord'), 0, 'accountline', 0);
|
||||||
|
|
||||||
@ -326,11 +334,12 @@ if ($result) {
|
|||||||
// Bank account
|
// Bank account
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("Account").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("Account").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
if (!$objp->rappro && !$bankline->getVentilExportCompta()) {
|
// $objp->fk_account may be not > 0 if data was lost by an old bug. In such a case, we let a chance to user to fix it.
|
||||||
print img_picto('', 'bank_account', 'class="paddingright"');
|
if (($objp->rappro || $bankline->getVentilExportCompta()) && $objp->fk_account > 0) {
|
||||||
print $form->select_comptes($acct->id, 'accountid', 0, '', 0, '', 0, '', 1);
|
|
||||||
} else {
|
|
||||||
print $acct->getNomUrl(1, 'transactions', 'reflabel');
|
print $acct->getNomUrl(1, 'transactions', 'reflabel');
|
||||||
|
} else {
|
||||||
|
print img_picto('', 'bank_account', 'class="paddingright"');
|
||||||
|
print $form->select_comptes($acct->id, 'accountid', 0, '', ($acct->id > 0 ? $acct->id : 1), '', 0, '', 1);
|
||||||
}
|
}
|
||||||
print '</td>';
|
print '</td>';
|
||||||
print '</tr>';
|
print '</tr>';
|
||||||
|
|||||||
@ -102,7 +102,7 @@ if ($mode == 'customer') {
|
|||||||
$stats->where .= ' AND f.fk_statut IN ('.$db->sanitize($object_status).')';
|
$stats->where .= ' AND f.fk_statut IN ('.$db->sanitize($object_status).')';
|
||||||
}
|
}
|
||||||
if (is_array($custcats) && !empty($custcats)) {
|
if (is_array($custcats) && !empty($custcats)) {
|
||||||
$stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cat OmdN (f.fk_soc = cat.fk_soc)';
|
$stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cat ON (f.fk_soc = cat.fk_soc)';
|
||||||
$stats->where .= ' AND cat.fk_categorie IN ('.$db->sanitize(implode(',', $custcats)).')';
|
$stats->where .= ' AND cat.fk_categorie IN ('.$db->sanitize(implode(',', $custcats)).')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ if (!defined('NOREQUIRETRAN')) {
|
|||||||
|
|
||||||
require '../../main.inc.php';
|
require '../../main.inc.php';
|
||||||
require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php';
|
require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php';
|
||||||
|
$hookmanager->initHooks(array('rowinterface'));
|
||||||
// Security check
|
// Security check
|
||||||
// This is done later into view.
|
// This is done later into view.
|
||||||
|
|
||||||
@ -116,7 +116,15 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3)
|
|||||||
$perm = 1;
|
$perm = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$parameters = array('roworder'=> &$roworder, 'table_element_line' => &$table_element_line, 'fk_element' => &$fk_element, 'element_id' => &$element_id, 'perm' => &$perm);
|
||||||
|
$row = new GenericObject($db);
|
||||||
|
$row->table_element_line = $table_element_line;
|
||||||
|
$row->fk_element = $fk_element;
|
||||||
|
$row->id = $element_id;
|
||||||
|
$reshook = $hookmanager->executeHooks('checkRowPerms', $parameters, $row, $action);
|
||||||
|
if ($reshook > 0) {
|
||||||
|
$perm = $hookmanager->resArray['perm'];
|
||||||
|
}
|
||||||
if (! $perm) {
|
if (! $perm) {
|
||||||
// We should not be here. If we are not allowed to reorder rows, feature should not be visible on script.
|
// We should not be here. If we are not allowed to reorder rows, feature should not be visible on script.
|
||||||
// If we are here, it is a hack attempt, so we report a warning.
|
// If we are here, it is a hack attempt, so we report a warning.
|
||||||
@ -133,10 +141,7 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = new GenericObject($db);
|
|
||||||
$row->table_element_line = $table_element_line;
|
|
||||||
$row->fk_element = $fk_element;
|
|
||||||
$row->id = $element_id;
|
|
||||||
|
|
||||||
$row->line_ajaxorder($newrowordertab); // This update field rank or position in table row->table_element_line
|
$row->line_ajaxorder($newrowordertab); // This update field rank or position in table row->table_element_line
|
||||||
|
|
||||||
|
|||||||
@ -892,7 +892,7 @@ class FormFile
|
|||||||
}
|
}
|
||||||
$out .= '>';
|
$out .= '>';
|
||||||
$out .= img_mime($file["name"], $langs->trans("File").': '.$file["name"]);
|
$out .= img_mime($file["name"], $langs->trans("File").': '.$file["name"]);
|
||||||
$out .= dol_trunc($file["name"], 150);
|
$out .= dol_trunc($file["name"], 40);
|
||||||
$out .= '</a>'."\n";
|
$out .= '</a>'."\n";
|
||||||
$out .= $this->showPreview($file, $modulepart, $relativepath, 0, $param);
|
$out .= $this->showPreview($file, $modulepart, $relativepath, 0, $param);
|
||||||
$out .= '</td>';
|
$out .= '</td>';
|
||||||
|
|||||||
@ -271,7 +271,7 @@ function societe_prepare_head(Societe $object)
|
|||||||
$h++;
|
$h++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'thirdparty') {
|
if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR', 'thirdparty') == 'thirdparty') {
|
||||||
if (!empty($user->rights->partnership->read)) {
|
if (!empty($user->rights->partnership->read)) {
|
||||||
$langs->load("partnership");
|
$langs->load("partnership");
|
||||||
$nbPartnership = is_array($object->partnerships) ? count($object->partnerships) : 0;
|
$nbPartnership = is_array($object->partnerships) ? count($object->partnerships) : 0;
|
||||||
|
|||||||
@ -8200,7 +8200,7 @@ function verifCond($strToEvaluate)
|
|||||||
* @param string $s String to evaluate
|
* @param string $s String to evaluate
|
||||||
* @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)).
|
* @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)).
|
||||||
* @param int $hideerrors 1=Hide errors
|
* @param int $hideerrors 1=Hide errors
|
||||||
* @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s$_->&|=';, 2=Accept also '!?():"\';,/'
|
* @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s^$_+-.*\/>&|=!?():"\',/';, 2=Accept also ';[]'
|
||||||
* @return mixed Nothing or return result of eval
|
* @return mixed Nothing or return result of eval
|
||||||
*/
|
*/
|
||||||
function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1')
|
function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1')
|
||||||
@ -8218,7 +8218,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
|
|||||||
// Test dangerous char (used for RCE), we allow only PHP variable testing.
|
// Test dangerous char (used for RCE), we allow only PHP variable testing.
|
||||||
if ($onlysimplestring == '1') {
|
if ($onlysimplestring == '1') {
|
||||||
//print preg_quote('$_->&|', '/');
|
//print preg_quote('$_->&|', '/');
|
||||||
if (preg_match('/[^a-z0-9\s'.preg_quote('$_+-*/>&|=!?():"', '/').']/i', $s)) {
|
if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-.*/>&|=!?():"\',/', '/').']/i', $s)) {
|
||||||
if ($returnvalue) {
|
if ($returnvalue) {
|
||||||
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s;
|
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s;
|
||||||
} else {
|
} else {
|
||||||
@ -8228,7 +8228,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
|
|||||||
}
|
}
|
||||||
} elseif ($onlysimplestring == '2') {
|
} elseif ($onlysimplestring == '2') {
|
||||||
//print preg_quote('$_->&|', '/');
|
//print preg_quote('$_->&|', '/');
|
||||||
if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-*/>&|=!?():"\';,/', '/').']/i', $s)) {
|
if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-.*/>&|=!?():"\',/;[]', '/').']/i', $s)) {
|
||||||
if ($returnvalue) {
|
if ($returnvalue) {
|
||||||
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s;
|
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s;
|
||||||
} else {
|
} else {
|
||||||
@ -8245,7 +8245,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strpos($s, '.') !== false) {
|
if (preg_match('/[^0-9]+\.[^0-9]+/', $s)) { // We refuse . if not between 2 numbers
|
||||||
if ($returnvalue) {
|
if ($returnvalue) {
|
||||||
return 'Bad string syntax to evaluate (dot char is forbidden): '.$s;
|
return 'Bad string syntax to evaluate (dot char is forbidden): '.$s;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -291,11 +291,12 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage,
|
|||||||
* @param string $fileindex Full path of file index.php
|
* @param string $fileindex Full path of file index.php
|
||||||
* @param string $filetpl File tpl the index.php page redirect to (used only if $fileindex is provided)
|
* @param string $filetpl File tpl the index.php page redirect to (used only if $fileindex is provided)
|
||||||
* @param string $filewrapper Full path of file wrapper.php
|
* @param string $filewrapper Full path of file wrapper.php
|
||||||
|
* @param Website $object Object website
|
||||||
* @return boolean True if OK
|
* @return boolean True if OK
|
||||||
*/
|
*/
|
||||||
function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
|
function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object = null)
|
||||||
{
|
{
|
||||||
global $conf;
|
global $conf, $db;
|
||||||
|
|
||||||
$result1 = false;
|
$result1 = false;
|
||||||
$result2 = false;
|
$result2 = false;
|
||||||
@ -320,6 +321,44 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
|
|||||||
if (!empty($conf->global->MAIN_UMASK)) {
|
if (!empty($conf->global->MAIN_UMASK)) {
|
||||||
@chmod($fileindex, octdec($conf->global->MAIN_UMASK));
|
@chmod($fileindex, octdec($conf->global->MAIN_UMASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_object($object) && $object->fk_default_home > 0) {
|
||||||
|
$objectpage = new WebsitePage($db);
|
||||||
|
$objectpage->fetch($object->fk_default_home);
|
||||||
|
|
||||||
|
// Create a version for sublanguages
|
||||||
|
if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
|
||||||
|
if (empty($conf->global->WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR) && is_object($object) && !empty($object->otherlang)) {
|
||||||
|
$dirname = dirname($fileindex);
|
||||||
|
foreach (explode(',', $object->otherlang) as $sublang) {
|
||||||
|
// Avoid to erase main alias file if $sublang is empty string
|
||||||
|
if (empty(trim($sublang))) continue;
|
||||||
|
$fileindexsub = $dirname.'/'.$sublang.'/index.php';
|
||||||
|
|
||||||
|
// Same indexcontent than previously but with ../ instead of ./ for master and tpl file include/require_once.
|
||||||
|
$relpath = '..';
|
||||||
|
$indexcontent = '<?php'."\n";
|
||||||
|
$indexcontent .= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
|
||||||
|
$indexcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
|
||||||
|
$indexcontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once '".$relpath."/master.inc.php'; } // Load master if not already loaded\n";
|
||||||
|
$indexcontent .= 'if (! empty($_GET[\'pageref\']) || ! empty($_GET[\'pagealiasalt\']) || ! empty($_GET[\'pageid\'])) {'."\n";
|
||||||
|
$indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
|
||||||
|
$indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
|
||||||
|
$indexcontent .= ' redirectToContainer($_GET[\'pageref\'], $_GET[\'pagealiasalt\'], $_GET[\'pageid\']);'."\n";
|
||||||
|
$indexcontent .= "}\n";
|
||||||
|
$indexcontent .= "include_once '".$relpath."/".basename($filetpl)."'\n"; // use .. instead of .
|
||||||
|
$indexcontent .= '// END PHP ?>'."\n";
|
||||||
|
$result = file_put_contents($fileindexsub, $indexcontent);
|
||||||
|
if ($result === false) {
|
||||||
|
dol_syslog("Failed to write file ".$fileindexsub, LOG_WARNING);
|
||||||
|
}
|
||||||
|
if (!empty($conf->global->MAIN_UMASK)) {
|
||||||
|
@chmod($fileindexsub, octdec($conf->global->MAIN_UMASK));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$result1 = true;
|
$result1 = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
|
|||||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
|
||||||
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -43,7 +43,6 @@ $forcereloadpage = empty($conf->global->MAIN_FORCE_RELOAD_PAGE) ? 0 : 1;
|
|||||||
$tagidfortablednd = (empty($tagidfortablednd) ? 'tablelines' : $tagidfortablednd);
|
$tagidfortablednd = (empty($tagidfortablednd) ? 'tablelines' : $tagidfortablednd);
|
||||||
$filepath = (empty($filepath) ? '' : $filepath);
|
$filepath = (empty($filepath) ? '' : $filepath);
|
||||||
|
|
||||||
|
|
||||||
if (GETPOST('action', 'aZ09') != 'editline' && $nboflines > 1 && $conf->browser->layout != 'phone') { ?>
|
if (GETPOST('action', 'aZ09') != 'editline' && $nboflines > 1 && $conf->browser->layout != 'phone') { ?>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
|
|||||||
@ -511,6 +511,21 @@ INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) value
|
|||||||
-- VMYSQL4.3 ALTER TABLE llx_user MODIFY COLUMN fk_soc integer NULL;
|
-- VMYSQL4.3 ALTER TABLE llx_user MODIFY COLUMN fk_soc integer NULL;
|
||||||
-- VPGSQL8.2 ALTER TABLE llx_user ALTER COLUMN fk_soc DROP NOT NULL;
|
-- VPGSQL8.2 ALTER TABLE llx_user ALTER COLUMN fk_soc DROP NOT NULL;
|
||||||
|
|
||||||
|
CREATE TABLE llx_element_tag
|
||||||
|
(
|
||||||
|
rowid integer AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
fk_categorie integer NOT NULL,
|
||||||
|
fk_element integer NOT NULL,
|
||||||
|
import_key varchar(14)
|
||||||
|
)ENGINE=innodb;
|
||||||
|
|
||||||
|
ALTER TABLE llx_element_tag ADD COLUMN fk_categorie integer;
|
||||||
|
ALTER TABLE llx_element_tag ADD COLUMN fk_element integer;
|
||||||
|
|
||||||
|
ALTER TABLE llx_element_tag ADD UNIQUE INDEX idx_element_tag_uk (fk_categorie, fk_element);
|
||||||
|
|
||||||
|
ALTER TABLE llx_element_tag ADD CONSTRAINT fk_element_tag_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid);
|
||||||
|
|
||||||
-- Add column to help to fix a very critical bug when transferring into accounting bank record of a bank account into another currency.
|
-- Add column to help to fix a very critical bug when transferring into accounting bank record of a bank account into another currency.
|
||||||
-- Idea is to update this column manually in v15 with value in currency of company for bank that are not into the main currency and the transfer
|
-- Idea is to update this column manually in v15 with value in currency of company for bank that are not into the main currency and the transfer
|
||||||
-- into accounting will use it in priority if value is not null. The script repair.sql contains the sequence to fix datas in llx_bank.
|
-- into accounting will use it in priority if value is not null. The script repair.sql contains the sequence to fix datas in llx_bank.
|
||||||
|
|||||||
@ -40,8 +40,8 @@ create table llx_product
|
|||||||
customcode varchar(32), -- Optionnal custom code
|
customcode varchar(32), -- Optionnal custom code
|
||||||
fk_country integer DEFAULT NULL, -- Optionnal id of original country
|
fk_country integer DEFAULT NULL, -- Optionnal id of original country
|
||||||
fk_state integer DEFAULT NULL, -- Optionnal id of original state/province
|
fk_state integer DEFAULT NULL, -- Optionnal id of original state/province
|
||||||
price double(24,8) DEFAULT 0,
|
price double(24,8) DEFAULT 0, -- price without tax
|
||||||
price_ttc double(24,8) DEFAULT 0,
|
price_ttc double(24,8) DEFAULT 0, -- price inc vat (but not localtax1 nor localtax2)
|
||||||
price_min double(24,8) DEFAULT 0,
|
price_min double(24,8) DEFAULT 0,
|
||||||
price_min_ttc double(24,8) DEFAULT 0,
|
price_min_ttc double(24,8) DEFAULT 0,
|
||||||
price_base_type varchar(3) DEFAULT 'HT',
|
price_base_type varchar(3) DEFAULT 'HT',
|
||||||
|
|||||||
@ -29,8 +29,8 @@ create table llx_product_price
|
|||||||
fk_product integer NOT NULL,
|
fk_product integer NOT NULL,
|
||||||
date_price datetime NOT NULL,
|
date_price datetime NOT NULL,
|
||||||
price_level smallint NULL DEFAULT 1,
|
price_level smallint NULL DEFAULT 1,
|
||||||
price double(24,8) DEFAULT NULL,
|
price double(24,8) DEFAULT NULL, -- price without tax
|
||||||
price_ttc double(24,8) DEFAULT NULL,
|
price_ttc double(24,8) DEFAULT NULL, -- price inc vat (but not localtax1 nor localtax2)
|
||||||
price_min double(24,8) default NULL,
|
price_min double(24,8) default NULL,
|
||||||
price_min_ttc double(24,8) default NULL,
|
price_min_ttc double(24,8) default NULL,
|
||||||
price_base_type varchar(3) DEFAULT 'HT',
|
price_base_type varchar(3) DEFAULT 'HT',
|
||||||
|
|||||||
@ -102,6 +102,7 @@ WrongSupplierCode=Vendor code invalid
|
|||||||
CustomerCodeModel=Customer code model
|
CustomerCodeModel=Customer code model
|
||||||
SupplierCodeModel=Vendor code model
|
SupplierCodeModel=Vendor code model
|
||||||
Gencod=Barcode
|
Gencod=Barcode
|
||||||
|
GencodBuyPrice=Barcode of price ref
|
||||||
##### Professional ID #####
|
##### Professional ID #####
|
||||||
ProfId1Short=Prof. id 1
|
ProfId1Short=Prof. id 1
|
||||||
ProfId2Short=Prof. id 2
|
ProfId2Short=Prof. id 2
|
||||||
|
|||||||
@ -275,6 +275,9 @@ ErrorIsNotADraft=%s is not a draft
|
|||||||
ErrorExecIdFailed=Can't execute command "id"
|
ErrorExecIdFailed=Can't execute command "id"
|
||||||
ErrorBadCharIntoLoginName=Unauthorized character in the login name
|
ErrorBadCharIntoLoginName=Unauthorized character in the login name
|
||||||
ErrorNotApproverForHoliday=You are not the approver for leave %s
|
ErrorNotApproverForHoliday=You are not the approver for leave %s
|
||||||
|
ErrorInvoiceLoadThirdParty=Can't load third-party object for invoice "%s"
|
||||||
|
ErrorInvoiceLoadThirdPartyKey=Third-party key "%s" no set for invoice "%s"
|
||||||
|
ErrorDeleteLineNotAllowedByObjectStatus=Delete line is not allowed by actual object status
|
||||||
|
|
||||||
# Warnings
|
# Warnings
|
||||||
WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.
|
WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.
|
||||||
@ -308,9 +311,9 @@ WarningTheHiddenOptionIsOn=Warning, the hidden option <b>%s</b> is on.
|
|||||||
WarningCreateSubAccounts=Warning, you can't create directly a sub account, you must create a third party or an user and assign them an accounting code to find them in this list
|
WarningCreateSubAccounts=Warning, you can't create directly a sub account, you must create a third party or an user and assign them an accounting code to find them in this list
|
||||||
WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connection.
|
WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connection.
|
||||||
WarningModuleXDisabledSoYouMayMissEventHere=Module %s has not been enabled. So you may miss a lot of event here.
|
WarningModuleXDisabledSoYouMayMissEventHere=Module %s has not been enabled. So you may miss a lot of event here.
|
||||||
<<<<<<< HEAD
|
|
||||||
WarningPaypalPaymentNotCompatibleWithStrict=The value 'Strict' makes the online payment features not working correctly. Use 'Lax' instead.
|
WarningPaypalPaymentNotCompatibleWithStrict=The value 'Strict' makes the online payment features not working correctly. Use 'Lax' instead.
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
# Validate
|
# Validate
|
||||||
RequireValidValue = Value not valid
|
RequireValidValue = Value not valid
|
||||||
@ -336,3 +339,5 @@ BadSetupOfFieldFetchNotCallable = Error bad setup of field : Fetch not callable
|
|||||||
=======
|
=======
|
||||||
>>>>>>> branch '13.0' of git@github.com:Dolibarr/dolibarr.git
|
>>>>>>> branch '13.0' of git@github.com:Dolibarr/dolibarr.git
|
||||||
>>>>>>> branch '14.0' of git@github.com:Dolibarr/dolibarr.git
|
>>>>>>> branch '14.0' of git@github.com:Dolibarr/dolibarr.git
|
||||||
|
=======
|
||||||
|
>>>>>>> branch '14.0' of git@github.com:Dolibarr/dolibarr.git
|
||||||
|
|||||||
@ -418,7 +418,7 @@ TotalLT2IN=Total SGST
|
|||||||
HT=HT
|
HT=HT
|
||||||
TTC=TTC
|
TTC=TTC
|
||||||
INCVATONLY=TVA incluse
|
INCVATONLY=TVA incluse
|
||||||
INCT=TTC
|
INCT=TVA+Taxes locales incluses
|
||||||
VAT=TVA
|
VAT=TVA
|
||||||
VATIN=IGST
|
VATIN=IGST
|
||||||
VATs=TVA
|
VATs=TVA
|
||||||
|
|||||||
@ -493,10 +493,13 @@ $trackid = 'xxxx'.$object->id;
|
|||||||
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
|
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
|
||||||
|
|
||||||
if ($search_all) {
|
if ($search_all) {
|
||||||
|
$setupstring = '';
|
||||||
foreach ($fieldstosearchall as $key => $val) {
|
foreach ($fieldstosearchall as $key => $val) {
|
||||||
$fieldstosearchall[$key] = $langs->trans($val);
|
$fieldstosearchall[$key] = $langs->trans($val);
|
||||||
|
$setupstring .= $key."=".$val.";";
|
||||||
}
|
}
|
||||||
print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>';
|
print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
|
||||||
|
print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>'."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$moreforfilter = '';
|
$moreforfilter = '';
|
||||||
|
|||||||
@ -2044,7 +2044,7 @@ class Product extends CommonObject
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify customer price of a product/Service
|
* Modify customer price of a product/Service for a given level
|
||||||
*
|
*
|
||||||
* @param double $newprice New price
|
* @param double $newprice New price
|
||||||
* @param string $newpricebase HT or TTC
|
* @param string $newpricebase HT or TTC
|
||||||
|
|||||||
@ -178,7 +178,7 @@ if (!empty($conf->barcode->enabled)) {
|
|||||||
$fieldstosearchall['p.barcode'] = 'Gencod';
|
$fieldstosearchall['p.barcode'] = 'Gencod';
|
||||||
$fieldstosearchall['pfp.barcode'] = 'GencodBuyPrice';
|
$fieldstosearchall['pfp.barcode'] = 'GencodBuyPrice';
|
||||||
}
|
}
|
||||||
// Personalized search criterias. Example: $conf->global->PRODUCT_QUICKSEARCH_ON_FIELDS = 'p.ref=ProductRef;p.label=ProductLabel'
|
// Personalized search criterias. Example: $conf->global->PRODUCT_QUICKSEARCH_ON_FIELDS = 'p.ref=ProductRef;p.label=ProductLabel;p.description=Description;p.note=Note;'
|
||||||
if (!empty($conf->global->PRODUCT_QUICKSEARCH_ON_FIELDS)) {
|
if (!empty($conf->global->PRODUCT_QUICKSEARCH_ON_FIELDS)) {
|
||||||
$fieldstosearchall = dolExplodeIntoArray($conf->global->PRODUCT_QUICKSEARCH_ON_FIELDS);
|
$fieldstosearchall = dolExplodeIntoArray($conf->global->PRODUCT_QUICKSEARCH_ON_FIELDS);
|
||||||
}
|
}
|
||||||
@ -800,10 +800,13 @@ if ($resql) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($sall) {
|
if ($sall) {
|
||||||
|
$setupstring = '';
|
||||||
foreach ($fieldstosearchall as $key => $val) {
|
foreach ($fieldstosearchall as $key => $val) {
|
||||||
$fieldstosearchall[$key] = $langs->trans($val);
|
$fieldstosearchall[$key] = $langs->trans($val);
|
||||||
|
$setupstring .= $key."=".$val.";";
|
||||||
}
|
}
|
||||||
print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'</div>';
|
print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
|
||||||
|
print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'</div>'."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter on categories
|
// Filter on categories
|
||||||
|
|||||||
@ -192,17 +192,52 @@ if (empty($reshook)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$error) {
|
if (!$error) {
|
||||||
// Force the update of the price of the product to 0 if error
|
if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
|
||||||
|
for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) {
|
||||||
|
// Force the update of the price of the product using the new VAT
|
||||||
|
if ($object->multiprices_base_type[$i] == 'HT') {
|
||||||
|
$oldprice = $object->multiprices[$i];
|
||||||
|
$oldminprice = $object->multiprices_min[$i];
|
||||||
|
} else {
|
||||||
|
$oldprice = $object->multiprices_ttc[$i];
|
||||||
|
$oldminprice = $object->multiprices_min_ttc[$i];
|
||||||
|
}
|
||||||
|
$oldpricebasetype = $object->multiprices_base_type[$i];
|
||||||
|
$oldnpr = $object->multiprices_recuperableonly[$i];
|
||||||
|
|
||||||
//$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2);
|
//$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2);
|
||||||
$localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them.
|
$localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them.
|
||||||
$ret = $object->updatePrice(0, $object->price_base_type, $user, $tva_tx, '', 0, $npr, 0, 0, $localtaxarray, $vatratecode);
|
$level = $i;
|
||||||
|
$ret = $object->updatePrice($oldprice, $oldpricebasetype, $user, $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode);
|
||||||
|
|
||||||
if ($ret < 0) {
|
if ($ret < 0) {
|
||||||
$error++;
|
$error++;
|
||||||
setEventMessages($object->error, $object->errors, 'errors');
|
setEventMessages($object->error, $object->errors, 'errors');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Force the update of the price of the product using the new VAT
|
||||||
|
if ($object->price_base_type == 'HT') {
|
||||||
|
$oldprice = $object->price;
|
||||||
|
$oldminprice = $object->price_min;
|
||||||
|
} else {
|
||||||
|
$oldprice = $object->price_ttc;
|
||||||
|
$oldminprice = $object->price_min_ttc;
|
||||||
|
}
|
||||||
|
$oldpricebasetype = $object->price_base_type;
|
||||||
|
$oldnpr = $object->tva_npr;
|
||||||
|
|
||||||
|
//$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2);
|
||||||
|
$localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them.
|
||||||
|
$level = 0;
|
||||||
|
$ret = $object->updatePrice($oldprice, $oldpricebasetype, $user, $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode);
|
||||||
|
|
||||||
|
if ($ret < 0) {
|
||||||
|
$error++;
|
||||||
|
setEventMessages($object->error, $object->errors, 'errors');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$error) {
|
if (!$error) {
|
||||||
$db->commit();
|
$db->commit();
|
||||||
@ -1602,6 +1637,7 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul
|
|||||||
}
|
}
|
||||||
$sql .= " ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
|
$sql .= " ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
|
||||||
// $sql .= $db->plimit();
|
// $sql .= $db->plimit();
|
||||||
|
//print $sql;
|
||||||
|
|
||||||
$result = $db->query($sql);
|
$result = $db->query($sql);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
@ -1640,8 +1676,9 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul
|
|||||||
print_barre_liste($langs->trans("PriceByCustomerLog"), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, $num, 'title_accountancy.png');
|
print_barre_liste($langs->trans("PriceByCustomerLog"), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, $num, 'title_accountancy.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
print '<div class="div-table-responsive">';
|
print '<!-- List of log prices -->'."\n";
|
||||||
print '<table class="liste centpercent">';
|
print '<div class="div-table-responsive">'."\n";
|
||||||
|
print '<table class="liste centpercent">'."\n";
|
||||||
|
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
print '<td>'.$langs->trans("AppliedPricesFrom").'</td>';
|
print '<td>'.$langs->trans("AppliedPricesFrom").'</td>';
|
||||||
@ -1659,6 +1696,9 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul
|
|||||||
}
|
}
|
||||||
print '<td class="right">'.$langs->trans("HT").'</td>';
|
print '<td class="right">'.$langs->trans("HT").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("TTC").'</td>';
|
print '<td class="right">'.$langs->trans("TTC").'</td>';
|
||||||
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
|
print '<td class="right">'.$langs->trans("INCT").'</td>';
|
||||||
|
}
|
||||||
if (!empty($conf->dynamicprices->enabled)) {
|
if (!empty($conf->dynamicprices->enabled)) {
|
||||||
print '<td class="right">'.$langs->trans("PriceExpressionSelected").'</td>';
|
print '<td class="right">'.$langs->trans("PriceExpressionSelected").'</td>';
|
||||||
}
|
}
|
||||||
@ -1725,6 +1765,24 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul
|
|||||||
print "</td>";
|
print "</td>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Line for default price
|
||||||
|
if ($objp->price_base_type == 'HT') {
|
||||||
|
$pu = $objp->price;
|
||||||
|
} else {
|
||||||
|
$pu = $objp->price_ttc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local tax was not saved into table llx_product on old version. So we will use value linked to VAT code.
|
||||||
|
$localtaxarray = getLocalTaxesFromRate($objp->tva_tx.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), 0, $mysoc, $mysoc);
|
||||||
|
// Define part of HT, VAT, TTC
|
||||||
|
$resultarray = calcul_price_total(1, $pu, 0, $objp->tva_tx, 1, 1, 0, $objp->price_base_type, $objp->recuperableonly, $object->type, $mysoc, $localtaxarray);
|
||||||
|
// Calcul du total ht sans remise
|
||||||
|
$total_ht = $resultarray[0];
|
||||||
|
$total_vat = $resultarray[1];
|
||||||
|
$total_localtax1 = $resultarray[9];
|
||||||
|
$total_localtax2 = $resultarray[10];
|
||||||
|
$total_ttc = $resultarray[2];
|
||||||
|
|
||||||
// Price
|
// Price
|
||||||
if (!empty($objp->fk_price_expression) && !empty($conf->dynamicprices->enabled)) {
|
if (!empty($objp->fk_price_expression) && !empty($conf->dynamicprices->enabled)) {
|
||||||
$price_expression = new PriceExpression($db);
|
$price_expression = new PriceExpression($db);
|
||||||
@ -1732,32 +1790,46 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul
|
|||||||
$title = $price_expression->title;
|
$title = $price_expression->title;
|
||||||
print '<td class="right"></td>';
|
print '<td class="right"></td>';
|
||||||
print '<td class="right"></td>';
|
print '<td class="right"></td>';
|
||||||
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
|
print '<td class="right"></td>';
|
||||||
|
}
|
||||||
print '<td class="right">'.$title."</td>";
|
print '<td class="right">'.$title."</td>";
|
||||||
} else {
|
} else {
|
||||||
|
// Price HT
|
||||||
print '<td class="right">';
|
print '<td class="right">';
|
||||||
if (empty($objp->price_by_qty)) {
|
if (empty($objp->price_by_qty)) {
|
||||||
print price($objp->price);
|
print price($objp->price);
|
||||||
}
|
}
|
||||||
print "</td>";
|
print "</td>";
|
||||||
|
// Price TTC
|
||||||
print '<td class="right">';
|
print '<td class="right">';
|
||||||
if (empty($objp->price_by_qty)) {
|
if (empty($objp->price_by_qty)) {
|
||||||
print price($objp->price_ttc);
|
$price_ttc = $objp->price_ttc;
|
||||||
|
print price($price_ttc);
|
||||||
}
|
}
|
||||||
print "</td>";
|
print "</td>";
|
||||||
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
|
print '<td class="right">';
|
||||||
|
print $resultarray[2];
|
||||||
|
print '</td>';
|
||||||
|
}
|
||||||
if (!empty($conf->dynamicprices->enabled)) { //Only if module is enabled
|
if (!empty($conf->dynamicprices->enabled)) { //Only if module is enabled
|
||||||
print '<td class="right"></td>';
|
print '<td class="right"></td>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Price min
|
||||||
print '<td class="right">';
|
print '<td class="right">';
|
||||||
if (empty($objp->price_by_qty)) {
|
if (empty($objp->price_by_qty)) {
|
||||||
print price($objp->price_min);
|
print price($objp->price_min);
|
||||||
}
|
}
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
|
||||||
|
// Price min inc tax
|
||||||
print '<td class="right">';
|
print '<td class="right">';
|
||||||
if (empty($objp->price_by_qty)) {
|
if (empty($objp->price_by_qty)) {
|
||||||
print price($objp->price_min_ttc);
|
$price_min_ttc = $objp->price_min_ttc;
|
||||||
|
print price($price_min_ttc);
|
||||||
}
|
}
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
|
||||||
@ -2042,11 +2114,9 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
|||||||
print '<td class="center">'.$langs->trans("PriceBase").'</td>';
|
print '<td class="center">'.$langs->trans("PriceBase").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("DefaultTaxRate").'</td>';
|
print '<td class="right">'.$langs->trans("DefaultTaxRate").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("HT").'</td>';
|
print '<td class="right">'.$langs->trans("HT").'</td>';
|
||||||
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
|
||||||
//print '<td class="right">' . $langs->trans("INCVATONLY") . '</td>';
|
|
||||||
print '<td class="right">'.$langs->trans("INCT").'</td>';
|
|
||||||
} else {
|
|
||||||
print '<td class="right">'.$langs->trans("TTC").'</td>';
|
print '<td class="right">'.$langs->trans("TTC").'</td>';
|
||||||
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
|
print '<td class="right">'.$langs->trans("INCT").'</td>';
|
||||||
}
|
}
|
||||||
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("HT").'</td>';
|
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("HT").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("TTC").'</td>';
|
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("TTC").'</td>';
|
||||||
@ -2107,11 +2177,9 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
|||||||
print "</td>";
|
print "</td>";
|
||||||
print '<td class="right">'.price($line->price)."</td>";
|
print '<td class="right">'.price($line->price)."</td>";
|
||||||
|
|
||||||
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
|
||||||
//print '<td class="right">' . price($line->price_ttc) . "</td>";
|
|
||||||
print '<td class="right">'.price($resultarray[2]).'</td>';
|
|
||||||
} else {
|
|
||||||
print '<td class="right">'.price($line->price_ttc)."</td>";
|
print '<td class="right">'.price($line->price_ttc)."</td>";
|
||||||
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
|
print '<td class="right">'.price($resultarray[2]).'</td>';
|
||||||
}
|
}
|
||||||
|
|
||||||
print '<td class="right">'.price($line->price_min).'</td>';
|
print '<td class="right">'.price($line->price_min).'</td>';
|
||||||
@ -2154,12 +2222,15 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
|||||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||||
print '<input type="hidden" name="id" value="'.$object->id.'">';
|
print '<input type="hidden" name="id" value="'.$object->id.'">';
|
||||||
|
|
||||||
print '<div class="div-table-responsive-no-min">';
|
print '<!-- List of prices per customer -->'."\n";
|
||||||
print '<table class="liste centpercent">';
|
print '<div class="div-table-responsive-no-min">'."\n";
|
||||||
|
print '<table class="liste centpercent">'."\n";
|
||||||
|
|
||||||
if (count($prodcustprice->lines) > 0 || $search_soc) {
|
if (count($prodcustprice->lines) > 0 || $search_soc) {
|
||||||
$colspan = 9;
|
$colspan = 9;
|
||||||
//if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") $colspan++;
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
|
$colspan++;
|
||||||
|
}
|
||||||
|
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
print '<td class="liste_titre"><input type="text" class="flat" name="search_soc" value="'.$search_soc.'" size="20"></td>';
|
print '<td class="liste_titre"><input type="text" class="flat" name="search_soc" value="'.$search_soc.'" size="20"></td>';
|
||||||
@ -2179,13 +2250,10 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
|||||||
print '<td class="center">'.$langs->trans("PriceBase").'</td>';
|
print '<td class="center">'.$langs->trans("PriceBase").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("DefaultTaxRate").'</td>';
|
print '<td class="right">'.$langs->trans("DefaultTaxRate").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("HT").'</td>';
|
print '<td class="right">'.$langs->trans("HT").'</td>';
|
||||||
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
|
||||||
//print '<td class="right">' . $langs->trans("INCVATONLY") . '</td>';
|
|
||||||
print '<td class="right">'.$langs->trans("INCT").'</td>';
|
|
||||||
} else {
|
|
||||||
print '<td class="right">'.$langs->trans("TTC").'</td>';
|
print '<td class="right">'.$langs->trans("TTC").'</td>';
|
||||||
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
|
print '<td class="right">'.$langs->trans("INCT").'</td>';
|
||||||
}
|
}
|
||||||
|
|
||||||
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("HT").'</td>';
|
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("HT").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("TTC").'</td>';
|
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("TTC").'</td>';
|
||||||
print '<td class="right">'.$langs->trans("ChangedBy").'</td>';
|
print '<td class="right">'.$langs->trans("ChangedBy").'</td>';
|
||||||
@ -2199,7 +2267,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
|||||||
$pu = $object->price_ttc;
|
$pu = $object->price_ttc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local tax is not saved into table of product. We use value linked to VAT code.
|
// Local tax was not saved into table llx_product on old version. So we will use value linked to VAT code.
|
||||||
$localtaxarray = getLocalTaxesFromRate($object->tva_tx.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), 0, $mysoc, $mysoc);
|
$localtaxarray = getLocalTaxesFromRate($object->tva_tx.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), 0, $mysoc, $mysoc);
|
||||||
// Define part of HT, VAT, TTC
|
// Define part of HT, VAT, TTC
|
||||||
$resultarray = calcul_price_total(1, $pu, 0, $object->tva_tx, 1, 1, 0, $object->price_base_type, $object->recuperableonly, $object->type, $mysoc, $localtaxarray);
|
$resultarray = calcul_price_total(1, $pu, 0, $object->tva_tx, 1, 1, 0, $object->price_base_type, $object->recuperableonly, $object->type, $mysoc, $localtaxarray);
|
||||||
@ -2237,14 +2305,12 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
|||||||
|
|
||||||
print '<td class="right">'.price($object->price)."</td>";
|
print '<td class="right">'.price($object->price)."</td>";
|
||||||
|
|
||||||
|
print '<td class="right">'.price($object->price_ttc)."</td>";
|
||||||
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
//print '<td class="right">' . price($object->price_ttc) . "</td>";
|
//print '<td class="right">' . price($object->price_ttc) . "</td>";
|
||||||
print '<td class="right">'.price($resultarray[2]).'</td>';
|
print '<td class="right">'.price($resultarray[2]).'</td>';
|
||||||
} else {
|
|
||||||
print '<td class="right">'.price($object->price_ttc)."</td>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
print '<td class="right">'.price($object->price_min).'</td>';
|
print '<td class="right">'.price($object->price_min).'</td>';
|
||||||
print '<td class="right">'.price($object->price_min_ttc).'</td>';
|
print '<td class="right">'.price($object->price_min_ttc).'</td>';
|
||||||
print '<td class="right">';
|
print '<td class="right">';
|
||||||
@ -2315,11 +2381,10 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
|||||||
print "</td>";
|
print "</td>";
|
||||||
print '<td class="right">'.price($line->price)."</td>";
|
print '<td class="right">'.price($line->price)."</td>";
|
||||||
|
|
||||||
|
print '<td class="right">'.price($line->price_ttc)."</td>";
|
||||||
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") {
|
||||||
//print '<td class="right">' . price($line->price_ttc) . "</td>";
|
//print '<td class="right">' . price($line->price_ttc) . "</td>";
|
||||||
print '<td class="right">'.price($resultarray[2]).'</td>';
|
print '<td class="right">'.price($resultarray[2]).'</td>';
|
||||||
} else {
|
|
||||||
print '<td class="right">'.price($line->price_ttc)."</td>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print '<td class="right">'.price($line->price_min).'</td>';
|
print '<td class="right">'.price($line->price_min).'</td>';
|
||||||
|
|||||||
@ -918,6 +918,7 @@ class Task extends CommonObjectLine
|
|||||||
// Add where from extra fields
|
// Add where from extra fields
|
||||||
$extrafieldsobjectkey = 'projet_task';
|
$extrafieldsobjectkey = 'projet_task';
|
||||||
$extrafieldsobjectprefix = 'efpt.';
|
$extrafieldsobjectprefix = 'efpt.';
|
||||||
|
global $db; // needed for extrafields_list_search_sql.tpl
|
||||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
|
||||||
// Add where from hooks
|
// Add where from hooks
|
||||||
$parameters = array();
|
$parameters = array();
|
||||||
@ -1182,6 +1183,7 @@ class Task extends CommonObjectLine
|
|||||||
dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG);
|
dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG);
|
||||||
|
|
||||||
$ret = 0;
|
$ret = 0;
|
||||||
|
$now = dol_now();
|
||||||
|
|
||||||
// Check parameters
|
// Check parameters
|
||||||
if (!is_object($user)) {
|
if (!is_object($user)) {
|
||||||
@ -1219,6 +1221,7 @@ class Task extends CommonObjectLine
|
|||||||
$sql .= ", task_duration";
|
$sql .= ", task_duration";
|
||||||
$sql .= ", fk_user";
|
$sql .= ", fk_user";
|
||||||
$sql .= ", note";
|
$sql .= ", note";
|
||||||
|
$sql .= ", datec";
|
||||||
$sql .= ") VALUES (";
|
$sql .= ") VALUES (";
|
||||||
$sql .= ((int) $this->id);
|
$sql .= ((int) $this->id);
|
||||||
$sql .= ", '".$this->db->idate($this->timespent_date)."'";
|
$sql .= ", '".$this->db->idate($this->timespent_date)."'";
|
||||||
@ -1227,6 +1230,7 @@ class Task extends CommonObjectLine
|
|||||||
$sql .= ", ".((int) $this->timespent_duration);
|
$sql .= ", ".((int) $this->timespent_duration);
|
||||||
$sql .= ", ".((int) $this->timespent_fk_user);
|
$sql .= ", ".((int) $this->timespent_fk_user);
|
||||||
$sql .= ", ".(isset($this->timespent_note) ? "'".$this->db->escape($this->timespent_note)."'" : "null");
|
$sql .= ", ".(isset($this->timespent_note) ? "'".$this->db->escape($this->timespent_note)."'" : "null");
|
||||||
|
$sql .= ", '".$this->db->idate($now)."'";
|
||||||
$sql .= ")";
|
$sql .= ")";
|
||||||
|
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
|
|||||||
@ -210,6 +210,8 @@ if (empty($reshook)) {
|
|||||||
$ret = $object->fetch($id); // Reload to get new records
|
$ret = $object->fetch($id); // Reload to get new records
|
||||||
$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setEventMessages($object->error, $object->errors, 'errors');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,8 +352,10 @@ if (empty($reshook)) {
|
|||||||
}
|
}
|
||||||
$qty = "qtyl".$i;
|
$qty = "qtyl".$i;
|
||||||
$comment = "comment".$i;
|
$comment = "comment".$i;
|
||||||
$eatby = "dlc".$i;
|
// EATBY <-> DLUO see productbatch.class.php
|
||||||
$sellby = "dluo".$i;
|
// SELLBY <-> DLC
|
||||||
|
$eatby = "dluo".$i;
|
||||||
|
$sellby = "dlc".$i;
|
||||||
$batch = "batch".$i;
|
$batch = "batch".$i;
|
||||||
$cost_price = "cost_price".$i;
|
$cost_price = "cost_price".$i;
|
||||||
|
|
||||||
@ -626,9 +630,11 @@ if (empty($reshook)) {
|
|||||||
$batch = "batch".$line_id;
|
$batch = "batch".$line_id;
|
||||||
$dlc = "dlc".$line_id;
|
$dlc = "dlc".$line_id;
|
||||||
$dluo = "dluo".$line_id;
|
$dluo = "dluo".$line_id;
|
||||||
$eatby = GETPOST($dlc, 'alpha');
|
// EATBY <-> DLUO
|
||||||
|
$eatby = GETPOST($dluo, 'alpha');
|
||||||
$eatbydate = str_replace('/', '-', $eatby);
|
$eatbydate = str_replace('/', '-', $eatby);
|
||||||
$sellby = GETPOST($dluo, 'alpha');
|
// SELLBY <-> DLC
|
||||||
|
$sellby = GETPOST($dlc, 'alpha');
|
||||||
$sellbydate = str_replace('/', '-', $sellby);
|
$sellbydate = str_replace('/', '-', $sellby);
|
||||||
$line->batch = GETPOST($batch, 'alpha');
|
$line->batch = GETPOST($batch, 'alpha');
|
||||||
$line->eatby = strtotime($eatbydate);
|
$line->eatby = strtotime($eatbydate);
|
||||||
@ -639,8 +645,7 @@ if (empty($reshook)) {
|
|||||||
setEventMessages($line->error, $line->errors, 'errors');
|
setEventMessages($line->error, $line->errors, 'errors');
|
||||||
$error++;
|
$error++;
|
||||||
}
|
}
|
||||||
} else // Product no predefined
|
} else { // Product no predefined
|
||||||
{
|
|
||||||
$qty = "qtyl".$line_id;
|
$qty = "qtyl".$line_id;
|
||||||
$line->id = $line_id;
|
$line->id = $line_id;
|
||||||
$line->qty = GETPOST($qty, 'int');
|
$line->qty = GETPOST($qty, 'int');
|
||||||
|
|||||||
@ -554,7 +554,7 @@ if ($action == 'create') {
|
|||||||
print '<tr><td>';
|
print '<tr><td>';
|
||||||
print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1).'</td><td>';
|
print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1).'</td><td>';
|
||||||
print '<input name="amount" id="amount" class="minwidth75 maxwidth100" value="'.GETPOST("amount").'"> ';
|
print '<input name="amount" id="amount" class="minwidth75 maxwidth100" value="'.GETPOST("amount").'"> ';
|
||||||
print '<button class="dpInvisibleButtons" id="updateAmountWithLastSalary" name="_useless" type="button">'.$langs->trans('UpdateAmountWithLastSalary').'</a>';
|
print '<button class="dpInvisibleButtons datenow" id="updateAmountWithLastSalary" name="_useless" type="button">'.$langs->trans('UpdateAmountWithLastSalary').'</a>';
|
||||||
print '</td>';
|
print '</td>';
|
||||||
print '</tr>';
|
print '</tr>';
|
||||||
|
|
||||||
|
|||||||
@ -234,7 +234,7 @@ $sql .= " ".MAIN_DB_PREFIX."user as u";
|
|||||||
$sql .= " WHERE u.rowid = sal.fk_user";
|
$sql .= " WHERE u.rowid = sal.fk_user";
|
||||||
$sql .= " AND s.entity IN (".getEntity('payment_salaries').")";
|
$sql .= " AND s.entity IN (".getEntity('payment_salaries').")";
|
||||||
if (empty($user->rights->salaries->readall)) {
|
if (empty($user->rights->salaries->readall)) {
|
||||||
$sql .= " AND s.fk_user IN (".$db->sanitize(join(',', $childids)).")";
|
$sql .= " AND sal.fk_user IN (".$db->sanitize(join(',', $childids)).")";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search criteria
|
// Search criteria
|
||||||
|
|||||||
@ -74,6 +74,10 @@ dol_mkdir($dir);
|
|||||||
|
|
||||||
$useridtofilter = $userid; // Filter from parameters
|
$useridtofilter = $userid; // Filter from parameters
|
||||||
|
|
||||||
|
if (empty($user->rights->salaries->readall) && empty($useridtofilter)) {
|
||||||
|
$useridtofilter = $user->getAllChildIds(1);
|
||||||
|
}
|
||||||
|
|
||||||
$stats = new SalariesStats($db, $socid, $useridtofilter);
|
$stats = new SalariesStats($db, $socid, $useridtofilter);
|
||||||
|
|
||||||
|
|
||||||
@ -204,7 +208,7 @@ print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->tra
|
|||||||
// User
|
// User
|
||||||
print '<tr><td>'.$langs->trans("Employee").'</td><td>';
|
print '<tr><td>'.$langs->trans("Employee").'</td><td>';
|
||||||
print img_picto('', 'user', 'class="pictofixedwidth"');
|
print img_picto('', 'user', 'class="pictofixedwidth"');
|
||||||
print $form->select_dolusers(($userid ? $userid : -1), 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
|
print $form->select_dolusers(($userid ? $userid : -1), 'userid', 1, '', 0, empty($user->rights->salaries->readall) ? 'hierarchyme' : '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
// Year
|
// Year
|
||||||
print '<tr><td>'.$langs->trans("Year").'</td><td>';
|
print '<tr><td>'.$langs->trans("Year").'</td><td>';
|
||||||
|
|||||||
@ -786,7 +786,7 @@ class Website extends CommonObject
|
|||||||
|
|
||||||
// Re-generates the index.php page to be the home page, and re-generates the wrapper.php
|
// Re-generates the index.php page to be the home page, and re-generates the wrapper.php
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
$result = dolSaveIndexPage($pathofwebsitenew, $fileindex, $filetpl, $filewrapper);
|
$result = dolSaveIndexPage($pathofwebsitenew, $fileindex, $filetpl, $filewrapper, $object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,7 +1275,7 @@ class Website extends CommonObject
|
|||||||
|
|
||||||
// Regenerate index page to point to the new index page
|
// Regenerate index page to point to the new index page
|
||||||
$pathofwebsite = $conf->website->dir_output.'/'.$object->ref;
|
$pathofwebsite = $conf->website->dir_output.'/'.$object->ref;
|
||||||
dolSaveIndexPage($pathofwebsite, $pathofwebsite.'/index.php', $pathofwebsite.'/page'.$object->fk_default_home.'.tpl.php', $pathofwebsite.'/wrapper.php');
|
dolSaveIndexPage($pathofwebsite, $pathofwebsite.'/index.php', $pathofwebsite.'/page'.$object->fk_default_home.'.tpl.php', $pathofwebsite.'/wrapper.php', $object);
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
$this->db->rollback();
|
$this->db->rollback();
|
||||||
@ -1287,7 +1287,7 @@ class Website extends CommonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuild all files of a containers of a website. Rebuild also the wrapper.php file. TODO Add other files too.
|
* Rebuild all files of all the pages/containers of a website. Rebuild also the index and wrapper.php file.
|
||||||
* Note: Files are already regenerated during importWebSite so this function is useless when importing a website.
|
* Note: Files are already regenerated during importWebSite so this function is useless when importing a website.
|
||||||
*
|
*
|
||||||
* @return int <0 if KO, >=0 if OK
|
* @return int <0 if KO, >=0 if OK
|
||||||
@ -1339,12 +1339,12 @@ class Website extends CommonObject
|
|||||||
$aliasesarray[] = $objectpagestatic->pageurl;
|
$aliasesarray[] = $objectpagestatic->pageurl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regenerate all aliases pages (pages with a natural name)
|
// Regenerate also all aliases pages (pages with a natural name) by calling dolSavePageAlias()
|
||||||
if (is_array($aliasesarray)) {
|
if (is_array($aliasesarray)) {
|
||||||
foreach ($aliasesarray as $aliasshortcuttocreate) {
|
foreach ($aliasesarray as $aliasshortcuttocreate) {
|
||||||
if (trim($aliasshortcuttocreate)) {
|
if (trim($aliasshortcuttocreate)) {
|
||||||
$filealias = $conf->website->dir_output.'/'.$object->ref.'/'.trim($aliasshortcuttocreate).'.php';
|
$filealias = $conf->website->dir_output.'/'.$object->ref.'/'.trim($aliasshortcuttocreate).'.php';
|
||||||
$result = dolSavePageAlias($filealias, $object, $objectpagestatic);
|
$result = dolSavePageAlias($filealias, $object, $objectpagestatic); // This includes also a copy into sublanguage directories.
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
$this->errors[] = 'Failed to write file '.basename($filealias);
|
$this->errors[] = 'Failed to write file '.basename($filealias);
|
||||||
$error++;
|
$error++;
|
||||||
@ -1357,10 +1357,15 @@ class Website extends CommonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$error) {
|
if (!$error) {
|
||||||
// Save wrapper.php
|
// Save index.php and wrapper.php
|
||||||
$pathofwebsite = $conf->website->dir_output.'/'.$object->ref;
|
$pathofwebsite = $conf->website->dir_output.'/'.$object->ref;
|
||||||
|
$fileindex = $pathofwebsite.'/index.php';
|
||||||
|
$filetpl = '';
|
||||||
|
if ($object->fk_default_home > 0) {
|
||||||
|
$filetpl = $pathofwebsite.'/page'.$object->fk_default_home.'.tpl.php';
|
||||||
|
}
|
||||||
$filewrapper = $pathofwebsite.'/wrapper.php';
|
$filewrapper = $pathofwebsite.'/wrapper.php';
|
||||||
dolSaveIndexPage($pathofwebsite, '', '', $filewrapper);
|
dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object); // This includes also a version of index.php into sublanguage directories
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
|
|||||||
@ -1087,7 +1087,7 @@ if ($action == 'addcontainer' && $usercanedit) {
|
|||||||
$filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
|
$filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
|
||||||
|
|
||||||
// Generate the index.php page (to be the home page) and the wrapper.php file
|
// Generate the index.php page (to be the home page) and the wrapper.php file
|
||||||
$result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper);
|
$result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object);
|
||||||
|
|
||||||
if ($result <= 0) {
|
if ($result <= 0) {
|
||||||
setEventMessages('Failed to write file '.$fileindex, null, 'errors');
|
setEventMessages('Failed to write file '.$fileindex, null, 'errors');
|
||||||
@ -1580,7 +1580,7 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
|
|
||||||
|
|
||||||
// Save wrapper.php
|
// Save wrapper.php
|
||||||
$result = dolSaveIndexPage($pathofwebsite, '', '', $filewrapper);
|
$result = dolSaveIndexPage($pathofwebsite, '', '', $filewrapper, $object);
|
||||||
|
|
||||||
|
|
||||||
// Message if no error
|
// Message if no error
|
||||||
@ -1621,7 +1621,7 @@ if ($action == 'setashome' && $usercanedit) {
|
|||||||
$filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
|
$filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
|
||||||
|
|
||||||
// Generate the index.php page to be the home page
|
// Generate the index.php page to be the home page
|
||||||
$result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper);
|
$result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object);
|
||||||
|
|
||||||
if ($result) {
|
if ($result) {
|
||||||
setEventMessages($langs->trans("Saved"), null, 'mesgs');
|
setEventMessages($langs->trans("Saved"), null, 'mesgs');
|
||||||
@ -2181,7 +2181,7 @@ if ($action == 'regeneratesite' && $usercanedit) {
|
|||||||
$pathtomediasinwebsite = $pathofwebsite.'/medias';
|
$pathtomediasinwebsite = $pathofwebsite.'/medias';
|
||||||
if (!is_link(dol_osencode($pathtomediasinwebsite))) {
|
if (!is_link(dol_osencode($pathtomediasinwebsite))) {
|
||||||
dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
|
dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
|
||||||
dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists
|
dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure that the directory for website exists
|
||||||
$result = symlink($pathtomedias, $pathtomediasinwebsite);
|
$result = symlink($pathtomedias, $pathtomediasinwebsite);
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
setEventMessages($langs->trans("ErrorFieldToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
|
setEventMessages($langs->trans("ErrorFieldToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
|
||||||
|
|||||||
@ -584,34 +584,6 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* testCheckLoginPassEntity
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function testCheckLoginPassEntity()
|
|
||||||
{
|
|
||||||
$login=checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr'));
|
|
||||||
print __METHOD__." login=".$login."\n";
|
|
||||||
$this->assertEquals($login, '');
|
|
||||||
|
|
||||||
$login=checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr'));
|
|
||||||
print __METHOD__." login=".$login."\n";
|
|
||||||
$this->assertEquals($login, '');
|
|
||||||
|
|
||||||
$login=checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists
|
|
||||||
print __METHOD__." login=".$login."\n";
|
|
||||||
$this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed');
|
|
||||||
|
|
||||||
$login=checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method
|
|
||||||
print __METHOD__." login=".$login."\n";
|
|
||||||
$this->assertEquals($login, 'admin');
|
|
||||||
|
|
||||||
$login=checkLoginPassEntity('admin', 'admin', 1, array('forceuser'));
|
|
||||||
print __METHOD__." login=".$login."\n";
|
|
||||||
$this->assertEquals($login, ''); // Expected '' because should failed because login 'auto' does not exists
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testEncodeDecode
|
* testEncodeDecode
|
||||||
*
|
*
|
||||||
@ -919,6 +891,11 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
|||||||
print "result = ".$result."\n";
|
print "result = ".$result."\n";
|
||||||
$this->assertContains('Bad string syntax to evaluate', $result);
|
$this->assertContains('Bad string syntax to evaluate', $result);
|
||||||
|
|
||||||
|
$result=dol_eval("90402.38+267678+0", 1, 1, 1);
|
||||||
|
print "result = ".$result."\n";
|
||||||
|
$this->assertEquals('358080.38', $result);
|
||||||
|
|
||||||
|
|
||||||
global $leftmenu;
|
global $leftmenu;
|
||||||
$leftmenu = 'admintools';
|
$leftmenu = 'admintools';
|
||||||
$result=dol_eval('$conf->currency && preg_match(\'/^(admintools|all)/\',$leftmenu)', 1, 0, '2');
|
$result=dol_eval('$conf->currency && preg_match(\'/^(admintools|all)/\',$leftmenu)', 1, 0, '2');
|
||||||
@ -936,4 +913,33 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
|||||||
print "result = ".$result."\n";
|
print "result = ".$result."\n";
|
||||||
$this->assertContains('Bad string syntax to evaluate', $result);
|
$this->assertContains('Bad string syntax to evaluate', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testCheckLoginPassEntity
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCheckLoginPassEntity()
|
||||||
|
{
|
||||||
|
$login=checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr'));
|
||||||
|
print __METHOD__." login=".$login."\n";
|
||||||
|
$this->assertEquals($login, '');
|
||||||
|
|
||||||
|
$login=checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr'));
|
||||||
|
print __METHOD__." login=".$login."\n";
|
||||||
|
$this->assertEquals($login, '');
|
||||||
|
|
||||||
|
$login=checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists
|
||||||
|
print __METHOD__." login=".$login."\n";
|
||||||
|
$this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed');
|
||||||
|
|
||||||
|
$login=checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method
|
||||||
|
print __METHOD__." login=".$login."\n";
|
||||||
|
$this->assertEquals($login, 'admin');
|
||||||
|
|
||||||
|
$login=checkLoginPassEntity('admin', 'admin', 1, array('forceuser'));
|
||||||
|
print __METHOD__." login=".$login."\n";
|
||||||
|
$this->assertEquals($login, ''); // Expected '' because should failed because login 'auto' does not exists
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user