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

This commit is contained in:
Florian HENRY 2016-02-01 15:00:09 +01:00
commit 72b0f62089
26 changed files with 230 additions and 139 deletions

View File

@ -197,6 +197,7 @@ before_script:
echo "Create documents directory and set permissions"
# and admin/temp subdirectory needed for unit tests
mkdir -p documents/admin/temp
echo "first line" > documents/dolibarr.log
echo
- |
@ -298,14 +299,15 @@ after_success:
after_failure:
- |
echo "Debugging informations"
# Upgrade log files
cat *.log
echo "Debugging informations"
# Apache log file
sudo cat /var/log/apache2/error.log
# Dolibarr log file
cat documents/dolibarr.log
if [ "$DEBUG" = true ]; then
echo "Debugging informations"
# Upgrade log files
cat *.log
# Dolibarr log file
cat documents/dolibarr.log
# Apache log file
sudo cat /var/log/apache2/error.log
# MariaDB log file
sudo cat /var/log/mysql/error.log
# TODO: PostgreSQL log file

View File

@ -14,8 +14,8 @@ with format .DEB (for Debian, Ubuntu, ...).
# To build a debian package, you need first
# With Ubuntu 12.04
# apt-get install debhelper dpkg-source gpg lintian git-buildpackage pkg-php-tools schroot sbuild dh-linktree dh-make-php
# With Debian 7
# apt-get install debhelper dpkg gnupg lintian git-buildpackage pkg-php-tools schroot sbuild dh-linktree dh-make-php
# With Ubuntu 14.04 ou Debian 7
# apt-get install debhelper dpkg gnupg lintian git-buildpackage pkg-php-tools schroot sbuild dh-linktree dh-make-php packaging-dev
# To generate gpg key for email used into changelog
@ -49,6 +49,7 @@ Other example:
export DEBFULLNAME="Laurent Destailleur"
export DEBEMAIL="eldy@destailleur.fr"
export QUILT_PATCHES=debian/patches
# To use Alioth.debian.org
* Create an account login
@ -212,7 +213,9 @@ Warning: Name and email must match value into debian/control file (Entry added h
* We try to build package
> rm -fr ../build-area;
> git-buildpackage -us -uc --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-3.5.x]
> git-buildpackage -us -uc --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-x.y.z]
ou
> git-buildpackage -us -uc --git-ignore-branch --git-upstream-branch=[upstream|upstream-x.y.z]
Note: To build an old version, do: git checkout oldtagname -b newbranchname; git-buildpackage -us -uc --git-debian-branch=newbranchname --git-upstream-branch=[upstream|upstream-3.5.x]
Note: You can use git-buildpackage -us -uc --git-ignore-new if you want to test build with uncommited file
@ -220,6 +223,7 @@ Note: You can use git-buildpackage -us -uc -d if you want to test
Note: Package is built into directory ../build-area
Note: To compare 2 packages: debdiff package1.dsc package2.dsc
* Test package (see dedicated chapter to test it with debian unstable env)
* If package .deb is ok:
Note: If there was errors managed manually, you may need to make a git commit but do not use option "amend" previous commit
@ -287,17 +291,24 @@ Then check/modify also the user/date signature:
- Name and email must match value into debian/control file (Entry added here is used by next step).
To update dolibarr debian package when only files into debian has changed, or if you include manually backport:
To update dolibarr debian package when only files into debian has changed:
* Change files and commit.
* Add a tag debian/x.y.z+dfsgw-2 (increase the last 1 into 2, 3...)
To update dolibarr debian package when only files into debian has changed:
* Manually, add patches into debian/patches and update file debian/series, or do the 2 steps with "quilt import filepatch.patch"
* You can test patching of serie with "quilt push" (autant de fois que de patch). Avec "quilt pop -a", on revien a l'état du upstream sans les patch.
Once files has been prepared, it's time to test:
* Try to build package
> rm -fr ../build-area;
> git-buildpackage -us -uc --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-3.5.x]
> git-buildpackage -us -uc --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-3.5.x|3.5.5]
ou
> git-buildpackage -us -uc --git-ignore-branch --git-upstream-branch=[upstream|upstream-3.5.x|3.5.5]
Note: To build an old version, do: git checkout oldtagname -b newbranchname; git-buildpackage -us -uc --git-debian-branch=newbranchname --git-upstream-branch=[upstream|upstream-3.5.x]
Note: You can use git-buildpackage -us -uc --git-ignore-new if you want to test build with uncommited file

View File

@ -159,7 +159,7 @@ Comments:
Those files are not shipped in the binary package as we
configure Dolibarr to use Dejavu fonts from "fonts-dejavu-core".
Files: docs/images/*
Files: doc/images/*
Copyright: Laurent Destailleur
License: CC-BY-SA-3.0
You are free:
@ -176,7 +176,7 @@ License: CC-BY-SA-3.0
.
For more information, see http://creativecommons.org/licenses/by-sa/3.0/
Files: htdocs/includes/fpdi/*
Files: htdocs/includes/fpdfi/*
Copyright: 2004-2011 Setasign - Jan Slabon
License: GPL-2+
This program is free software; you can redistribute it

View File

@ -107,6 +107,10 @@ $dump_buffer_len = 0;
$time_start = time();
$outputdir = $conf->admin->dir_output.'/backup';
$result=dol_mkdir($outputdir);
// MYSQL
if ($what == 'mysql')
{
@ -116,7 +120,6 @@ if ($what == 'mysql')
dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
}
$outputdir = $conf->admin->dir_output.'/backup';
$outputfile = $outputdir.'/'.$file;
// for compression format, we add extension
$compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
@ -185,8 +188,6 @@ if ($what == 'mysql')
$errormsg='';
$result=dol_mkdir($outputdir);
// Debut appel methode execution
$fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
$fullcommandclear=$command." ".$paramclear." 2>&1";
@ -254,7 +255,6 @@ if ($what == 'mysql')
if ($what == 'mysqlnobin')
{
$outputdir = $conf->admin->dir_output.'/backup';
$outputfile = $outputdir.'/'.$file;
$outputfiletemp = $outputfile.'-TMP.sql';
// for compression format, we add extension
@ -288,7 +288,6 @@ if ($what == 'postgresql')
dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
}
$outputdir = $conf->admin->dir_output.'/backup';
$outputfile = $outputdir.'/'.$file;
// for compression format, we add extension
$compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
@ -299,7 +298,7 @@ if ($what == 'postgresql')
// Parameteres execution
$command=$cmddump;
if (preg_match("/\s/",$command)) $command=$command=escapeshellarg($command); // Use quotes on command
if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command
//$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
//$param="-F c";
@ -352,38 +351,34 @@ if ($what == 'postgresql')
if ($errormsg)
{
setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors');
// Si on a demande une generation
//if ($what)
//{
if ($errormsg)
{
setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors');
$resultstring='';
$resultstring.='<div class="error">'.$langs->trans("Error")." : ".$errormsg.'</div>';
$resultstring='';
$resultstring.='<div class="error">'.$langs->trans("Error")." : ".$errormsg.'</div>';
$_SESSION["commandbackupresult"]=$resultstring;
}
else
{
if ($what)
{
setEventMessages($langs->trans("BackupFileSuccessfullyCreated").'.<br>'.$langs->trans("YouCanDownloadBackupFile"), null, 'mesgs');
$resultstring='<div class="ok">';
$resultstring.=$langs->trans("BackupFileSuccessfullyCreated").'.<br>';
$resultstring.=$langs->trans("YouCanDownloadBackupFile");
$resultstring.='<div>';
$_SESSION["commandbackupresult"]=$resultstring;
}
else
}
else
{
if ($what)
{
setEventMessages($langs->trans("BackupFileSuccessfullyCreated").'.<br>'.$langs->trans("YouCanDownloadBackupFile"), null, 'mesgs');
setEventMessages($langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user), null, 'mesgs');
}
}
$resultstring='<div class="ok">';
$resultstring.=$langs->trans("BackupFileSuccessfullyCreated").'.<br>';
$resultstring.=$langs->trans("YouCanDownloadBackupFile");
$resultstring.='<div>';
$_SESSION["commandbackupresult"]=$resultstring;
}
else
{
setEventMessages($langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user), null, 'mesgs');
}
}
//}
/*
$filearray=dol_dir_list($conf->admin->dir_output.'/backup','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1);

View File

@ -50,10 +50,9 @@ if ($action=='purge' && ! preg_match('/^confirm/i',$choice) && ($choice != 'allf
{
require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
$utils = new Utils($db);
$count = $utils->purgeFiles($choice);
if ($count) $mesg=$langs->trans("PurgeNDirectoriesDeleted", $count);
else $mesg=$langs->trans("PurgeNothingToDelete");
$result = $utils->purgeFiles($choice);
$mesg = $utils->output;
setEventMessages($mesg, null, 'mesgs');
}

View File

@ -1992,14 +1992,18 @@ class Facture extends CommonInvoice
$this->brouillon=0;
$this->date_validation=$now;
$i = 0;
$final = True;
while ($i < count($this->lines) && $final == True) {
$final = ($this->lines[$i]->situation_percent == 100);
$i++;
}
if ($final) {
$this->setFinal();
}
if (!empty($conf->global->INVOICE_USE_SITUATION))
{
$final = True;
while ($i < count($this->lines) && $final == True) {
$final = ($this->lines[$i]->situation_percent == 100);
$i++;
}
if ($final) {
$this->setFinal();
}
}
}
}
else
@ -2277,7 +2281,6 @@ class Facture extends CommonInvoice
$this->line->context = $this->context;
$this->line->situpation_percent = $situation_percent;
$this->line->fk_facture=$this->id;
$this->line->label=$label; // deprecated
$this->line->desc=$desc;
@ -3770,11 +3773,14 @@ class Facture extends CommonInvoice
function setFinal()
{
global $conf, $langs, $user;
$this->db->begin();
$this->situation_final = 1;
$sql = 'update ' . MAIN_DB_PREFIX . 'facture set situation_final = ' . $this->situation_final . ' where rowid = ' . $this->id;
$resql = $this->db->query($sql);
if ($resql) {
// FIXME: call triggers?
// FIXME: call triggers MODIFY because we modify invoice
$this->db->commit();
return 1;
} else {

View File

@ -418,6 +418,9 @@ class Conf
// By default, suppliers objects can be linked to all projects
$this->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS = 1;
// MAIN_HTML_TITLE
if (! isset($conf->global->MAIN_HTML_TITLE)) $conf->global->MAIN_HTML_TITLE='noapp,thirdpartynameonly,contactnameonly,projectnameonly';
// conf->liste_limit = constante de taille maximale des listes
if (empty($this->global->MAIN_SIZE_LISTE_LIMIT)) $this->global->MAIN_SIZE_LISTE_LIMIT=25;
$this->liste_limit=$this->global->MAIN_SIZE_LISTE_LIMIT;

View File

@ -1018,7 +1018,7 @@ class Form
// Do not use textempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
//$textifempty=' ';
//if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) $textifempty.=$langs->trans("NoFilter");
if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) $textifempty.=$langs->trans("All");
if ($showempty) $out.= '<option value="-1">'.$textifempty.'</option>'."\n";
$num = $this->db->num_rows($resql);
@ -4134,7 +4134,7 @@ class Form
* - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
* - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
*
* @param timestamp $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date.
* @param timestamp $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date (emptydate must be 0).
* @param string $prefix Prefix for fields name
* @param int $h 1=Show also hours
* @param int $m 1=Show also minutes

View File

@ -44,11 +44,11 @@ class Utils
* Purge files into directory of data files.
*
* @param string $choice Choice of purge mode ('tempfiles', 'tempfilesold' to purge temp older than 24h, 'allfiles', 'logfiles')
* @return int Nb of files deleted
* @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
*/
function purgeFiles($choice='tempfilesold')
{
global $conf, $dolibarr_main_data_root;
global $conf, $langs, $dolibarr_main_data_root;
dol_syslog("Utils::purgeFiles choice=".$choice, LOG_DEBUG);
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
@ -123,7 +123,11 @@ class Utils
$result = $ecmdirstatic->refreshcachenboffile(1);
}
}
return $count;
if ($count > 0) $this->output=$langs->trans("PurgeNDirectoriesDeleted", $count);
else $this->output=$langs->trans("PurgeNothingToDelete");
//return $count;
return 0; // This function can be called by cron so must return 0 if OK
}
}

View File

@ -1176,6 +1176,8 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n
else $ok=unlink($filename);
if ($ok) dol_syslog("Removed file ".$filename, LOG_DEBUG);
else dol_syslog("Failed to remove file ".$filename, LOG_WARNING);
// TODO Failure to remove can be because file was already removed or because of permission
// If error because of not exists, we must can return true but we should return false if this is a permission problem
}
}
else dol_syslog("No files to delete found", LOG_WARNING);
@ -1186,7 +1188,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n
if ($nophperrors) $ok=@unlink($file_osencoded);
else $ok=unlink($file_osencoded);
if ($ok) dol_syslog("Removed file ".$file_osencoded, LOG_DEBUG);
else dol_syslog("Failed to remove file ".$file_osencoded, LOG_WARNING);
else dol_syslog("Failed to remove file ".$file_osencoded, LOG_WARNING);
}
return $ok;

View File

@ -306,7 +306,7 @@ function dol_getprefix()
* To link to a module file from a core file, then this function can be used (call by hook / trigger / speciales pages)
*
* @param string $relpath Relative path to file (Ie: mydir/myfile, ../myfile, ...)
* @param string $classname Class name
* @param string $classname Class name (deprecated)
* @return bool True if load is a success, False if it fails
*/
function dol_include_once($relpath, $classname='')

View File

@ -913,7 +913,10 @@ class DolibarrModules // Can not be abstract, because we need to insta
$comment = isset($this->cronjobs[$key]['comment'])?$this->cronjobs[$key]['comment']:'';
$frequency = isset($this->cronjobs[$key]['frequency'])?$this->cronjobs[$key]['frequency']:'';
$unitfrequency = isset($this->cronjobs[$key]['unitfrequency'])?$this->cronjobs[$key]['unitfrequency']:'';
$status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:'';
$priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:'';
$test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:'';
// Search if boxes def already present
$sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob";
$sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'";
@ -936,7 +939,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
if (! $err)
{
$sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note, frequency, unitfrequency, entity)";
$sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note, frequency, unitfrequency, priority, status, entity, test)";
$sql.= " VALUES (";
$sql.= "'".$this->db->escape($this->rights_class)."', ";
$sql.= "'".$this->db->idate($now)."', ";
@ -951,7 +954,10 @@ class DolibarrModules // Can not be abstract, because we need to insta
$sql.= ($comment?"'".$this->db->escape($comment)."'":"null").",";
$sql.= "'".$this->db->escape($frequency)."', ";
$sql.= "'".$this->db->escape($unitfrequency)."', ";
$sql.= $conf->entity;
$sql.= "'".$this->db->escape($priority)."', ";
$sql.= "'".$this->db->escape($status)."', ";
$sql.= $conf->entity.",";
$sql.= "'".$this->db->escape($test)."'";
$sql.= ")";
dol_syslog(get_class($this)."::insert_cronjobs", LOG_DEBUG);

View File

@ -101,8 +101,9 @@ class modCron extends DolibarrModules
// Cronjobs
$this->cronjobs = array(
0=>array('label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7),
// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24)
0=>array('label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>10, 'status'=>1, 'test'=>'1'),
1=>array('label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>20, 'status'=>0, 'test'=>'0'),
// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24)
);
$this->rights[$r][0] = 23001;

View File

@ -107,7 +107,7 @@ class modFacture extends DolibarrModules
// Cronjobs
$this->cronjobs = array(
0=>array('label'=>'RecurringInvoices', 'jobtype'=>'method', 'class'=>'compta/facture/class/facture-rec.class.php', 'objectname'=>'Facture', 'method'=>'generateRecurringInvoices', 'parameters'=>'', 'comment'=>'Generate recurring invoices', 'frequency'=>1, 'unitfrequency'=>3600*24),
0=>array('label'=>'RecurringInvoices', 'jobtype'=>'method', 'class'=>'compta/facture/class/facture-rec.class.php', 'objectname'=>'FactureRec', 'method'=>'generateRecurringInvoices', 'parameters'=>'', 'comment'=>'Generate recurring invoices', 'frequency'=>1, 'unitfrequency'=>3600*24),
// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>3600, 'unitfrequency'=>3600)
);
// List of cron jobs entries to add

View File

@ -142,6 +142,7 @@ if ($action=='add')
$object->note=GETPOST('note');
$object->datestart=dol_mktime(GETPOST('datestarthour','int'), GETPOST('datestartmin','int'), 0, GETPOST('datestartmonth','int'), GETPOST('datestartday','int'), GETPOST('datestartyear','int'));
$object->dateend=dol_mktime(GETPOST('dateendhour','int'), GETPOST('dateendmin','int'), 0, GETPOST('dateendmonth','int'), GETPOST('dateendday','int'), GETPOST('dateendyear','int'));
$object->datenextrun=dol_mktime(GETPOST('datenextrunhour','int'), GETPOST('datenextrunmin','int'), 0, GETPOST('datenextrunmonth','int'), GETPOST('datenextrunday','int'), GETPOST('datenextrunyear','int'));
$object->unitfrequency=GETPOST('unitfrequency','int');
$object->frequency=GETPOST('nbfrequency','int');
$object->maxrun=GETPOST('maxrun','int');
@ -177,6 +178,7 @@ if ($action=='update')
$object->note=GETPOST('note');
$object->datestart=dol_mktime(GETPOST('datestarthour','int'), GETPOST('datestartmin','int'), 0, GETPOST('datestartmonth','int'), GETPOST('datestartday','int'), GETPOST('datestartyear','int'));
$object->dateend=dol_mktime(GETPOST('dateendhour','int'), GETPOST('dateendmin','int'), 0, GETPOST('dateendmonth','int'), GETPOST('dateendday','int'), GETPOST('dateendyear','int'));
$object->datenextrun=dol_mktime(GETPOST('datenextrunhour','int'), GETPOST('datenextrunmin','int'), 0, GETPOST('datenextrunmonth','int'), GETPOST('datenextrunday','int'), GETPOST('datenextrunyear','int'));
$object->unitfrequency=GETPOST('unitfrequency','int');
$object->frequency=GETPOST('nbfrequency','int');
$object->maxrun=GETPOST('maxrun','int');
@ -475,7 +477,7 @@ if (($action=="create") || ($action=="edit"))
$form->select_date($object->dateend,'dateend',1,1,'',"cronform");
}
else{
$form->select_date('','dateend',1,1,1,"cronform");
$form->select_date(-1,'dateend',1,1,1,"cronform");
}
print "</td>";
print "<td>";
@ -506,6 +508,23 @@ if (($action=="create") || ($action=="edit"))
print "</td>";
print "</tr>\n";
print '<tr><td>';
print $langs->trans('CronDtNextLaunch');
print ' ('.$langs->trans('CronFrom').')';
print "</td><td>";
if(!empty($object->datenextrun))
{
$form->select_date($object->datenextrun,'datenextrun',1,1,'',"cronform");
}
else
{
$form->select_date(-1,'datenextrun',1,1,'',"cronform");
}
print "</td>";
print "<td>";
print "</td>";
print "</tr>";
print '</table>';
dol_fiche_end();

View File

@ -107,7 +107,8 @@ class Cronjob extends CommonObject
if (isset($this->note)) $this->note=trim($this->note);
if (isset($this->nbrun)) $this->nbrun=trim($this->nbrun);
if (isset($this->libname)) $this->libname = trim($this->libname);
if (isset($this->test)) $this->test = trim($this->test);
// Check parameters
// Put here code to add a control on parameters values
if (dol_strlen($this->datestart)==0) {
@ -177,11 +178,9 @@ class Cronjob extends CommonObject
$sql.= "note,";
$sql.= "nbrun,";
$sql.= "maxrun,";
$sql.= "libname";
$sql.= "libname,";
$sql.= "test";
$sql.= ") VALUES (";
$sql.= " '".$this->db->idate($now)."',";
$sql.= " ".(! isset($this->jobtype)?'NULL':"'".$this->db->escape($this->jobtype)."'").",";
$sql.= " ".(! isset($this->label)?'NULL':"'".$this->db->escape($this->label)."'").",";
@ -208,7 +207,8 @@ class Cronjob extends CommonObject
$sql.= " ".(! isset($this->note)?'NULL':"'".$this->db->escape($this->note)."'").",";
$sql.= " ".(! isset($this->nbrun)?'0':"'".$this->db->escape($this->nbrun)."'").",";
$sql.= " ".(empty($this->maxrun)?'null':"'".$this->db->escape($this->maxrun)."'").",";
$sql.= " ".(! isset($this->libname)?'NULL':"'".$this->db->escape($this->libname)."'")."";
$sql.= " ".(! isset($this->libname)?'NULL':"'".$this->db->escape($this->libname)."'").",";
$sql.= " ".(! isset($this->test)?'NULL':"'".$this->db->escape($this->test)."'")."";
$sql.= ")";
$this->db->begin();
@ -292,9 +292,8 @@ class Cronjob extends CommonObject
$sql.= " t.note,";
$sql.= " t.nbrun,";
$sql.= " t.maxrun,";
$sql.= " t.libname";
$sql.= " t.libname,";
$sql.= " t.test";
$sql.= " FROM ".MAIN_DB_PREFIX."cronjob as t";
$sql.= " WHERE t.rowid = ".$id;
@ -337,7 +336,7 @@ class Cronjob extends CommonObject
$this->nbrun = $obj->nbrun;
$this->maxrun = $obj->maxrun;
$this->libname = $obj->libname;
$this->test = $obj->test;
}
$this->db->free($resql);
@ -391,9 +390,9 @@ class Cronjob extends CommonObject
$sql.= " t.fk_user_author,";
$sql.= " t.fk_user_mod,";
$sql.= " t.note,";
$sql.= " t.nbrun";
$sql .= ", t.libname";
$sql.= " t.nbrun,";
$sql.= " t.libname,";
$sql.= " t.test";
$sql.= " FROM ".MAIN_DB_PREFIX."cronjob as t";
$sql.= " WHERE 1 = 1";
if ($status >= 0) $sql.= " AND t.status = ".(empty($status)?'0':'1');
@ -465,7 +464,8 @@ class Cronjob extends CommonObject
$line->fk_user_mod = $obj->fk_user_mod;
$line->note = $obj->note;
$line->nbrun = $obj->nbrun;
$line->libname = $obj->libname;
$line->libname = $obj->libname;
$line->test = $obj->test;
$this->lines[]=$line;
$i++;
@ -519,7 +519,8 @@ class Cronjob extends CommonObject
if (isset($this->nbrun)) $this->nbrun=trim($this->nbrun);
if (isset($this->maxrun)) $this->maxrun=trim($this->maxrun);
if (isset($this->libname)) $this->libname = trim($this->libname);
if (isset($this->test)) $this->test = trim($this->test);
// Check parameters
// Put here code to add a control on parameters values
if (dol_strlen($this->datestart)==0) {
@ -586,10 +587,11 @@ class Cronjob extends CommonObject
$sql.= " status=".(isset($this->status)?$this->status:"null").",";
$sql.= " fk_user_mod=".$user->id.",";
$sql.= " note=".(isset($this->note)?"'".$this->db->escape($this->note)."'":"null").",";
$sql.= " nbrun=".(isset($this->nbrun)?$this->nbrun:"null").",";
$sql.= " maxrun=".(isset($this->maxrun)?$this->maxrun:"null").",";
$sql.= " libname=".(isset($this->libname)?"'".$this->db->escape($this->libname)."'":"null");
$sql.= " WHERE rowid=".$this->id;
$sql.= " nbrun=".((isset($this->nbrun) && $this->nbrun >0)?$this->nbrun:"null").",";
$sql.= " maxrun=".((isset($this->maxrun) && $this->maxrun > 0)?$this->maxrun:"null").",";
$sql.= " libname=".(isset($this->libname)?"'".$this->db->escape($this->libname)."'":"null").",";
$sql.= " test=".(isset($this->test)?"'".$this->db->escape($this->test)."'":"null");
$sql.= " WHERE rowid=".$this->id;
$this->db->begin();
@ -829,10 +831,10 @@ class Cronjob extends CommonObject
/**
* Run a job.
* Once job is finished, status and nb of of run is updated.
* Once job is finished, status and nb of run is updated.
* This function does not plan the next run. This is done by function ->reprogram_jobs
*
* @param string $userlogin User login
* @param string $userlogin User login
* @return int <0 if KO, >0 if OK
*/
function run_jobs($userlogin)
@ -905,25 +907,43 @@ class Cronjob extends CommonObject
if ($this->jobtype=='method')
{
// load classes
$ret=dol_include_once($this->classesname,$this->objectname);
if (! $error && $ret===false)
if (! $error)
{
$this->error=$langs->trans('CronCannotLoadClass',$this->classesname,$this->objectname);
dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
$this->lastoutput = $this->error;
$this->lastresult = -1;
$retval = $this->lastresult;
$error++;
$ret=dol_include_once($this->classesname);
if ($ret===false || (! class_exists($this->objectname)))
{
$this->error=$langs->trans('CronCannotLoadClass',$this->classesname,$this->objectname);
dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
$this->lastoutput = $this->error;
$this->lastresult = -1;
$retval = $this->lastresult;
$error++;
}
}
// test if method exists
if (! $error)
{
if (! method_exists($this->objectname, $this->methodename))
{
$this->error=$langs->trans('CronMethodDoesNotExists',$this->objectname,$this->methodename);
dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
$this->lastoutput = $this->error;
$this->lastresult = -1;
$retval = $this->lastresult;
$error++;
}
}
// Load langs
if (! $error)
{
$result=$langs->load($this->module_name.'@'.$this->module_name);
if ($result<0)
if ($result < 0)
{
dol_syslog(get_class($this)."::run_jobs Cannot load module lang file - ".$langs->error, LOG_ERR);
$this->lastoutput = $langs->error;
$this->error = $langs->error;
$this->lastoutput = $this->error;
$this->lastresult = -1;
$retval = $this->lastresult;
$error++;
@ -947,17 +967,19 @@ class Cronjob extends CommonObject
$result = call_user_func_array(array($object, $this->methodename), $params_arr);
}
if ($result===false)
if ($result===false || $result != 0)
{
dol_syslog(get_class($this)."::run_jobs ".$object->error, LOG_ERR);
$this->lastoutput = $object->error;
$this->lastresult = -1;
$langs->load("errors");
dol_syslog(get_class($this)."::run_jobs result=".$result." error=".$object->error, LOG_ERR);
$this->error = $object->error?$object->error:$langs->trans('ErrorUnknown');
$this->lastoutput = $this->error;
$this->lastresult = is_numeric($result)?$result:-1;
$retval = $this->lastresult;
$error++;
}
else
{
$this->lastoutput='NA';
$this->lastoutput=$object->output;
$this->lastresult=var_export($result,true);
$retval = $this->lastresult;
}
@ -993,13 +1015,15 @@ class Cronjob extends CommonObject
$result = call_user_func_array($this->methodename, $params_arr);
}
if ($result === false)
if ($result === false || $result != 0)
{
dol_syslog(get_class($this) . "::run_jobs " . $object->error, LOG_ERR);
$this->lastoutput = $object->error;
$this->lastresult = -1;
$retval = $this->lastresult;
$langs->load("errors");
dol_syslog(get_class($this)."::run_jobs result=".$result, LOG_ERR);
$this->error = $langs->trans('ErrorUnknown');
$this->lastoutput = $this->error;
$this->lastresult = is_numeric($result)?$result:-1;
$retval = $this->lastresult;
$error++;
}
else
{
@ -1024,6 +1048,16 @@ class Cronjob extends CommonObject
if ($execmethod == 1)
{
exec($command, $output_arr, $retval);
if ($retval != 0)
{
$langs->load("errors");
dol_syslog(get_class($this)."::run_jobs retval=".$retval, LOG_ERR);
$this->error = 'Error '.$retval;
$this->lastoutput = ''; // Will be filled later
$this->lastresult = $retval;
$retval = $this->lastresult;
$error++;
}
}
if ($execmethod == 2)
{
@ -1046,7 +1080,7 @@ class Cronjob extends CommonObject
}
}
dol_syslog(get_class($this)."::run_jobs output_arr:".var_export($output_arr,true), LOG_DEBUG);
dol_syslog(get_class($this)."::run_jobs output_arr:".var_export($output_arr,true)." lastoutput=".$this->lastoutput." lastresult=".$this->lastresult, LOG_DEBUG);
// Update with result
if (is_array($output_arr) && count($output_arr)>0)

View File

@ -99,7 +99,7 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex
$now = dol_now(); // Date we start
$resrunjob = $object->run_jobs($user->login);
$resrunjob = $object->run_jobs($user->login); // Return -1 if KO, 1 if OK
if ($resrunjob < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
@ -110,8 +110,8 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex
{
if ($resrunjob >= 0) // We add result of reprogram ony if no error message already reported
{
if ($object->lastresult > 0) setEventMessages($langs->trans("JobFinished"), null, 'warnings');
else setEventMessages($langs->trans("JobFinished"), null, 'mesgs');
if ($object->lastresult >= 0) setEventMessages($langs->trans("JobFinished"), null, 'mesgs');
else setEventMessages($langs->trans("JobFinished"), null, 'errors');
}
$action='';
}
@ -220,13 +220,15 @@ if ($num > 0)
$style='pair';
foreach($object->lines as $line)
{
if (! verifCond($line->test)) continue; // Discard line with test = false
// title profil
if ($style=='pair') {$style='impair';}
else {$style='pair';}
print '<tr class="'.$style.'">';
print '<td>';
print '<td class="nowrap">';
print '<a href="'.DOL_URL_ROOT.'/cron/card.php?id='.$line->id.'">';
print img_picto('', 'object_cron').' ';
print $line->id;
@ -252,15 +254,15 @@ if ($num > 0)
$texttoshow.=$langs->trans('CronClass').': '. $line->classesname.'<br>';
$texttoshow.=$langs->trans('CronObject').': '. $line->objectname.'<br>';
$texttoshow.=$langs->trans('CronMethod').': '. $line->methodename;
$texttoshow.='<br>'.$langs->trans('CronArgs').':'. $line->params;
$texttoshow.='<br>'.$langs->trans('Comment').':'. $line->note;
$texttoshow.='<br>'.$langs->trans('CronArgs').': '. $line->params;
$texttoshow.='<br>'.$langs->trans('Comment').': '. $langs->trans($line->note);
}
elseif ($line->jobtype=='command')
{
$text=$langs->trans('CronCommand');
$texttoshow=$langs->trans('CronCommand').': '.dol_trunc($line->command);
$texttoshow.='<br>'.$langs->trans('CronArgs').':'. $line->params;
$texttoshow.='<br>'.$langs->trans('Comment').':'. $line->note;
$texttoshow.='<br>'.$langs->trans('CronArgs').': '. $line->params;
$texttoshow.='<br>'.$langs->trans('Comment').': '. $langs->trans($line->note);
}
print $form->textwithpicto($text, $texttoshow, 1);
print '</td>';

View File

@ -153,7 +153,6 @@ class Fichinter extends CommonObject
$sql.= ", ".$conf->entity;
$sql.= ", ".$user->id;
$sql.= ", ".$user->id;
$sql.= ", ".$user->id;
$sql.= ", ".($this->description?"'".$this->db->escape($this->description)."'":"null");
$sql.= ", '".$this->db->escape($this->modelpdf)."'";
$sql.= ", ".($this->fk_project ? $this->fk_project : 0);

View File

@ -35,6 +35,7 @@ UPDATE llx_projet as p set opp_percent = (SELECT percent from llx_c_lead_status
ALTER TABLE llx_overwrite_trans ADD UNIQUE INDEX uk_overwrite_trans(lang, transkey);
ALTER TABLE llx_cronjob MODIFY COLUMN unitfrequency varchar(255) NOT NULL DEFAULT '3600';
ALTER TABLE llx_cronjob ADD COLUMN test varchar(255) DEFAULT '1';
ALTER TABLE llx_facture ADD INDEX idx_facture_fk_statut (fk_statut);

View File

@ -46,6 +46,7 @@ CREATE TABLE llx_cronjob
nbrun integer, -- nb of run complete (failed or not)
autodelete integer DEFAULT 0, -- 0=Job is kept unchanged once nbrun > maxrun or date > dateend, 2=Job must be archived (archive = status 2) once nbrun > maxrun or date > dateend
status integer NOT NULL DEFAULT 1, -- 0=disabled, 1=enabled, 2=archived
test varchar(255) DEFAULT '1',
fk_user_author integer DEFAULT NULL,
fk_user_mod integer DEFAULT NULL,
fk_mailing integer DEFAULT NULL, -- id of emailing if job was queued to send mass emailing

View File

@ -16,6 +16,7 @@ KeyForCronAccess=Security key for URL to launch cron jobs
FileToLaunchCronJobs=Command line to launch cron jobs
CronExplainHowToRunUnix=On Unix environment you should use the following crontab entry to run the command line each 5 minutes
CronExplainHowToRunWin=On Microsoft(tm) Windows environement you can use Scheduled task tools to run the command line each 5 minutes
CronMethodDoesNotExists=Class %s does not contains any method %s
# Menu
CronJobs=Scheduled jobs
CronListActive=List of enabled/scheduled jobs
@ -89,3 +90,5 @@ CronMenu=Cron
CronCannotLoadClass=Cannot load class %s or object %s
UseMenuModuleToolsToAddCronJobs=Go into menu "Home - Modules tools - Job list" to see and edit scheduled jobs.
TaskDisabled=Job disabled
MakeLocalDatabaseDumpShort=Local database backup
MakeLocalDatabaseDump=Create a local database dump

View File

@ -32,6 +32,7 @@ Language_es_MX=Spanish (Mexico)
Language_es_PY=Spanish (Paraguay)
Language_es_PE=Spanish (Peru)
Language_es_PR=Spanish (Puerto Rico)
Language_es_VE=Spanish (Venezuela)
Language_et_EE=Estonian
Language_eu_ES=Basque
Language_fa_IR=Persian

View File

@ -1010,7 +1010,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs
if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
if ($title && ! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/noapp/',$conf->global->MAIN_HTML_TITLE)) print '<title>'.dol_htmlentities($title).'</title>';
if ($title) print '<title>'.dol_htmlentities($appli.' - '.$title).'</title>';
else if ($title) print '<title>'.dol_htmlentities($appli.' - '.$title).'</title>';
else print "<title>".dol_htmlentities($appli)."</title>";
print "\n";

View File

@ -398,8 +398,8 @@ $formfile = new FormFile($db);
$formproject = new FormProjets($db);
$userstatic = new User($db);
$title=$langs->trans("Project").' - '.$object->ref.' '.$object->name;
if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->ref.' '.$object->name;
$title=$langs->trans("Project").' - '.$object->ref.($object->thirdparty->name?' - '.$object->thirdparty->name:'').($object->title?' - '.$object->title:'');
if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/',$conf->global->MAIN_HTML_TITLE)) $title=$object->ref.($object->thirdparty->name?' - '.$object->thirdparty->name:'').($object->title?' - '.$object->title:'');
$help_url="EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
llxHeader("",$title,$help_url);
@ -660,7 +660,7 @@ else
print '<tr><td>'.$langs->trans("ThirdParty").'</td><td>';
$filteronlist='';
if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
$text=$form->select_thirdparty_list($object->thirdparty->id,'socid',$filteronlist,1,1);
$text=$form->select_thirdparty_list($object->thirdparty->id, 'socid', $filteronlist, 1, 1);
$texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty");
print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2);
print '</td></tr>';

View File

@ -144,7 +144,7 @@ if (is_array($object->lines) && (count($object->lines)>0))
$result=$cronjob->fetch($line->id);
if ($result<0)
{
echo "Error:".$cronjob->error;
echo "Error:".$cronjob->error."<br>\n";
dol_syslog("cron_run_jobs.php:: fetch Error".$cronjob->error, LOG_ERR);
exit;
}
@ -152,7 +152,7 @@ if (is_array($object->lines) && (count($object->lines)>0))
$result=$cronjob->run_jobs($userlogin);
if ($result < 0)
{
echo "Error:".$cronjob->error;
echo "Error:".$cronjob->error."<br>\n";
dol_syslog("cron_run_jobs.php:: run_jobs Error".$cronjob->error, LOG_ERR);
$nbofjobslaunchedko++;
}
@ -165,7 +165,7 @@ if (is_array($object->lines) && (count($object->lines)>0))
$result=$cronjob->reprogram_jobs($userlogin, $now);
if ($result<0)
{
echo "Error:".$cronjob->error;
echo "Error:".$cronjob->error."<br>\n";
dol_syslog("cron_run_jobs.php:: reprogram_jobs Error".$cronjob->error, LOG_ERR);
exit;
}

View File

@ -75,7 +75,8 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase
public static function setUpBeforeClass()
{
global $conf,$user,$langs,$db;
$db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
$db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
print __METHOD__."\n";
}
@ -136,7 +137,8 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase
$conf->global->FACTURE_ADDON='mercure';
$conf->global->FACTURE_MERCURE_MASK_CREDIT='{yyyy}-{0000}';
$conf->global->FACTURE_MERCURE_MASK_INVOICE='{yyyy}-{0000}';
$conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED=0;
$localobject=new Facture($this->savdb);
$localobject->initAsSpecimen();
$localobject->date=dol_mktime(12, 0, 0, 1, 1, 1915); // we use year 1915 to be sure to not have existing invoice for this year
@ -145,10 +147,10 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase
$result2=$localobject->create($user,1);
$result3=$localobject->validate($user, $result); // create invoice by forcing ref
print __METHOD__." result=".$result."\n";
$this->assertEquals('1915-0001', $result); // counter must start to 1
$this->assertEquals('1915-0001', $result, 'Test for {yyyy}-{0000}, 1st invoice'); // counter must start to 1
$result=$localobject->is_erasable();
print __METHOD__." is_erasable=".$result."\n";
$this->assertEquals(1, $result, 'Test for {yyyy}-{0000}, 1st invoice'); // Can be deleted
$this->assertEquals(1, $result, 'Test for is_erasable, 1st invoice'); // Can be deleted
$localobject2=new Facture($this->savdb);
$localobject2->initAsSpecimen();
@ -156,7 +158,7 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase
$numbering=new mod_facture_mercure();
$result=$numbering->getNextValue($mysoc, $localobject2, 'last');
print __METHOD__." result=".$result."\n";
$this->assertEquals('1915-0001', $result);
$this->assertEquals('1915-0001', $result, "Test to get last value with param 'last'");
$result=$numbering->getNextValue($mysoc, $localobject2);
$result2=$localobject2->create($user,1);
$result3=$localobject2->validate($user, $result); // create invoice by forcing ref