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

Conflicts:
	htdocs/filefunc.inc.php
This commit is contained in:
Laurent Destailleur 2017-04-06 21:59:11 +02:00
commit f598bf8bef
12 changed files with 216 additions and 58 deletions

View File

@ -187,6 +187,42 @@ Dolibarr 5.0 was frozen before PHP 7.1 was released. Unit tests are successful o
feedback to confirm all application is compatible. Current officiel supported PHP versions are PHP 5.3 to 7.0. feedback to confirm all application is compatible. Current officiel supported PHP versions are PHP 5.3 to 7.0.
***** ChangeLog for 4.0.5 to 4.0.4 *****
FIX: #6234
FIX: #6259
FIX: #6330
FIX: #6360
FIX: #6411
FIX: #6443
FIX: #6444
FIX: #6453
FIX: #6503: SQL error in "Last pending payment invoices"
FIX: #6505 Project elements page shows greyed-out links even if the option to show actions not available is disabled
FIX: #6507: Statistics counter show wrong total Contract numbers when the user does not have full access
FIX: #6533 #6590
FIX: #6619 Template invoices list do not respect restricted thirdparty user rights
FIX: #6621 Documents tab shows greyed out upload form even if the option to show actions not available is disabled
FIX: add entity param to document link
FIX: Can use quote into supplier ref on order line add
FIX: Change the customer code only if error on duplicate
FIX: Creation of credit note on invoice with deposit stole the discount.
FIX: delete bank class lines when we delete bank_categ
FIX: deletion of bank tag
FIX: detail of deposit and credit not was not visible into final invoice
FIX: Error management during bank account creation
FIX: error management in bank account deletion.
FIX: event status is not modified when assign an user
FIX: forgotten fk_facture_fourn attribute on supplierinvoice line object
FIX: If bank module on, field must be required to register payment of expense report.
FIX: load multicurrency informations on supplier order and bill lines fetch
FIX: Missing total on project overview.
FIX: multicurrency_subprice
FIX: param billed when we change page
FIX: protection against infinite loop on hierarchy
FIX: Supplier Order list filter by project
FIX: the dolCopyDir fails if target dir does not exists.
FIX: use param for http links
***** ChangeLog for 4.0.4 to 4.0.3 ***** ***** ChangeLog for 4.0.4 to 4.0.3 *****
FIX: #6227 Document models table header "Unit" is shown in 2 lines in Spanish FIX: #6227 Document models table header "Unit" is shown in 2 lines in Spanish
FIX: #6230 FIX: #6230

View File

@ -638,7 +638,7 @@ if (! empty($conf->banque->enabled))
$sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account";
$sql.= " WHERE clos = 0"; $sql.= " WHERE clos = 0";
$sql.= " AND courant = 1"; $sql.= " AND courant = 1";
$sql.= " AND entity IN (".getEntity('bank', 1).")"; $sql.= " AND entity IN (".getEntity('bank_account', 1).")";
$resql=$db->query($sql); $resql=$db->query($sql);
if ($resql) if ($resql)
{ {
@ -683,7 +683,7 @@ $sql = "SELECT rowid, label";
$sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account";
$sql.= " WHERE clos = 0"; $sql.= " WHERE clos = 0";
$sql.= " AND courant = 1"; $sql.= " AND courant = 1";
$sql.= " AND entity IN (".getEntity('bank', 1).")"; $sql.= " AND entity IN (".getEntity('bank_account', 1).")";
$var=True; $var=True;
$resql=$db->query($sql); $resql=$db->query($sql);
if ($resql) if ($resql)

View File

@ -80,7 +80,7 @@ if ($categid) {
llxHeader(); llxHeader();
print load_fiche_titre($langs->trans("Rubriques"), '', 'title_bank.png'); print load_fiche_titre($langs->trans("RubriquesTransactions"), '', 'title_bank.png');
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';

View File

@ -1540,8 +1540,14 @@ else
$sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre, f.total, f.tva as total_vat, f.total_ttc, f.frequency,"; $sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre, f.total, f.tva as total_vat, f.total_ttc, f.frequency,";
$sql.= " f.date_last_gen, f.date_when"; $sql.= " f.date_last_gen, f.date_when";
$sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f";
if (! $user->rights->societe->client->voir && ! $socid) {
$sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
}
$sql.= " WHERE f.fk_soc = s.rowid"; $sql.= " WHERE f.fk_soc = s.rowid";
$sql.= " AND f.entity = ".$conf->entity; $sql.= " AND f.entity = ".$conf->entity;
if (! $user->rights->societe->client->voir && ! $socid) {
$sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
}
if ($search_ref) $sql .= natural_search('f.titre', $search_ref); if ($search_ref) $sql .= natural_search('f.titre', $search_ref);
if ($search_societe) $sql .= natural_search('s.nom', $search_societe); if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
if ($search_frequency) $sql .= natural_search('f.frequency', $search_frequency); if ($search_frequency) $sql .= natural_search('f.frequency', $search_frequency);

View File

@ -55,7 +55,6 @@ class CMailFile
var $eol; var $eol;
var $eol2; var $eol2;
var $atleastonefile=0;
var $error=''; var $error='';
var $smtps; // Contains SMTPs object (if this method is used) var $smtps; // Contains SMTPs object (if this method is used)
@ -74,7 +73,7 @@ class CMailFile
// Image // Image
var $html; var $html;
var $image_boundary; var $image_boundary;
var $atleastoneimage=0; var $atleastoneimage=0; // at least one image file with file=xxx.ext into content (TODO Debug this. How can this case be tested. Remove if not used).
var $html_images=array(); var $html_images=array();
var $images_encoded=array(); var $images_encoded=array();
var $image_types = array('gif' => 'image/gif', var $image_types = array('gif' => 'image/gif',
@ -108,7 +107,7 @@ class CMailFile
*/ */
function __construct($subject,$to,$from,$msg,$filename_list=array(),$mimetype_list=array(),$mimefilename_list=array(),$addr_cc="",$addr_bcc="",$deliveryreceipt=0,$msgishtml=0,$errors_to='',$css='',$trackid='',$moreinheader='') function __construct($subject,$to,$from,$msg,$filename_list=array(),$mimetype_list=array(),$mimefilename_list=array(),$addr_cc="",$addr_bcc="",$deliveryreceipt=0,$msgishtml=0,$errors_to='',$css='',$trackid='',$moreinheader='')
{ {
global $conf; global $conf, $dolibarr_main_data_root;
// We define end of line (RFC 821). // We define end of line (RFC 821).
$this->eol="\r\n"; $this->eol="\r\n";
@ -160,7 +159,11 @@ class CMailFile
if ($this->msgishtml) if ($this->msgishtml)
{ {
$this->html = $msg; $this->html = $msg;
$findimg = $this->findHtmlImages($conf->fckeditor->dir_output);
if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS))
{
$findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias');
}
// Define if there is at least one file // Define if there is at least one file
if ($findimg) if ($findimg)
@ -231,17 +234,6 @@ class CMailFile
// Define body in text_body // Define body in text_body
$text_body = $this->write_body($msg); $text_body = $this->write_body($msg);
// Encode images
$images_encoded = '';
if ($this->atleastoneimage)
{
$images_encoded.= $this->write_images($this->images_encoded);
// always end related and end alternative after inline images
$images_encoded.= "--" . $this->related_boundary . "--" . $this->eol;
$images_encoded.= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol;
$images_encoded.= $this->eol;
}
// Add attachments to text_encoded // Add attachments to text_encoded
if ($this->atleastonefile) if ($this->atleastonefile)
{ {
@ -255,8 +247,8 @@ class CMailFile
// comme des injections mail par les serveurs de messagerie. // comme des injections mail par les serveurs de messagerie.
$this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers); $this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers);
$this->message = 'This is a message with multiple parts in MIME format.'.$this->eol; $this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol;
$this->message.= $text_body . $images_encoded . $files_encoded; $this->message.= $text_body . $files_encoded;
$this->message.= "--" . $this->mixed_boundary . "--" . $this->eol; $this->message.= "--" . $this->mixed_boundary . "--" . $this->eol;
} }
else if ($conf->global->MAIN_MAIL_SENDMODE == 'smtps') else if ($conf->global->MAIN_MAIL_SENDMODE == 'smtps')
@ -973,23 +965,23 @@ class CMailFile
$out.= "--" . $this->alternative_boundary . $this->eol; $out.= "--" . $this->alternative_boundary . $this->eol;
} }
if ($this->msgishtml)
{
// Check if html header already in message
$strContent = $this->checkIfHTML($msgtext);
}
else
{
$strContent = $msgtext;
}
// Make RFC821 Compliant, replace bare linefeeds // Make RFC821 Compliant, replace bare linefeeds
$strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent); $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $msgtext);
if (! empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)) if (! empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA))
{ {
$strContent = preg_replace("/\r\n/si", "\n", $strContent); $strContent = preg_replace("/\r\n/si", "\n", $strContent);
} }
$strContentAltText = '';
if ($this->msgishtml)
{
$strContentAltText = html_entity_decode(strip_tags($strContent));
$strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n"));
// Check if html header already in message, if not complete the message
$strContent = $this->checkIfHTML($strContent);
}
// Make RFC2045 Compliant, split lines // Make RFC2045 Compliant, split lines
//$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content
$strContent = rtrim(wordwrap($strContent)); // TODO Using this method creates unexpected line break on text/plain content. $strContent = rtrim(wordwrap($strContent)); // TODO Using this method creates unexpected line break on text/plain content.
@ -999,14 +991,30 @@ class CMailFile
if ($this->atleastoneimage) if ($this->atleastoneimage)
{ {
$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
$out.= $this->eol.strip_tags($strContent).$this->eol; // Add plain text message $out.= $this->eol.($strContentAltText?$strContentAltText:strip_tags($strContent)).$this->eol; // Add plain text message
$out.= "--" . $this->alternative_boundary . $this->eol; $out.= "--" . $this->alternative_boundary . $this->eol;
$out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol; $out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol;
$out.= $this->eol; $out.= $this->eol;
$out.= "--" . $this->related_boundary . $this->eol; $out.= "--" . $this->related_boundary . $this->eol;
} }
if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part
{
$out.= "Content-Type: multipart/alternative; boundary=\"".$this->alternative_boundary."\"".$this->eol;
$out.= $this->eol;
$out.= "--" . $this->alternative_boundary . $this->eol;
$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
$out.= $this->eol.$strContentAltText.$this->eol;
$out.= "--" . $this->alternative_boundary . $this->eol;
}
$out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol; $out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol;
$out.= $this->eol.$strContent.$this->eol; $out.= $this->eol.$strContent.$this->eol;
if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part
{
$out.= "--" . $this->alternative_boundary . "--". $this->eol;
}
} }
else else
{ {
@ -1016,6 +1024,16 @@ class CMailFile
$out.= $this->eol; $out.= $this->eol;
// Encode images
if ($this->atleastoneimage)
{
$out .= $this->write_images($this->images_encoded);
// always end related and end alternative after inline images
$out .= "--" . $this->related_boundary . "--" . $this->eol;
$out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol;
$out .= $this->eol;
}
return $out; return $out;
} }
@ -1184,14 +1202,15 @@ class CMailFile
$extensions = array_keys($this->image_types); $extensions = array_keys($this->image_types);
preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); // If "xxx.ext" or 'xxx.ext' found
if ($matches) if ($matches)
{ {
$i=0; $i=0;
foreach ($matches[1] as $full) foreach ($matches[1] as $full)
{ {
if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs))
if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) // If xxx is 'file=aaa'
{ {
$img = $regs[1]; $img = $regs[1];

View File

@ -89,6 +89,11 @@ class FormFile
} }
else else
{ {
//If there is no permission and the option to hide unauthorized actions is enabled, then nothing is printed
if (!$perm && !empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) {
return 1;
}
$maxlength=$size; $maxlength=$size;
$out = "\n\n<!-- Start form attach new file -->\n"; $out = "\n\n<!-- Start form attach new file -->\n";

View File

@ -1304,6 +1304,13 @@ class SMTPs
// Make RFC821 Compliant, replace bare linefeeds // Make RFC821 Compliant, replace bare linefeeds
$strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent); $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent);
$strContentAltText = '';
if ($strType == 'html')
{
$strContentAltText = html_entity_decode(strip_tags($strContent));
$strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n"));
}
// Make RFC2045 Compliant // Make RFC2045 Compliant
//$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content
$strContent = rtrim(wordwrap($strContent, 75, "\r\n")); // TODO Using this method creates unexpected line break on text/plain content. $strContent = rtrim(wordwrap($strContent, 75, "\r\n")); // TODO Using this method creates unexpected line break on text/plain content.
@ -1312,6 +1319,7 @@ class SMTPs
$this->_msgContent[$strType]['mimeType'] = $strMimeType; $this->_msgContent[$strType]['mimeType'] = $strMimeType;
$this->_msgContent[$strType]['data'] = $strContent; $this->_msgContent[$strType]['data'] = $strContent;
$this->_msgContent[$strType]['dataText'] = $strContentAltText;
if ( $this->getMD5flag() ) if ( $this->getMD5flag() )
$this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3); $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3);
@ -1325,6 +1333,8 @@ class SMTPs
*/ */
function getBodyContent() function getBodyContent()
{ {
global $conf;
// Generate a new Boundary string // Generate a new Boundary string
$this->_setBoundary(); $this->_setBoundary();
@ -1339,7 +1349,7 @@ class SMTPs
die ("Sorry, no content"); die ("Sorry, no content");
// If we have ONE, we can use the simple format // If we have ONE, we can use the simple format
else if( $keyCount === 1 ) else if( $keyCount === 1 && empty($conf->global->MAIN_MAIL_USE_MULTI_PART))
{ {
$_msgData = $this->_msgContent; $_msgData = $this->_msgContent;
$_msgData = $_msgData[$_types[0]]; $_msgData = $_msgData[$_types[0]];
@ -1357,7 +1367,7 @@ class SMTPs
} }
// If we have more than ONE, we use the multi-part format // If we have more than ONE, we use the multi-part format
else if( $keyCount > 1 ) else if( $keyCount >= 1 || ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))
{ {
// Since this is an actual multi-part message // Since this is an actual multi-part message
// We need to define a content message Boundary // We need to define a content message Boundary
@ -1373,13 +1383,17 @@ class SMTPs
$content .= "--" . $this->_getBoundary('mixed') . "\r\n"; $content .= "--" . $this->_getBoundary('mixed') . "\r\n";
if (key_exists('image', $this->_msgContent)) if (key_exists('image', $this->_msgContent)) // If inline image found
{ {
$content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n"; $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n";
$content .= "\r\n"; $content .= "\r\n";
$content .= "--" . $this->_getBoundary('alternative') . "\r\n"; $content .= "--" . $this->_getBoundary('alternative') . "\r\n";
} }
// $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment'
// Loop through message content array // Loop through message content array
foreach ($this->_msgContent as $type => $_content ) foreach ($this->_msgContent as $type => $_content )
{ {
@ -1430,13 +1444,24 @@ class SMTPs
if (key_exists('image', $this->_msgContent)) if (key_exists('image', $this->_msgContent))
{ {
$content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n"; $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n";
$content.= "\r\n" . strip_tags($_content['data']) . "\r\n"; // Add plain text message $content.= "\r\n" . ($_content['dataText']?$_content['dataText']:strip_tags($_content['data'])) . "\r\n"; // Add plain text message
$content.= "--" . $this->_getBoundary('alternative') . "\r\n"; $content.= "--" . $this->_getBoundary('alternative') . "\r\n";
$content.= 'Content-Type: multipart/related; boundary="' . $this->_getBoundary('related') . '"' . "\r\n"; $content.= 'Content-Type: multipart/related; boundary="' . $this->_getBoundary('related') . '"' . "\r\n";
$content.= "\r\n"; $content.= "\r\n";
$content.= "--" . $this->_getBoundary('related') . "\r\n"; $content.= "--" . $this->_getBoundary('related') . "\r\n";
} }
if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part
{
$content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n";
$content .= "\r\n";
$content .= "--" . $this->_getBoundary('alternative') . "\r\n";
$content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n";
$content.= "\r\n". $_content['dataText'] . "\r\n";
$content.= "--" . $this->_getBoundary('alternative') . "\r\n";
}
$content .= 'Content-Type: ' . $_content['mimeType'] . '; ' $content .= 'Content-Type: ' . $_content['mimeType'] . '; '
// . 'charset="' . $this->getCharSet() . '"'; // . 'charset="' . $this->getCharSet() . '"';
. 'charset=' . $this->getCharSet() . ''; . 'charset=' . $this->getCharSet() . '';
@ -1452,7 +1477,14 @@ class SMTPs
if ( $this->getMD5flag() ) if ( $this->getMD5flag() )
$content .= 'Content-MD5: ' . $_content['md5'] . "\r\n"; $content .= 'Content-MD5: ' . $_content['md5'] . "\r\n";
$content .= "\r\n" . $_content['data'] . "\r\n\r\n"; $content .= "\r\n" . $_content['data'] . "\r\n";
if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part
{
$content.= "--" . $this->_getBoundary('alternative') . "--". "\r\n";
}
$content .= "\r\n";
} }
} }

View File

@ -1156,10 +1156,11 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
if (! empty($conf->categorie->enabled)) { if (! empty($conf->categorie->enabled)) {
$langs->load("categories"); $langs->load("categories");
//$newmenu->add("/compta/bank/categ.php",$langs->trans("Rubriques"),1,$user->rights->banque->configurer);
$newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags'); $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags');
$newmenu->add("/categories/card.php?action=create&amp;type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer); $newmenu->add("/categories/card.php?action=create&amp;type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer);
} $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags');
$newmenu->add("/compta/bank/categ.php",$langs->trans("NewCategory"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags');
}
// Prelevements // Prelevements
if (! empty($conf->prelevement->enabled)) if (! empty($conf->prelevement->enabled))

View File

@ -76,6 +76,7 @@ print 'Option restore_thirdparties_logos is '.(GETPOST('restore_thirdparties_log
print 'Option clean_linked_elements is '.(GETPOST('clean_linked_elements')?GETPOST('clean_linked_elements'):'0').'<br>'."\n"; print 'Option clean_linked_elements is '.(GETPOST('clean_linked_elements')?GETPOST('clean_linked_elements'):'0').'<br>'."\n";
print 'Option clean_orphelin_dir (1 or confirmed) is '.(GETPOST('clean_orphelin_dir')?GETPOST('clean_orphelin_dir'):'0').'<br>'."\n"; print 'Option clean_orphelin_dir (1 or confirmed) is '.(GETPOST('clean_orphelin_dir')?GETPOST('clean_orphelin_dir'):'0').'<br>'."\n";
print 'Option clean_product_stock_batch (1 or confirmed) is '.(GETPOST('clean_product_stock_batch')?GETPOST('clean_product_stock_batch'):'0').'<br>'."\n"; print 'Option clean_product_stock_batch (1 or confirmed) is '.(GETPOST('clean_product_stock_batch')?GETPOST('clean_product_stock_batch'):'0').'<br>'."\n";
print 'Option set_empty_time_spent_amount (1 or confirmed) is '.(GETPOST('set_empty_time_spent_amount')?GETPOST('set_empty_time_spent_amount'):'0').'<br>'."\n";
print '<br>'; print '<br>';
print '<table cellspacing="0" cellpadding="1" border="0" width="100%">'; print '<table cellspacing="0" cellpadding="1" border="0" width="100%">';
@ -151,7 +152,7 @@ if ($ok)
} }
// Show wait message // Show wait message
print '<tr><td colspan="2">'.$langs->trans("PleaseBePatient").'</td></tr>'; print '<tr><td colspan="2">'.$langs->trans("PleaseBePatient").'<br><br></td></tr>';
flush(); flush();
@ -190,7 +191,7 @@ if ($ok)
// Loop on each file // Loop on each file
foreach($filelist as $file) foreach($filelist as $file)
{ {
print '<tr><td class="nowrap">'; print '<tr><td class="nowrap">*** ';
print $langs->trans("Script").'</td><td align="right">'.$file.'</td></tr>'; print $langs->trans("Script").'</td><td align="right">'.$file.'</td></tr>';
$name = substr($file, 0, dol_strlen($file) - 4); $name = substr($file, 0, dol_strlen($file) - 4);
@ -210,7 +211,7 @@ if ($ok)
'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture',
'commande_fournisseur'=>'commande_fournisseur', 'actioncomm'=>'actioncomm', 'commande_fournisseur'=>'commande_fournisseur', 'actioncomm'=>'actioncomm',
'adherent_type'=>'adherent_type','user'=>'user','projet'=>'projet', 'projet_task'=>'projet_task'); 'adherent_type'=>'adherent_type','user'=>'user','projet'=>'projet', 'projet_task'=>'projet_task');
print '<tr><td colspan="2"><br>Check fields into extra table structure match table of definition. If not add column into table</td></tr>'; print '<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
foreach($listofmodulesextra as $tablename => $elementtype) foreach($listofmodulesextra as $tablename => $elementtype)
{ {
// Get list of fields // Get list of fields
@ -324,7 +325,7 @@ if ($ok && GETPOST('restore_thirdparties_logos'))
$ext=''; $ext='';
print '<tr><td colspan="2"><br>'; print '<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
//foreach($exts as $ext) //foreach($exts as $ext)
//{ //{
$sql="SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX."societe as s ORDER BY s.nom"; $sql="SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX."societe as s ORDER BY s.nom";
@ -395,7 +396,7 @@ if ($ok && GETPOST('restore_thirdparties_logos'))
// clean_linked_elements: Check and clean linked elements // clean_linked_elements: Check and clean linked elements
if ($ok && GETPOST('clean_linked_elements')) if ($ok && GETPOST('clean_linked_elements'))
{ {
print '<tr><td colspan="2"><br>Check table of linked elements and delete orphelins links</td></tr>'; print '<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
// propal => order // propal => order
print '<tr><td colspan="2">'.checkLinkedElements('propal', 'commande')."</td></tr>\n"; print '<tr><td colspan="2">'.checkLinkedElements('propal', 'commande')."</td></tr>\n";
@ -435,7 +436,7 @@ if ($ok && GETPOST('clean_orphelin_dir'))
if (empty($upload_dir)) continue; if (empty($upload_dir)) continue;
print '<tr><td colspan="2"><br>Clean orphelins files into files '.$upload_dir.'</td></tr>'; print '<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.'</td></tr>';
$filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','(\.meta|_preview\.png)$','^temp$','^payments$','^CVS$','^thumbs$'),'',SORT_DESC,1,true); $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','(\.meta|_preview\.png)$','^temp$','^payments$','^CVS$','^thumbs$'),'',SORT_DESC,1,true);
@ -546,7 +547,7 @@ if ($ok && GETPOST('clean_orphelin_dir'))
// clean_linked_elements: Check and clean linked elements // clean_linked_elements: Check and clean linked elements
if ($ok && GETPOST('clean_product_stock_batch')) if ($ok && GETPOST('clean_product_stock_batch'))
{ {
print '<tr><td colspan="2"><br>Clean table product_batch</td></tr>'; print '<tr><td colspan="2"><br>*** Clean table product_batch</td></tr>';
$sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch"; $sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
$sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb"; $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb";
@ -636,6 +637,64 @@ if ($ok && GETPOST('clean_product_stock_batch'))
{ {
dol_print_error($db); dol_print_error($db);
} }
}
// clean_linked_elements: Check and clean linked elements
if ($ok && GETPOST('set_empty_time_spent_amount'))
{
print '<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
$sql ="SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
$sql.=" FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."user as u";
$sql.=" WHERE ptt.fk_user = u.rowid";
$sql.=" AND ptt.thm IS NULL and u.thm > 0";
$sql.=" GROUP BY u.rowid, u.login, u.thm";
$resql = $db->query($sql);
if ($resql)
{
$num = $db->num_rows($resql);
if ($num)
{
$i = 0;
while ($i < $num)
{
$obj=$db->fetch_object($resql);
print '<tr><td>'.$obj->login.'-'.$obj->user_id.' ('.$obj->nb.' lines to fix) -> '.$obj->user_thm;
$db->begin();
$sql2 ="UPDATE ".MAIN_DB_PREFIX."projet_task_time";
$sql2.=" SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".$obj->user_id;
$resql2=$db->query($sql2);
if (! $resql2)
{
$error++;
dol_print_error($db);
}
if (!$error) $db->commit();
else $db->rollback();
print'</td></tr>';
if ($error) break;
$i++;
}
}
else
{
print '<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
}
}
else
{
dol_print_error($db);
}
} }
@ -643,7 +702,6 @@ if ($ok && GETPOST('clean_product_stock_batch'))
print '</table>'; print '</table>';

View File

@ -213,7 +213,7 @@ MainDbPasswordFileConfEncrypted=Database password encrypted in conf.php (Activat
InstrucToEncodePass=To have password encoded into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="...";</b><br>by<br><b>$dolibarr_main_db_pass="crypted:%s";</b> InstrucToEncodePass=To have password encoded into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="...";</b><br>by<br><b>$dolibarr_main_db_pass="crypted:%s";</b>
InstrucToClearPass=To have password decoded (clear) into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="crypted:...";</b><br>by<br><b>$dolibarr_main_db_pass="%s";</b> InstrucToClearPass=To have password decoded (clear) into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="crypted:...";</b><br>by<br><b>$dolibarr_main_db_pass="%s";</b>
ProtectAndEncryptPdfFiles=Protection of generated pdf files (Activated NOT recommended, breaks mass pdf generation) ProtectAndEncryptPdfFiles=Protection of generated pdf files (Activated NOT recommended, breaks mass pdf generation)
ProtectAndEncryptPdfFilesDesc=Protection of a PDF document keeps it available to read and print with any PDF browser. However, editing and copying is not possible anymore. Note that using this feature make building of a global cumulated pdf not working (like unpaid invoices). ProtectAndEncryptPdfFilesDesc=Protection of a PDF document keeps it available to read and print with any PDF browser. However, editing and copying is not possible anymore. Note that using this feature makes building of a global merged PDFs not working.
Feature=Feature Feature=Feature
DolibarrLicense=License DolibarrLicense=License
Developpers=Developers/contributors Developpers=Developers/contributors

View File

@ -1,6 +1,7 @@
# Dolibarr language file - Source file is en_US - categories # Dolibarr language file - Source file is en_US - categories
Rubrique=Tag/Category Rubrique=Tag/Category
Rubriques=Tags/Categories Rubriques=Tags/Categories
RubriquesTransactions=Tags/Categories of transactions
categories=tags/categories categories=tags/categories
NoCategoryYet=No tag/category of this type created NoCategoryYet=No tag/category of this type created
In=In In=In

View File

@ -176,8 +176,8 @@ class MouvementStock extends CommonObject
if ($this->db->jdate($obj->eatby) != $eatby && $this->db->jdate($obj->eatby) != $eatbywithouthour) // We test date without hours and with hours for backward compatibility if ($this->db->jdate($obj->eatby) != $eatby && $this->db->jdate($obj->eatby) != $eatbywithouthour) // We test date without hours and with hours for backward compatibility
{ {
// If found and eatby/sellby defined into table and provided and differs, return error // If found and eatby/sellby defined into table and provided and differs, return error
$this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)); $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby), 'dayhour'), dol_print_date($eatby, 'dayhour'));
dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)), LOG_ERR); dol_syslog("ThisSerialAlreadyExistWithDifferentDate batch=".$batch.", eatby found into product_lot = ".$obj->eatby." = ".dol_print_date($this->db->jdate($obj->eatby), 'dayhourrfc')." so eatbywithouthour = ".$eatbywithouthour." = ".dol_print_date($eatbywithouthour)." - eatby provided = ".$eatby." = ".dol_print_date($eatby, 'dayhourrfc'), LOG_ERR);
$this->db->rollback(); $this->db->rollback();
return -3; return -3;
} }