Merge branch 'develop' of github.com:Dolibarr/dolibarr into develop_new_dashboard

This commit is contained in:
John Botella 2019-08-06 09:57:49 +02:00
commit bc0508164b
18 changed files with 209 additions and 33 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -1016,14 +1016,13 @@ class AccountancyExport
* Export format : Charlemagne
*
* @param array $objectLines data
*
* @return void
*/
public function exportCharlemagne($objectLines)
public function exportCharlemagne($objectLines)
{
global $langs;
$langs->load('compta');
$separator = "\t";
$end_line = "\n";
@ -1045,9 +1044,9 @@ class AccountancyExport
print self::trunc($langs->transnoentitiesnoconv('Analytic') . ' 3', 15) . $separator;
print self::trunc($langs->transnoentitiesnoconv('AnalyticLabel') . ' 3', 60) . $separator;
print $end_line;
foreach($objectLines as $line) {
$date = dol_print_date($line->doc_date, '%Y%m%d');
print $date . $separator; //Date
@ -1069,7 +1068,6 @@ class AccountancyExport
print $separator;//Analytic
print $separator;//Analytic
print $end_line;
}
}

View File

@ -17,7 +17,7 @@
/**
* \file /htdocs/core/ajax/extraparams.php
* \brief File to return Ajax response on set extra parameters of elements
* \brief File to make Ajax action on setting extra parameters of elements
*/
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Disables token renewal

View File

@ -15,8 +15,9 @@
*/
/**
* \file htdocs/core/ajax/productonoff.php
* \brief File to set tosell and tobuy for product
* \file htdocs/core/ajax/objectonoff.php
* \brief File to set status for an object
* This Ajax service is called when option MAIN_DIRECT_STATUS_UPDATE is set.
*/
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Disables token renewal
@ -36,6 +37,13 @@ $field=GETPOST('field', 'alpha');
$element=GETPOST('element', 'alpha');
$object = new GenericObject($db);
// Security check
if (! empty($user->societe_id))
$socid = $user->societe_id;
/*
* View
*/
@ -44,6 +52,20 @@ top_httphead();
print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
if ($element == 'societe' && in_array($field, array('status')))
{
$result = restrictedArea($user, 'societe', $id);
}
elseif ($element == 'product' && in_array($field, array('tosell', 'tobuy', 'tobatch')))
{
$result = restrictedArea($user, 'produit|service', $id, 'product&product', '', '', 'rowid');
}
else
{
accessforbidden("Bad value for combination of parameters element/field.", 0, 0, 1);
exit;
}
// Registering new values
if (($action == 'set') && ! empty($id))
$object->setValueFrom($field, $value, $element, $id);

View File

@ -0,0 +1,72 @@
<?php
/* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/core/ajax/pingresult.php
* \brief File to save result of anonymous ping
* Example: captureserver/public/index.php?action=dolibarrping
*/
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Disables token renewal
if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1');
if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1');
if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1');
if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1');
if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1');
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
$action=GETPOST('action', 'alpha');
$hash_unique_id=GETPOST('hash_unique_id', 'alpha');
$hash_algo=GETPOST('hash', 'alpha');
// Security check
if (! empty($user->societe_id))
$socid = $user->societe_id;
$now = dol_now();
/*
* View
*/
top_httphead();
print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
// If ok
if ($action == 'firstpingok')
{
// Note: pings are by entities
dolibarr_set_const($db, 'MAIN_FIRST_PING_OK_DATE', dol_print_date($now, 'dayhourlog', 'gmt'));
dolibarr_set_const($db, 'MAIN_FIRST_PING_OK_ID', $hash_unique_id);
print 'First ping OK saved for entity '.$conf->entity;
}
// If ko
elseif ($action == 'firstpingko')
{
// Note: pings are by entities
dolibarr_set_const($db, 'MAIN_LAST_PING_KO_DATE', dol_print_date($now, 'dayhourlog'), 'gmt');
print 'First ping KO saved for entity '.$conf->entity;
}
else {
print 'Error action='.$action.' not supported';
}

View File

@ -17,7 +17,7 @@
/**
* \file htdocs/core/ajax/security.php
* \brief This ajax component is used to generated has keys for security purposes
* \brief This ajax component is used to generated hash keys for security purposes
* like key to use into URL to protect them.
*/

View File

@ -2053,7 +2053,8 @@ abstract class CommonObject
return -2;
}
}
/**
* Change the retained warranty payments terms
*
@ -2066,11 +2067,11 @@ abstract class CommonObject
if ($this->statut >= 0 || $this->element == 'societe')
{
$fieldname = 'retained_warranty_fk_cond_reglement';
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
$sql .= ' SET '.$fieldname.' = '.$id;
$sql .= ' WHERE rowid='.$this->id;
if ($this->db->query($sql))
{
$this->retained_warranty_fk_cond_reglement = $id;
@ -5064,7 +5065,7 @@ abstract class CommonObject
//dol_syslog("attributeLabel=".$attributeLabel, LOG_DEBUG);
//dol_syslog("attributeType=".$attributeType, LOG_DEBUG);
if (!empty($attrfieldcomputed))
{
if (!empty($conf->global->MAIN_STORE_COMPUTED_EXTRAFIELDS))
@ -6111,7 +6112,7 @@ abstract class CommonObject
{
$morecss = 'minwidth100imp';
}
elseif ($type == 'datetime')
elseif ($type == 'datetime' || $type == 'timestamp')
{
$morecss = 'minwidth200imp';
}
@ -6155,7 +6156,7 @@ abstract class CommonObject
$value='';
}
}
elseif ($type == 'datetime')
elseif ($type == 'datetime' || $type == 'timestamp')
{
if(! empty($value)) {
$value=dol_print_date($value, 'dayhour');
@ -7390,6 +7391,7 @@ abstract class CommonObject
if (!empty($id)) $sql.= ' WHERE rowid = '.$id;
elseif (!empty($ref)) $sql.= " WHERE ref = ".$this->quote($ref, $this->fields['ref']);
else $sql.=' WHERE 1 = 1'; // usage with empty id and empty ref is very rare
if (empty($id) && isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.=' AND entity IN ('.getEntity($this->table_element).')';
if ($morewhere) $sql.= $morewhere;
$sql.=' LIMIT 1'; // This is a fetch, to be sure to get only one record

View File

@ -17,7 +17,7 @@
*/
/**
* \file htdocs/core/ajax/fileupload.php
* \file htdocs/core/ajax/fileupload.class.php
* \brief File to return Ajax response on file upload
*/

View File

@ -538,11 +538,12 @@ function ajax_constantonoff($code, $input = array(), $entity = null, $revertonof
}
/**
* On/off button for object
* On/off button to change status of an object
* This is called when MAIN_DIRECT_STATUS_UPDATE is set and it use tha ajax service objectonoff.php
*
* @param Object $object Object to set
* @param string $code Name of constant : status or status_buy for product by example
* @param string $field Name of database field : tosell or tobuy for product by example
* @param string $field Name of database field : 'tosell' or 'tobuy' for product by example
* @param string $text_on Text if on
* @param string $text_off Text if off
* @param array $input Array of type->list of CSS element to switch. Example: array('disabled'=>array(0=>'cssid'))

View File

@ -279,7 +279,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
// Check write permission from module (we need to know write permission to create but also to delete drafts record)
$createok=1; $nbko=0;
if (GETPOST('action', 'aZ09') == 'create' || ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete'))
if (GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update' || ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete'))
{
foreach ($featuresarray as $feature)
{
@ -329,7 +329,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
// If a or and at least one ok
if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $createok=1;
if (GETPOST('action', 'aZ09') == 'create' && ! $createok) accessforbidden();
if ((GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update') && ! $createok) accessforbidden();
//print "Write access is ok";
}

View File

@ -996,6 +996,34 @@ if (empty($reshook))
}
}
if ($action == 'set_unpaid' && $id > 0 && $user->rights->expensereport->to_paid)
{
$object = new ExpenseReport($db);
$object->fetch($id);
$result = $object->set_unpaid($user);
if ($result > 0)
{
// Define output language
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
{
$outputlangs = $langs;
$newlang = '';
if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
if (! empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
}
$model=$object->modelpdf;
$ret = $object->fetch($id); // Reload to get new records
$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
}
}
}
if ($action == 'set_paid' && $id > 0 && $user->rights->expensereport->to_paid)
{
$object = new ExpenseReport($db);
@ -1679,7 +1707,7 @@ else
if ($action == 'cancel')
{
$array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text",'label'=>'<strong>'.$langs->trans("Comment").'</strong>','name'=>"detail_cancel",'size'=>"50",'value'=>""));
$array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text",'label'=>'<strong>'.$langs->trans("Comment").'</strong>','name'=>"detail_cancel",'value'=>""));
$formconfirm=$form->formconfirm($_SEVER["PHP_SELF"]."?id=".$id, $langs->trans("Cancel"), "", "confirm_cancel", $array_input, "", 1);
}
@ -1690,7 +1718,7 @@ else
if ($action == 'refuse') // Deny
{
$array_input = array('text'=>$langs->trans("ConfirmRefuseTrip"), array('type'=>"text",'label'=>$langs->trans("Comment"),'name'=>"detail_refuse",'size'=>"50",'value'=>""));
$array_input = array('text'=>$langs->trans("ConfirmRefuseTrip"), array('type'=>"text",'label'=>$langs->trans("Comment"),'name'=>"detail_refuse",'value'=>""));
$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("Deny"), '', "confirm_refuse", $array_input, "yes", 1);
}
@ -2662,8 +2690,8 @@ if ($action != 'create' && $action != 'edit')
}
// If status is Appoved
// --------------------
// If status is Approved
// ---------------------
if ($user->rights->expensereport->approve && $object->fk_statut == ExpenseReport::STATUS_APPROVED)
{
@ -2707,9 +2735,15 @@ if ($action != 'create' && $action != 'edit')
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans('Cancel').'</a></div>';
}
if ($user->rights->expensereport->to_paid && $object->paid && $object->fk_statut == ExpenseReport::STATUS_CLOSED)
{
// Set unpaid
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=set_unpaid&id='.$object->id.'">'.$langs->trans('ClassifyUnPaid').'</a></div>';
}
// Clone
if ($user->rights->expensereport->creer) {
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=clone">' . $langs->trans("ToClone") . '</a></div>';
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=clone">' . $langs->trans("ToClone") . '</a></div>';
}
/* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */

View File

@ -1397,12 +1397,12 @@ class ExpenseReport extends CommonObject
// phpcs:enable
$error = 0;
if ($this->fk_c_deplacement_statuts != 5)
if ($this->paid)
{
$this->db->begin();
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
$sql.= " SET fk_statut = 5";
$sql.= " SET paid = 0";
$sql.= ' WHERE rowid = '.$this->id;
dol_syslog(get_class($this)."::set_unpaid sql=".$sql, LOG_DEBUG);

View File

@ -286,7 +286,6 @@ else
dol_print_error($db);
}
print '</div>';
/*

View File

@ -95,6 +95,7 @@ PaymentHigherThanReminderToPay=Payment higher than reminder to pay
HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess received for each overpaid invoice.
HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess paid for each overpaid invoice.
ClassifyPaid=Classify 'Paid'
ClassifyUnPaid=Classify 'Unpaid'
ClassifyPaidPartially=Classify 'Paid partially'
ClassifyCanceled=Classify 'Abandoned'
ClassifyClosed=Classify 'Closed'

View File

@ -96,6 +96,7 @@ HelpPaymentHigherThanReminderToPay=Attention, le montant de paiement pour une ou
HelpPaymentHigherThanReminderToPaySupplier=Attention, le montant de paiement pour une ou plusieurs factures est supérieur au reste à payer.<br>Corrigez votre saisie, sinon, confirmez et pensez à créer un avoir pour l'excédent pour chaque facture surpayée.
ClassifyPaid=Classer 'Payée'
ClassifyPaidPartially=Classer 'Payée partiellement'
ClassifyUnPaid=Classer 'Non payée'
ClassifyCanceled=Classer 'Abandonnée'
ClassifyClosed=Classer 'Fermée'
ClassifyUnBilled=Classer 'Non facturée'

View File

@ -1124,6 +1124,7 @@ function top_httphead($contenttype = 'text/html', $forcenocache = 0)
if ($contenttype == 'text/html' ) header("Content-Type: text/html; charset=".$conf->file->character_set_client);
else header("Content-Type: ".$contenttype);
// Security options
header("X-Content-Type-Options: nosniff"); // With the nosniff option, if the server says the content is text/html, the browser will render it as text/html (note that most browsers now force this option to on)
if (! defined('XFRAMEOPTIONS_ALLOWALL')) header("X-Frame-Options: SAMEORIGIN"); // Frames allowed only if on same domain (stop some XSS attacks)
@ -2319,6 +2320,51 @@ if (! function_exists("llxFooter"))
print "\n<!-- A div to allow dialog popup -->\n";
print '<div id="dialogforpopup" style="display: none;"></div>'."\n";
// Add code for the asynchronous anonymous first ping (for telemetry)
if (($_SERVER["PHP_SELF"] == DOL_URL_ROOT.'/index.php') || GETPOST('forceping', 'alpha'))
{
if (empty($conf->global->MAIN_FIRST_PING_OK_DATE)
|| (! empty($conf->file->instance_unique_id) && (md5($conf->file->instance_unique_id) != $conf->global->MAIN_FIRST_PING_OK_ID))
|| GETPOST('forceping', 'alpha'))
{
print "\n".'<!-- Includes JS for Ping of Dolibarr MAIN_FIRST_PING_OK_DATE = '.$conf->global->MAIN_FIRST_PING_OK_DATE.' MAIN_FIRST_PING_OK_ID = '.$conf->global->MAIN_FIRST_PING_OK_ID.' -->'."\n";
print "\n<!-- JS CODE TO ENABLE the anonymous Ontime Ping -->\n";
?>
<script>
jQuery(document).ready(function (tmp) {
$.ajax({
method: "POST",
url: "https://ping.dolibarr.org/",
timeout: 500, // timeout milliseconds
cache: false,
data: { hash_algo: "md5", hash_unique_id: "<?php echo md5($conf->file->instance_unique_id); ?>", action: "dolibarrping", version: "<?php echo (float) DOL_VERSION; ?>", entity: <?php echo (int) $conf->entity; ?> },
success: function (data, status, xhr) { // success callback function (data contains body of response)
console.log("Ping ok");
$.ajax({
method: "GET",
url: "<?php echo DOL_URL_ROOT.'/core/ajax/pingresult.php'; ?>",
timeout: 500, // timeout milliseconds
cache: false,
data: { hash_algo: "md5", hash_unique_id: "<?php echo md5($conf->file->instance_unique_id); ?>", action: "firstpingok" },
});
},
error: function (data,status,xhr) { // success callback function
console.log("Ping ko: " + data);
$.ajax({
method: "GET",
url: "<?php echo DOL_URL_ROOT.'/core/ajax/pingresult.php'; ?>",
timeout: 500, // timeout milliseconds
cache: false,
data: { hash_algo: "md5", hash_unique_id: "<?php echo md5($conf->file->instance_unique_id); ?>", action: "firstpingko", version: "<?php echo (float) DOL_VERSION; ?>" },
});
}
});
});
</script>
<?php
}
}
print "</body>\n";
print "</html>\n";

View File

@ -60,7 +60,7 @@ class MyObject extends CommonObject
const STATUS_DRAFT = 0;
const STATUS_VALIDATED = 1;
const STATUS_DISABLED = 9;
const STATUS_CANCELED = 9;
/**
@ -388,7 +388,7 @@ class MyObject extends CommonObject
$sql = 'SELECT ';
$sql .= $this->getFieldList();
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t';
if ($this->ismultientitymanaged) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')';
if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')';
else $sql .= ' WHERE 1 = 1';
// Manage filter
$sqlwhere = array();

View File

@ -135,7 +135,7 @@ $arrayfields=array();
foreach($object->fields as $key => $val)
{
// If $val['visible']==0, then we never show the field
if (! empty($val['visible'])) $arrayfields['t.'.$key]=array('label'=>$val['label'], 'checked'=>(($val['visible']<0)?0:1), 'enabled'=>$val['enabled'], 'position'=>$val['position']);
if (! empty($val['visible'])) $arrayfields['t.'.$key]=array('label'=>$val['label'], 'checked'=>(($val['visible']<0)?0:1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']);
}
// Extra fields
if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0)
@ -493,7 +493,7 @@ while ($i < min($num, $limit))
if (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap';
elseif ($key == 'ref') $cssforfield.=($cssforfield?' ':'').'nowrap';
if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price'))) $cssforfield.=($cssforfield?' ':'').'right';
if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status') $cssforfield.=($cssforfield?' ':'').'right';
if (! empty($arrayfields['t.'.$key]['checked']))
{