Browse Source

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

Conflicts:
	htdocs/accountancy/bookkeeping/balance.php
	htdocs/install/repair.php
Laurent Destailleur 5 years ago
parent
commit
a5f7211730

+ 7 - 7
htdocs/accountancy/bookkeeping/balance.php

@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2016       Olivier Geffroy         <jeff@jeffinfo.com>
  * Copyright (C) 2016       Florian Henry           <florian.henry@open-concept.pro>
- * Copyright (C) 2016-2018  Alexandre Spangaro      <aspangaro@open-dsi.fr>
+ * Copyright (C) 2016-2019  Alexandre Spangaro      <aspangaro@open-dsi.fr>
  * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -164,7 +164,7 @@ if ($action == 'export_csv')
 		print $object->get_compte_desc($line->numero_compte) . $sep;
 		print price($line->debit) . $sep;
 		print price($line->credit) . $sep;
-		print price($line->credit - $line->debit) . $sep;
+		print price($line->debit - $line->credit) . $sep;
 		print "\n";
 	}
 
@@ -293,9 +293,9 @@ if ($action != 'export_csv')
 
 		print '<td>' . length_accountg($line->numero_compte) . '</td>';
 		print '<td>' . $description . '</td>';
-		print '<td class="right">' . price($line->debit) . '</td>';
-		print '<td class="right">' . price($line->credit) . '</td>';
-		print '<td class="right">' . price($line->credit - $line->debit) . '</td>';
+		print '<td class="nowraponall right">' . price($line->debit) . '</td>';
+		print '<td class="nowraponall right">' . price($line->credit) . '</td>';
+		print '<td class="nowraponall right">' . price($line->debit - $line->credit) . '</td>';
 		print '<td class="center">' . $link;
 		print '</td>';
 		print "</tr>\n";
@@ -305,11 +305,11 @@ if ($action != 'export_csv')
 		$sous_total_credit += $line->credit;
 	}
 
-	print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap right">' . price($sous_total_debit) . '</td><td class="nowrap right">' . price($sous_total_credit) . '</td><td class="nowrap right">' . price(price2num($sous_total_credit - $sous_total_debit)) . '</td>';
+	print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap right">' . price($sous_total_debit) . '</td><td class="nowrap right">' . price($sous_total_credit) . '</td><td class="nowrap right">' . price(price2num($sous_total_debit - $sous_total_credit)) . '</td>';
 	print "<td>&nbsp;</td>\n";
 	print '</tr>';
 
-	print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap right">' . price($total_debit) . '</td><td class="nowrap right">' . price($total_credit) . '</td><td class="nowrap right">' . price(price2num($total_credit - $total_debit)) . '</td>';
+	print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap right">' . price($total_debit) . '</td><td class="nowrap right">' . price($total_credit) . '</td><td class="nowrap right">' . price(price2num($total_debit - $total_credit)) . '</td>';
 	print "<td>&nbsp;</td>\n";
 	print '</tr>';
 

+ 1 - 1
htdocs/comm/mailing/card.php

@@ -835,7 +835,7 @@ else
 				{
 					// EMailing feature may be a spam problem, so when you host several users/instance, having this option may force each user to use their own SMTP agent.
 					// You ensure that every user is using its own SMTP server when using the mass emailing module.
-					$linktoadminemailbefore='<a href="'.DOL_URL_ROOT.'/admin/mails.php">';
+					$linktoadminemailbefore='<a href="'.DOL_URL_ROOT.'/admin/mails_emailing.php">';
 					$linktoadminemailend='</a>';
 					setEventMessages($langs->trans("MailSendSetupIs", $listofmethods[$sendingmode]), null, 'warnings');
 					setEventMessages($langs->trans("MailSendSetupIs2", $linktoadminemailbefore, $linktoadminemailend, $langs->transnoentitiesnoconv("MAIN_MAIL_SENDMODE"), $listofmethods['smtps']), null, 'warnings');

+ 9 - 0
htdocs/core/class/html.form.class.php

@@ -1903,6 +1903,15 @@ class Form
 		$price_level = (! empty($price_level) ? $price_level : 0);
 		if (is_null($ajaxoptions)) $ajaxoptions=array();
 
+		if(strval($filtertype) === '' && (!empty($conf->product->enabled) || !empty($conf->service->enabled))){
+			if(!empty($conf->product->enabled) && empty($conf->service->enabled)){
+				$filtertype = '0';
+			}
+			elseif(empty($conf->product->enabled) && !empty($conf->service->enabled)){
+				$filtertype = '1';
+			}
+		}
+
 		if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
 		{
 			$placeholder='';

+ 139 - 0
htdocs/install/repair.php

@@ -78,6 +78,7 @@ print 'Option rebuild_product_thumbs (\'test\' or \'confirmed\') is '.(GETPOST('
 print 'Option force_disable_of_modules_not_found (\'test\' or \'confirmed\') is '.(GETPOST('force_disable_of_modules_not_found', 'alpha')?GETPOST('force_disable_of_modules_not_found', 'alpha'):'undefined').'<br>'."\n";
 print 'Option clean_perm_table (\'test\' or \'confirmed\') is '.(GETPOST('clean_perm_table', 'alpha')?GETPOST('clean_perm_table', 'alpha'):'undefined').'<br>'."\n";
 print 'Option force_utf8_on_tables, for mysql/mariadb only (\'test\' or \'confirmed\') is '.(GETPOST('force_utf8_on_tables', 'alpha')?GETPOST('force_utf8_on_tables', 'alpha'):'undefined').'<br>'."\n";
+print 'Option repair_link_dispatch_lines_supplier_order_lines, (\'test\' or \'confirmed\') is '.(GETPOST('repair_link_dispatch_lines_supplier_order_lines','alpha')?GETPOST('repair_link_dispatch_lines_supplier_order_lines','alpha'):'undefined').'<br>'."\n";
 print '<br>';
 
 print '<table cellspacing="0" cellpadding="1" border="0" width="100%">';
@@ -1275,6 +1276,144 @@ if ($ok && GETPOST('force_utf8_on_tables', 'alpha'))
     }
 }
 
+//
+if ($ok && GETPOST('repair_link_dispatch_lines_supplier_order_lines')) {
+    /*
+     * This script is meant to be run when upgrading from a dolibarr version < 3.8
+     * to a newer version.
+     *
+     * Version 3.8 introduces a new column in llx_commande_fournisseur_dispatch, which
+     * matches the dispatch to a specific supplier order line (so that if there are
+     * several with the same product, the user can specifically tell which products of
+     * which line were dispatched where).
+     *
+     * However when migrating, the new column has a default value of 0, which means that
+     * old supplier orders whose lines were dispatched using the old dolibarr version
+     * have unspecific dispatch lines, which are not taken into account by the new version,
+     * thus making the order look like it was never dispatched at all.
+     *
+     * This scripts sets this foreign key to the first matching supplier order line whose
+     * product (and supplier order of course) are the same as the dispatch’s.
+     *
+     * If the dispatched quantity is more than indicated on the order line (this happens if
+     * there are several order lines for the same product), it creates new dispatch lines
+     * pointing to the other order lines accordingly, until all the dispatched quantity is
+     * accounted for.
+     */
+
+	$repair_link_dispatch_lines_supplier_order_lines = GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha');
+
+
+    echo '<tr><th>Repair llx_commande_fournisseur_dispatch.fk_commandefourndet</th></tr>';
+    echo '<tr><td>Repair in progress. This may take a while.</td></tr>';
+
+    $sql_dispatch = 'SELECT * FROM ' . MAIN_DB_PREFIX . 'commande_fournisseur_dispatch WHERE COALESCE(fk_commandefourndet, 0) = 0';
+    $db->begin();
+    $resql_dispatch = $db->query($sql_dispatch);
+    $n_processed_rows = 0;
+    $errors = array();
+    if ($resql_dispatch) {
+        if ($db->num_rows($resql_dispatch) == 0) {
+            echo '<tr><td>Nothing to do.</td></tr>';
+            exit;
+        }
+        while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
+            $sql_line = 'SELECT line.rowid, line.qty FROM ' . MAIN_DB_PREFIX . 'commande_fournisseurdet AS line'
+                .       ' WHERE line.fk_commande = ' . $obj_dispatch->fk_commande
+                .       ' AND   line.fk_product  = ' . $obj_dispatch->fk_product;
+            $resql_line = $db->query($sql_line);
+
+            // s’il y a plusieurs lignes avec le même produit sur cette commande fournisseur,
+            // on divise la ligne de dispatch en autant de lignes qu’on en a sur la commande pour le produit
+            // et on met la quantité de la ligne dans la limite du "budget" indiqué par dispatch.qty
+
+            $remaining_qty = $obj_dispatch->qty;
+            $first_iteration = true;
+            if (!$resql_line) {
+                echo '<tr><td>Unable to find a matching supplier order line for dispatch #' . $obj_dispatch->rowid . '</td></tr>';
+                $errors[] = $sql_line;
+                $n_processed_rows++;
+                continue;
+            }
+            if ($db->num_rows($resql_line) == 0) continue;
+            while ($obj_line = $db->fetch_object($resql_line)) {
+                if (!$remaining_qty) break;
+                if (!$obj_line->rowid) {
+                    continue;
+                }
+                $qty_for_line = min($remaining_qty, $obj_line->qty);
+                if ($first_iteration) {
+                    $sql_attach = 'UPDATE ' . MAIN_DB_PREFIX . 'commande_fournisseur_dispatch'
+                        .        ' SET fk_commandefourndet = ' . $obj_line->rowid . ', qty = ' . $qty_for_line
+                        .        ' WHERE rowid = ' . $obj_dispatch->rowid;
+                    $first_iteration = false;
+                } else {
+                    $sql_attach_values = array(
+                        $obj_dispatch->fk_commande,
+                        $obj_dispatch->fk_product,
+                        $obj_line->rowid,
+                        $qty_for_line,
+                        $obj_dispatch->fk_entrepot,
+                        $obj_dispatch->fk_user,
+                        $obj_dispatch->datec ? '"' . $db->escape($obj_dispatch->datec) . '"' : 'NULL',
+                        $obj_dispatch->comment ? '"' . $db->escape($obj_dispatch->comment) . '"' : 'NULL',
+                        $obj_dispatch->status ?: 'NULL',
+                        $obj_dispatch->tms ? '"' . $db->escape($obj_dispatch->tms) . '"': 'NULL',
+                        $obj_dispatch->batch ?: 'NULL',
+                        $obj_dispatch->eatby ? '"' . $db->escape($obj_dispatch->eatby) . '"': 'NULL',
+                        $obj_dispatch->sellby ? '"' . $db->escape($obj_dispatch->sellby) . '"': 'NULL'
+                    );
+                    $sql_attach_values = join(', ', $sql_attach_values);
+
+                    $sql_attach = 'INSERT INTO ' . MAIN_DB_PREFIX . 'commande_fournisseur_dispatch'
+                        .         ' (fk_commande, fk_product, fk_commandefourndet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)'
+                        .         ' VALUES (' . $sql_attach_values . ')';
+                }
+
+                if ($repair_link_dispatch_lines_supplier_order_lines == 'confirmed')
+                {
+	                $resql_attach = $db->query($sql_attach);
+                }
+                else
+                {
+                	$resql_attach = true;	// Force success in test mode
+                }
+
+                if ($resql_attach) {
+                    $remaining_qty -= $qty_for_line;
+                } else {
+                    $errors[] = $sql_attach;
+                }
+
+                $first_iteration = false;
+            }
+            $n_processed_rows++;
+
+            // report progress every 256th row
+            if (!($n_processed_rows & 0xff)) {
+                echo '<tr><td>Processed ' . $n_processed_rows . ' rows with ' . count($errors) . ' errors…' . "</td></tr>\n";
+                flush();
+                ob_flush();
+            }
+        }
+    } else {
+        echo '<tr><td>Unable to find any dispatch without an fk_commandefourndet.' . "</td></tr>\n";
+        echo $sql_dispatch . "\n";
+    }
+    echo '<tr><td>Fixed ' . $n_processed_rows . ' rows with ' . count($errors) . ' errors…' . "</td></tr>\n";
+    echo '<tr><td>DONE.' . "</td></tr>\n";
+
+    if (count($errors)) {
+        $db->rollback();
+        echo '<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
+    } else {
+        $db->commit();
+    }
+    $db->close();
+
+    echo '<tr><td><h3>SQL queries with errors:</h3></tr></td>';
+    echo '<tr><td>' . join('</td></tr><tr><td>', $errors) . '</td></tr>';
+}
 
 print '</table>';
 

+ 1 - 1
htdocs/product/class/product.class.php

@@ -447,7 +447,7 @@ class Product extends CommonObject
             $error=0;
 
         // Clean parameters
-        $this->ref = dol_string_nospecial(trim($this->ref));
+        $this->ref = dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)));
         $this->label = trim($this->label);
         $this->price_ttc=price2num($this->price_ttc);
         $this->price=price2num($this->price);