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

Conflicts:
	ChangeLog
This commit is contained in:
Laurent Destailleur 2019-06-25 23:14:49 +02:00
commit 51a1550dbb
11 changed files with 134 additions and 46 deletions

View File

@ -16,6 +16,7 @@ Following changes may create regressions for some external modules, but were nec
* Properties ->libelle_incoterms were renamed into ->label_incoterms
***** ChangeLog for 10.0.0 compared to 9.0.0 *****
For Users:
NEW: Module "Ticket" is available as a stable module.
@ -195,6 +196,55 @@ Following changes may create regressions for some external modules, but were nec
called $dolibarr_main_instance_unique_id is now generated at each installation. It will be used by some future features.
***** ChangeLog for 9.0.4 compared to 9.0.3 *****
FIX: #5249
FIX: #11025
FIX: #11032
FIX: #11097
FIX: #11169
FIX: #11202
FIX: #11244
FIX: #11296
FIX: #11316
FIX: #11335
FIX: Add missing end date of subscription in export
FIX: A user may read holiday and expense report without permissions
FIX: better syntax
FIX: condition
FIX: confirmation of mass email sending + option MAILING_NO_USING_PHPMAIL
FIX: crabe pdf: bad detailed VAT for situation invoices, in situations S2 and above
FIX: default value for duration of validity can be set from generic
FIX: do not include tpl from disabled modules
FIX: Error management when MAILING_NO_USING_PHPMAIL is set
FIX: Even with permission, can't validate leave once validator defined.
FIX: extrafield list search: SQL error when field is multiselect
FIX: if last char of customercode is accent making the truncate of first
FIX: Import of chart of account
FIX: in edit mode, dictionary inputs do not escape the string inside the 'value' attribute, causing errors if there are any double quotes
FIX: invalid link on user.fk_user
FIX: invoice class: bad SQL request if product type not set
FIX: javascript error when ckeditor module not enabled
FIX: mail presend: can overwrite a file previously uploaded (Issue #11056)
FIX: mass send mail
FIX: missing compatibility with multicompany transverse mode
FIX: missing llx_const encrypt
FIX: modulebuilder: hardcoded llx_
FIX: Not showing Contract and Project columns on ficheinter list
FIX: only profid1 to 4 were editable for pdf option to show. Not 5 and 6.
FIX: productaccount buylist with pages
FIX: remove isolated transaction commit
FIX: security (a user can read leave or holiday of other without perm.
FIX: situation invoices: bad detailed VAT in situations following the first one
FIX: situation invoices: block progress percentage change for discount lines
FIX: syntax error
FIX: the id was not loaded in fetch of accounting system
FIX: try to use WHERE EXISTS instead of DISTINCT
FIX: use dol_sanitizeFileName() function to remove double spaces in filenames, as well as done on document.php when we want to download pdf
FIX: Use of cron with multicompany
FIX: var name
FIX: we need to fetch fourn invoice with ref in current entity
FIX: Wrong stock movement on supplier credit notes
FIX: Import of record in ledger
***** ChangeLog for 9.0.3 compared to 9.0.2 *****
FIX: #11013

View File

@ -106,6 +106,7 @@ if (empty($includecustom)) {
}
print "Release : ".$release."\n";
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
print "Include custom in signature : ".$includecustom."\n";
print "Include constants in signature : ";
foreach ($includeconstants as $countrycode => $tmp) {

View File

@ -50,33 +50,36 @@ class Utils
* Purge files into directory of data files.
* CAN BE A CRON TASK
*
* @param string $choice Choice of purge mode ('tempfiles', '' or 'tempfilesold' to purge temp older than 24h, 'allfiles', 'logfile')
* @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
* @param string $choice Choice of purge mode ('tempfiles', '' or 'tempfilesold' to purge temp older than $nbsecondsold seconds, 'allfiles', 'logfile')
* @param int $nbsecondsold Nb of seconds old to accept deletion of a directory if $choice is 'tempfilesold'
* @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
*/
public function purgeFiles($choice = 'tempfilesold')
public function purgeFiles($choice = 'tempfilesold', $nbsecondsold = 86400)
{
global $conf, $langs, $dolibarr_main_data_root;
$langs->load("admin");
dol_syslog("Utils::purgeFiles choice=".$choice, LOG_DEBUG);
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$filesarray=array();
if (empty($choice)) $choice='tempfilesold';
dol_syslog("Utils::purgeFiles choice=".$choice, LOG_DEBUG);
if ($choice=='tempfiles' || $choice=='tempfilesold')
{
// Delete temporary files
if ($dolibarr_main_data_root)
{
$filesarray=dol_dir_list($dolibarr_main_data_root, "directories", 1, '^temp$', '', 'name', SORT_ASC, 2, 0, '', 1); // Do not follow symlinks
if ($choice == 'tempfilesold')
$filesarray=dol_dir_list($dolibarr_main_data_root, "directories", 1, '^temp$', '', 'name', SORT_ASC, 2, 0, '', 1); // Do not follow symlinks
if ($choice == 'tempfilesold')
{
$now = dol_now();
foreach($filesarray as $key => $val)
{
if ($val['date'] > ($now - (24 * 3600))) unset($filesarray[$key]); // Discard files not older than 24h
if ($val['date'] > ($now - ($nbsecondsold))) unset($filesarray[$key]); // Discard temp dir not older than $nbsecondsold
}
}
}
@ -119,13 +122,14 @@ class Utils
$counterror=0;
if (count($filesarray))
{
foreach($filesarray as $key => $value)
foreach($filesarray as $key => $value)
{
//print "x ".$filesarray[$key]['fullname']."-".$filesarray[$key]['type']."<br>\n";
if ($filesarray[$key]['type'] == 'dir')
if ($filesarray[$key]['type'] == 'dir')
{
$startcount=0;
$tmpcountdeleted=0;
$result=dol_delete_dir_recursive($filesarray[$key]['fullname'], $startcount, 1, 0, $tmpcountdeleted);
$count+=$result;
$countdeleted+=$tmpcountdeleted;
@ -165,6 +169,13 @@ class Utils
}
else $this->output=$langs->trans("PurgeNothingToDelete").($choice == 'tempfilesold' ? ' (older than 24h)':'');
// Recreate temp dir that are not automatically recreated by core code for performance purpose, we need them
if (! empty($conf->api->enabled))
{
dol_mkdir($conf->api->dir_temp);
}
dol_mkdir($conf->user->dir_temp);
//return $count;
return 0; // This function can be called by cron so must return 0 if OK
}

View File

@ -669,18 +669,30 @@ class ImportCsv extends ModeleImports
if (! preg_match('/^'.preg_quote($alias).'\./', $key)) continue; // Not a field of current table
if ($val == 'user->id')
{
$listfields[] = preg_replace('/^'.preg_quote($alias).'\./', '', $key);
$listfields[] = preg_replace('/^'.preg_quote($alias, '/').'\./', '', $key);
$listvalues[] = $user->id;
}
elseif (preg_match('/^lastrowid-/', $val))
{
$tmp=explode('-', $val);
$lastinsertid=(isset($last_insert_id_array[$tmp[1]]))?$last_insert_id_array[$tmp[1]]:0;
$keyfield = preg_replace('/^'.preg_quote($alias).'\./', '', $key);
$keyfield = preg_replace('/^'.preg_quote($alias, '/').'\./', '', $key);
$listfields[] = $keyfield;
$listvalues[] = $lastinsertid;
//print $key."-".$val."-".$listfields."-".$listvalues."<br>";exit;
}
elseif (preg_match('/^const-/', $val))
{
$tmp=explode('-', $val, 2);
$listfields[] = preg_replace('/^'.preg_quote($alias, '/').'\./', '', $key);
$listvalues[] = "'".$tmp[1]."'";
}
else
{
$this->errors[$error]['lib']='Bad value of profile setup '.$val.' for array_import_fieldshidden';
$this->errors[$error]['type']='Import profile setup';
$error++;
}
}
}
//print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';

View File

@ -688,21 +688,33 @@ class ImportXlsx extends ModeleImports
// Loop on each hidden fields to add them into listfields/listvalues
foreach($objimport->array_import_fieldshidden[0] as $key => $val)
{
if (! preg_match('/^'.preg_quote($alias).'\./', $key)) continue; // Not a field of current table
if (! preg_match('/^'.preg_quote($alias, '/').'\./', $key)) continue; // Not a field of current table
if ($val == 'user->id')
{
$listfields[] = preg_replace('/^'.preg_quote($alias).'\./', '', $key);
$listfields[] = preg_replace('/^'.preg_quote($alias, '/').'\./', '', $key);
$listvalues[] = $user->id;
}
elseif (preg_match('/^lastrowid-/', $val))
{
$tmp=explode('-', $val);
$lastinsertid=(isset($last_insert_id_array[$tmp[1]]))?$last_insert_id_array[$tmp[1]]:0;
$keyfield = preg_replace('/^'.preg_quote($alias).'\./', '', $key);
$keyfield = preg_replace('/^'.preg_quote($alias, '/').'\./', '', $key);
$listfields[] = $keyfield;
$listvalues[] = $lastinsertid;
//print $key."-".$val."-".$listfields."-".$listvalues."<br>";exit;
}
elseif (preg_match('/^const-/', $val))
{
$tmp=explode('-', $val, 2);
$listfields[] = preg_replace('/^'.preg_quote($alias, '/').'\./', '', $key);
$listvalues[] = "'".$tmp[1]."'";
}
else
{
$this->errors[$error]['lib']='Bad value of profile setup '.$val.' for array_import_fieldshidden';
$this->errors[$error]['type']='Import profile setup';
$error++;
}
}
}
//print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';

View File

@ -288,32 +288,36 @@ class modAccounting extends DolibarrModules
$this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
$this->import_tables_array[$r]=array('b'=>MAIN_DB_PREFIX.'accounting_bookkeeping'); // List of tables to insert into (insert done in same order)
$this->import_fields_array[$r]=array(
'b.doc_date'=>"Docdate",
'b.piece_num'=>"TransactionNumShort",
'b.piece_num'=>"TransactionNumShort",
'b.doc_date'=>"Docdate",
//'b.doc_type'=>'Doctype',
'b.doc_ref'=>'Piece',
'b.code_journal'=>'Codejournal',
'b.journal_label'=>'JournalLabel',
//'b.journal_label'=>'JournalLabel',
'b.numero_compte'=>'AccountAccounting',
'b.label_compte'=>'LabelAccount',
//'b.label_compte'=>'LabelAccount',
'b.subledger_account'=>'SubledgerAccount',
'b.subledger_label'=>'SubledgerAccountLabel',
'b.label_operation'=>'LabelOperation',
'b.debit'=>"Debit",
'b.credit'=>"Credit"
);
$this->import_fieldshidden_array[$r]=array('b.fk_user_author'=>'user->id'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent)
$this->import_fieldshidden_array[$r]=array('b.doc_type'=>'const-import_from_external', 'b.fk_doc'=>'const-0', 'b.fk_docdet'=>'const-0', 'b.fk_user_author'=>'user->id', 'b.date_creation'=>'const-'.dol_print_date(dol_now(), 'standard')); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent)
$this->import_regex_array[$r]=array('b.doc_date'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$');
$this->import_examplevalues_array[$r]=array(
'b.doc_date'=>'formatted as \'.dol_print_date(dol_now(),\'%Y-%m-%d\')',
'b.piece_num'=>'1',
'b.piece_num'=>'123 (!!! use next value not already used)',
'b.doc_date'=>dol_print_date(dol_now(), "%Y-%m-%d"),
//'b.doc_type'=>'import',
'b.doc_ref'=>'My document ABC',
'b.code_journal'=>"VTE",
'b.journal_label'=>"Journal des ventes",
//'b.journal_label'=>"Sale journal",
'b.numero_compte'=>"707",
'b.label_compte'=>'Ventes',
//'b.label_compte'=>'Product account 707',
'b.subledger_account'=>'',
'b.subledger_label'=>'',
'b.label_operation'=>"Ventes services",
'b.debit'=>"0,00",
'b.credit'=>"100,00"
'b.label_operation'=>"Sale of ABC",
'b.debit'=>"0",
'b.credit'=>"100"
);
// Chart of accounts

View File

@ -343,7 +343,7 @@ class FactureFournisseur extends CommonInvoice
$sql.= ", '".$this->db->escape($this->ref_supplier)."'";
$sql.= ", ".$conf->entity;
$sql.= ", '".$this->db->escape($this->type)."'";
$sql.= ", '".$this->db->escape($this->libelle)."'";
$sql.= ", '".$this->db->escape($this->label?$this->label:$this->libelle)."'";
$sql.= ", ".$this->socid;
$sql.= ", '".$this->db->idate($now)."'";
$sql.= ", '".$this->db->idate($this->date)."'";
@ -484,7 +484,7 @@ class FactureFournisseur extends CommonInvoice
{
$idligne = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn_det');
$this->updateline(
$this->updateline(
$idligne,
$line->description,
$line->pu_ht,
@ -511,8 +511,6 @@ class FactureFournisseur extends CommonInvoice
$result=$this->update_price();
if ($result > 0)
{
$action='create';
// Actions on extra fields
if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
{
@ -587,7 +585,7 @@ class FactureFournisseur extends CommonInvoice
$sql.= " t.datec,";
$sql.= " t.datef,";
$sql.= " t.tms,";
$sql.= " t.libelle,";
$sql.= " t.libelle as label,";
$sql.= " t.paye,";
$sql.= " t.amount,";
$sql.= " t.remise,";
@ -646,8 +644,8 @@ class FactureFournisseur extends CommonInvoice
$this->date = $this->db->jdate($obj->datef);
$this->datep = $this->db->jdate($obj->datef);
$this->tms = $this->db->jdate($obj->tms);
$this->libelle = $obj->libelle; // deprecated
$this->label = $obj->libelle;
$this->libelle = $obj->label; // deprecated
$this->label = $obj->label;
$this->paye = $obj->paye;
$this->amount = $obj->amount;
$this->remise = $obj->remise;
@ -2847,7 +2845,7 @@ class SupplierInvoiceLine extends CommonObjectLine
*/
public function fetch($rowid)
{
$sql = 'SELECT f.rowid, f.ref as ref_supplier, f.libelle as label, f.description, f.date_start, f.date_end, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.tva_tx';
$sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.date_start, f.date_end, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.tva_tx';
$sql.= ', f.localtax1_type, f.localtax2_type, f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2 ';
$sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_facture_fourn, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit';
$sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc';

View File

@ -21,8 +21,9 @@ CREATE TABLE llx_accounting_bookkeeping
(
rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1 NOT NULL, -- | multi company id
doc_date date NOT NULL, -- FEC:PieceDate
doc_type varchar(30) NOT NULL, -- | facture_client/reglement_client/facture_fournisseur/reglement_fournisseur
piece_num integer NOT NULL, -- FEC:EcritureNum | accounting transaction id
doc_date date NOT NULL, -- FEC:PieceDate | date of source document
doc_type varchar(30) NOT NULL, -- | facture_client/reglement_client/facture_fournisseur/reglement_fournisseur/import
doc_ref varchar(300) NOT NULL, -- FEC:PieceRef | facture_client/reglement_client/... reference number
fk_doc integer NOT NULL, -- | facture_client/reglement_client/... rowid
fk_docdet integer NOT NULL, -- | facture_client/reglement_client/... line rowid
@ -48,7 +49,6 @@ CREATE TABLE llx_accounting_bookkeeping
fk_user integer NULL, -- The id of user that validate the accounting source document
code_journal varchar(32) NOT NULL, -- FEC:JournalCode
journal_label varchar(255), -- FEC:JournalLib
piece_num integer NOT NULL, -- FEC:EcritureNum | accounting source document
date_validated datetime, -- FEC:ValidDate | if empty: movement not validated / if not empty: movement validated (No deleting / No modification)
date_export datetime DEFAULT NULL, --
import_key varchar(14),

View File

@ -149,7 +149,7 @@ SystemToolsAreaDesc=This area provides administration functions. Use the menu to
Purge=Purge
PurgeAreaDesc=This page allows you to delete all files generated or stored by Dolibarr (temporary files or all files in <b>%s</b> directory). Using this feature is not normally necessary. It is provided as a workaround for users whose Dolibarr is hosted by a provider that does not offer permissions to delete files generated by the web server.
PurgeDeleteLogFile=Delete log files, including <b>%s</b> defined for Syslog module (no risk of losing data)
PurgeDeleteTemporaryFiles=Delete all temporary files (no risk of losing data)
PurgeDeleteTemporaryFiles=Delete all temporary files (no risk of losing data). Note: Deletion is done only if the temp directory was created 24 hours ago.
PurgeDeleteTemporaryFilesShort=Delete temporary files
PurgeDeleteAllFilesInDocumentsDir=Delete all files in directory: <b>%s</b>.<br>This will delete all generated documents related to elements (third parties, invoices etc...), files uploaded into the ECM module, database backup dumps and temporary files.
PurgeRunNow=Purge now
@ -1110,7 +1110,7 @@ AreaForAdminOnly=Setup parameters can be set by <b>administrator users</b> only.
SystemInfoDesc=System information is miscellaneous technical information you get in read only mode and visible for administrators only.
SystemAreaForAdminOnly=This area is available to administrator users only. Dolibarr user permissions cannot change this restriction.
CompanyFundationDesc=Edit the information of the company/entity. Click on "%s" or "%s" button at the bottom of the page.
AccountantDesc=Edit the details of your accountant/bookkeeper
AccountantDesc=If you have an external accountant/bookkeeper, you can edit here its information.
AccountantFileNumber=Accountant code
DisplayDesc=Parameters affecting the look and behaviour of Dolibarr can be modified here.
AvailableModules=Available app/modules

View File

@ -106,13 +106,13 @@ if (empty($reshook))
// Visible
$alwayscheckedmodules=array('barcode','bookmark','categorie','externalrss','fckeditor','geoipmaxmind','gravatar','memcached','syslog','user','webservices'); // Technical module we always want
$alwaysuncheckedmodules=array('dynamicprices','incoterm','loan','multicurrency','paybox','paypal','stripe','google','printing','scanner','skype','workflow'); // Module we dont want by default
$alwaysuncheckedmodules=array('dav','dynamicprices','incoterm','loan','multicurrency','paybox','paypal','stripe','google','printing','scanner','skype','takepos','workflow','website'); // Module we dont want by default
// Not visible
$alwayshiddencheckedmodules=array('accounting','api','barcode','blockedlog','bookmark','clicktodial','comptabilite','cron','document','domain','externalrss','externalsite','fckeditor','geoipmaxmind','gravatar','label','ldap',
'mailmanspip','notification','oauth','syslog','user','webservices',
// Extended modules
'memcached','numberwords','zipautofillfr');
$alwayshiddenuncheckedmodules=array('ftp','hrm','webservicesclient','websites',
$alwayshiddenuncheckedmodules=array('debugbar','emailcollector','ftp','hrm','modulebuilder','webservicesclient','websites',
// Extended modules
'awstats','bittorrent','bootstrap','cabinetmed','cmcic','concatpdf','customfield','deplacement','dolicloud','filemanager','lightbox','mantis','monitoring','moretemplates','multicompany','nltechno','numberingpack','openstreetmap',
'ovh','phenix','phpsysinfo','pibarcode','postnuke','selectbank','skincoloreditor','submiteverywhere','survey','thomsonphonebook','topten','tvacerfa','voyage','webcalendar','webmail');

View File

@ -135,7 +135,7 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase
$localobject->initAsSpecimen();
$result=$localobject->create($user);
$this->assertLessThan($result, 0);
$this->assertLessThan($result, 0, $localobject->errorsToString());
print __METHOD__." result=".$result."\n";
return $result;
}
@ -160,7 +160,7 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase
$localobject=new FactureFournisseur($this->savdb);
$result=$localobject->fetch($id);
$this->assertLessThan($result, 0);
$this->assertLessThan($result, 0, $localobject->errorsToString());
print __METHOD__." id=".$id." result=".$result."\n";
return $localobject;
}
@ -186,7 +186,7 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase
$result=$localobject->update($user);
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
$this->assertLessThan($result, 0, $localobject->errorsToString());
return $localobject;
}
@ -210,7 +210,7 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase
$result=$localobject->validate($user);
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
$this->assertLessThan($result, 0, $localobject->errorsToString());
return $localobject;
}
@ -265,7 +265,7 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase
$result=$localobject->delete($user);
print __METHOD__." id=".$id." result=".$result."\n";
$this->assertLessThan($result, 0);
$this->assertLessThan($result, 0, $localobject->errorsToString());
return $result;
}
}