diff --git a/htdocs/comm/multiprix.php b/htdocs/comm/multiprix.php
index c4e0df11df2..6d80626242d 100644
--- a/htdocs/comm/multiprix.php
+++ b/htdocs/comm/multiprix.php
@@ -20,7 +20,7 @@
/**
* \file htdocs/comm/multiprix.php
* \ingroup societe
- * \brief Onglet choix du niveau de prix
+ * \brief Tab to set the price level of a thirdparty
*/
require '../main.inc.php';
@@ -64,20 +64,11 @@ $userstatic = new User($db);
if ($_socid > 0)
{
- // On recupere les donnees societes par l'objet
+ // We load data of thirdparty
$objsoc = new Societe($db);
$objsoc->id = $_socid;
$objsoc->fetch($_socid, $to);
- if ($errmesg)
- {
- print '
'.$errmesg.'
';
- }
-
-
- /*
- * Affichage onglets
- */
$head = societe_prepare_head($objsoc);
@@ -91,7 +82,7 @@ if ($_socid > 0)
dol_fiche_head($head, $tabchoice, $langs->trans("ThirdParty"), 0, 'company');
- print '';
+ print '';
print '';
print $langs->trans("PriceLevel").' '.$objsoc->price_level." ";
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index ffed0ec77b0..bc51fabfefc 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -3968,7 +3968,7 @@ elseif ($id > 0 || !empty($ref))
if ($result > 0) {
print '. '.$langs->trans(
"GeneratedFromTemplate",
- ''.$tmptemplate->ref.' '
+ ''.$tmptemplate->ref.' '
).' ';
}
}
diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php
index f8a9a2d2975..ff2cb84dbce 100644
--- a/htdocs/compta/sociales/card.php
+++ b/htdocs/compta/sociales/card.php
@@ -604,7 +604,7 @@ if ($id > 0)
*/
$sql = "SELECT p.rowid, p.num_paiement, datep as dp, p.amount,";
$sql .= " c.code as type_code,c.libelle as paiement_type,";
- $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal';
+ $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.currency_code as bacurrency_code, ba.fk_accountancy_journal';
$sql .= " FROM ".MAIN_DB_PREFIX."paiementcharge as p";
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
@@ -653,6 +653,7 @@ if ($id > 0)
$bankaccountstatic->ref = $objp->baref;
$bankaccountstatic->label = $objp->baref;
$bankaccountstatic->number = $objp->banumber;
+ $bankaccountstatic->currency_code = $objp->bacurrency_code;
if (!empty($conf->accounting->enabled)) {
$bankaccountstatic->account_number = $objp->account_number;
diff --git a/htdocs/core/actions_setnotes.inc.php b/htdocs/core/actions_setnotes.inc.php
index b9473de1b31..425204e00a4 100644
--- a/htdocs/core/actions_setnotes.inc.php
+++ b/htdocs/core/actions_setnotes.inc.php
@@ -33,7 +33,7 @@ if ($action == 'setnote_public' && ! empty($permissionnote) && ! GETPOST('cancel
if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('', 'Include of actions_setnotes.inc.php was done but required variable was not set before');
if (empty($object->id)) $object->fetch($id); // Fetch may not be already done
- $result_update=$object->update_note(dol_html_entity_decode(GETPOST('note_public', 'none'), ENT_QUOTES), '_public');
+ $result_update = $object->update_note(dol_html_entity_decode(GETPOST('note_public', 'none'), ENT_QUOTES, 'UTF-8', 1), '_public');
if ($result_update < 0) setEventMessages($object->error, $object->errors, 'errors');
elseif (in_array($object->table_element, array('supplier_proposal', 'propal', 'commande_fournisseur', 'commande', 'facture_fourn', 'facture')))
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 2c2064a0619..a9308ae03fb 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -213,7 +213,7 @@ class Form
$valuetoshow = price2num($editvalue ? $editvalue : $value);
$ret .= ' ';
}
- elseif (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata))
+ elseif (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata)) // if wysiwyg is enabled $typeofdata = 'ckeditor'
{
$tmp = explode(':', $typeofdata);
$cols = $tmp[2];
@@ -225,8 +225,10 @@ class Form
}
$valuetoshow = ($editvalue ? $editvalue : $value);
-
$ret .= '';
}
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index ba47a1bcb76..8805da44a96 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -5701,14 +5701,19 @@ function dol_htmlcleanlastbr($stringtodecode)
/**
* Replace html_entity_decode functions to manage errors
*
- * @param string $a Operand a
- * @param string $b Operand b (ENT_QUOTES=convert simple and double quotes)
- * @param string $c Operand c
- * @return string String decoded
+ * @param string $a Operand a
+ * @param string $b Operand b (ENT_QUOTES=convert simple and double quotes)
+ * @param string $c Operand c
+ * @param string $keepsomeentities Entities but &, <, >, " are not converted.
+ * @return string String decoded
*/
-function dol_html_entity_decode($a, $b, $c = 'UTF-8')
+function dol_html_entity_decode($a, $b, $c = 'UTF-8', $keepsomeentities = 0)
{
- return html_entity_decode($a, $b, $c);
+ $newstring = $a;
+ if ($keepsomeentities) $newstring = strtr($newstring, array('&'=>'__andamp__', '<'=>'__andlt__', '>'=>'__andgt__', '"'=>'__dquot__'));
+ $newstring = html_entity_decode($newstring, $b, $c);
+ if ($keepsomeentities) $newstring = strtr($newstring, array('__andamp__'=>'&', '__andlt__'=>'<', '__andgt__'=>'>', '__dquot__'=>'"'));
+ return $newstring;
}
/**
diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php
index 374e740ea40..9056f3bde9d 100644
--- a/htdocs/core/tpl/objectline_create.tpl.php
+++ b/htdocs/core/tpl/objectline_create.tpl.php
@@ -620,7 +620,7 @@ if (!empty($usemargins) && $user->rights->margins->creer)
/* When changing predefined product, we reload list of supplier prices required for margin combo */
$("#idprod, #idprodfournprice").change(function()
{
- console.log("#idprod, #idprodfournprice change triggered this.val = "+$(this).val());
+ console.log("Call method change() after change on #idprod or #idprodfournprice. this.val = "+$(this).val());
setforpredef(); // TODO Keep vat combo visible and set it to first entry into list that match result of get_default_tva
@@ -631,6 +631,7 @@ if (!empty($usemargins) && $user->rights->margins->creer)
{
?>
// Get the HT price for the product and display it
+ console.log("Load price without tax and set it into #price_ht");
$.post('/product/ajax/products.php?action=fetch',
{ 'id': $(this).val(), 'socid' : socid; ?> },
function(data) { jQuery("#price_ht").val(data.price_ht); },
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index b8745aa0d2b..e03b050d693 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -705,7 +705,7 @@ class CommandeFournisseur extends CommonOrder
*/
public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0)
{
- global $langs, $conf;
+ global $langs, $conf, $user;
$result = '';
$label = ''.$langs->trans("ShowOrder").' ';
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index 1f00720a12d..587f9fbb226 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -2253,7 +2253,7 @@ class FactureFournisseur extends CommonInvoice
*/
public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0)
{
- global $langs, $conf;
+ global $langs, $conf, $user;
$result = '';
diff --git a/htdocs/install/doctemplates/websites/website_template-corporate.zip b/htdocs/install/doctemplates/websites/website_template-corporate.zip
index a9773ce496b..f83fecc2c2e 100644
Binary files a/htdocs/install/doctemplates/websites/website_template-corporate.zip and b/htdocs/install/doctemplates/websites/website_template-corporate.zip differ
diff --git a/htdocs/install/doctemplates/websites/website_template-stellar.zip b/htdocs/install/doctemplates/websites/website_template-stellar.zip
index 59ebb470d72..ca73b125015 100644
Binary files a/htdocs/install/doctemplates/websites/website_template-stellar.zip and b/htdocs/install/doctemplates/websites/website_template-stellar.zip differ
diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang
index 7ee672f089b..052b1b25859 100644
--- a/htdocs/langs/en_US/other.lang
+++ b/htdocs/langs/en_US/other.lang
@@ -267,7 +267,7 @@ WEBSITE_PAGEURL=URL of page
WEBSITE_TITLE=Title
WEBSITE_DESCRIPTION=Description
WEBSITE_IMAGE=Image
-WEBSITE_IMAGEDesc=Relative path of the image media. You can keep this empty as this is rarely used (it can be used by dynamic content to show a preview of a list of blog posts).
+WEBSITE_IMAGEDesc=Relative path of the image media. You can keep this empty as this is rarely used (it can be used by dynamic content to show a thumbnail in a list of blog posts). Use __WEBSITEKEY__ in the path if path depends on website name.
WEBSITE_KEYWORDS=Keywords
LinesToImport=Lines to import
diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php
index 19fd7926453..918950179c7 100644
--- a/htdocs/product/ajax/products.php
+++ b/htdocs/product/ajax/products.php
@@ -59,8 +59,9 @@ dol_syslog(join(',', $_GET));
if (!empty($action) && $action == 'fetch' && !empty($id))
{
- // When action='fetch', id must be the product id.
+ // action='fetch' is used to get product information on a product. So when action='fetch', id must be the product id.
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
$outjson = array();
@@ -77,6 +78,13 @@ if (!empty($action) && $action == 'fetch' && !empty($id))
$found = false;
+ $price_level = 1;
+ if ($socid > 0 && !empty($conf->global->PRODUIT_MULTIPRICES)) {
+ $thirdpartytemp = new Societe($db);
+ $thirdpartytemp->fetch($socid);
+ $price_level = $thirdpartytemp->price_level;
+ }
+
// Price by qty
if (!empty($price_by_qty_rowid) && $price_by_qty_rowid >= 1 && (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))) // If we need a particular price related to qty
{
@@ -100,14 +108,13 @@ if (!empty($action) && $action == 'fetch' && !empty($id))
}
// Multiprice
- if (!$found && isset($price_level) && $price_level >= 1 && (!empty($conf->global->PRODUIT_MULTIPRICES))) // If we need a particular price
- // level (from 1 to 6)
+ if (!$found && isset($price_level) && $price_level >= 1 && (!empty($conf->global->PRODUIT_MULTIPRICES))) // If we need a particular price level (from 1 to 6)
{
$sql = "SELECT price, price_ttc, price_base_type, tva_tx";
$sql .= " FROM ".MAIN_DB_PREFIX."product_price ";
- $sql .= " WHERE fk_product='".$id."'";
+ $sql .= " WHERE fk_product = '".$id."'";
$sql .= " AND entity IN (".getEntity('productprice').")";
- $sql .= " AND price_level=".$price_level;
+ $sql .= " AND price_level = ".((int) $price_level);
$sql .= " ORDER BY date_price";
$sql .= " DESC LIMIT 1";
@@ -160,8 +167,7 @@ else
{
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
- $langs->load("products");
- $langs->load("main");
+ $langs->loadLangs(array("main", "products"));
top_httphead();
@@ -186,6 +192,7 @@ else
$searchkey = (($idprod && GETPOST($idprod, 'alpha')) ? GETPOST($idprod, 'alpha') : (GETPOST($htmlname, 'alpha') ? GETPOST($htmlname, 'alpha') : ''));
$form = new Form($db);
+
if (empty($mode) || $mode == 1) { // mode=1: customer
$arrayresult = $form->select_produits_list("", $htmlname, $type, 0, $price_level, $searchkey, $status, $finished, $outjson, $socid, '1', 0, '', $hidepriceinlabel, $warehouseStatus);
} elseif ($mode == 2) { // mode=2: supplier
diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php
index 708ff1c6464..1e189026366 100644
--- a/htdocs/product/class/api_products.class.php
+++ b/htdocs/product/class/api_products.class.php
@@ -1596,11 +1596,19 @@ class Products extends DolibarrApi
}
if ($includestockdata) {
- $this->product->load_stock();
+ $this->product->load_stock();
+
+ if (is_array($this->product->stock_warehouse)) {
+ foreach($this->product->stock_warehouse as $keytmp => $valtmp) {
+ if (is_array($this->product->stock_warehouse[$keytmp]->detail_batch)) {
+ foreach($this->product->stock_warehouse[$keytmp]->detail_batch as $keytmp2 => $valtmp2) {
+ unset($this->product->stock_warehouse[$keytmp]->detail_batch[$keytmp2]->db);
+ }
+ }
+ }
+ }
}
-
-
if ($includesubproducts) {
$childsArbo = $this->product->getChildsArbo($id, 1);
diff --git a/htdocs/product/stock/class/api_stockmovements.class.php b/htdocs/product/stock/class/api_stockmovements.class.php
index cfa901bce30..9951c05d323 100644
--- a/htdocs/product/stock/class/api_stockmovements.class.php
+++ b/htdocs/product/stock/class/api_stockmovements.class.php
@@ -154,51 +154,42 @@ class StockMovements extends DolibarrApi
return $obj_ret;
}
- /*
- * @param int $product_id Id product id {@min 1}
- * @param int $warehouse_id Id warehouse {@min 1}
- * @param float $qty Qty to add (Use negative value for a stock decrease) {@min 0} {@message qty must be higher than 0}
- * @param string $lot Lot
- * @param string $movementcode Movement code {@example INV123}
- * @param string $movementlabel Movement label {@example Inventory number 123}
- * @param string $price To update AWP (Average Weighted Price) when you make a stock increase (qty must be higher then 0).
- */
-
-
/**
* Create stock movement object.
* You can use the following message to test this RES API:
* { "product_id": 1, "warehouse_id": 1, "qty": 1, "lot": "", "movementcode": "INV123", "movementlabel": "Inventory 123", "price": 0 }
+ * $price Can be set to update AWP (Average Weighted Price) when you make a stock increase
+ * $dlc Eat-by date. Will be used if lot does not exists yet and will be created.
+ * $dluo Sell-by date. Will be used if lot does not exists yet and will be created.
+ *
+ * @param int $product_id Id product id {@min 1} {@from body} {@required true}
+ * @param int $warehouse_id Id warehouse {@min 1} {@from body} {@required true}
+ * @param float $qty Qty to add (Use negative value for a stock decrease) {@min 0} {@message qty must be higher than 0} {@from body} {@required true}
+ * @param string $lot Lot {@from body}
+ * @param string $movementcode Movement code {@example INV123} {@from body}
+ * @param string $movementlabel Movement label {@example Inventory number 123} {@from body}
+ * @param string $price To update AWP (Average Weighted Price) when you make a stock increase (qty must be higher then 0). {@from body}
+ * @param string $dlc Eat-by date. {@from body} {@type date}
+ * @param string $dluo Sell-by date. {@from body} {@type date}
*
- * @param array $request_data Request data
* @return int ID of stock movement
+ * @throws RestException
*/
- //function post($product_id, $warehouse_id, $qty, $lot='', $movementcode='', $movementlabel='', $price=0)
- public function post($request_data = null)
+ public function post($product_id, $warehouse_id, $qty, $lot = '', $movementcode = '', $movementlabel = '', $price = '', $dlc = '', $dluo = '')
{
if(! DolibarrApiAccess::$user->rights->stock->creer) {
throw new RestException(401);
}
- // Check mandatory fields
- //$result = $this->_validate($request_data);
-
- foreach($request_data as $field => $value) {
- //$this->stockmovement->$field = $value;
- if ($field == 'product_id') $product_id = $value;
- if ($field == 'warehouse_id') $warehouse_id = $value;
- if ($field == 'qty') $qty = $value;
- if ($field == 'lot') $lot = $value;
- if ($field == 'movementcode') $movementcode = $value;
- if ($field == 'movementlabel') $movementlabel = $value;
- if ($field == 'price') $price = $value;
+ if ($qty == 0) {
+ throw new RestException(503, "Making a stock movement with a quentity of 0 is not possible");
}
// Type increase or decrease
if ($qty >= 0) $type = 3;
else $type = 2;
- if($this->stockmovement->_create(DolibarrApiAccess::$user, $product_id, $warehouse_id, $qty, $type, $price, $movementlabel, $movementcode, '', '', '', $lot) <= 0) {
+ if($this->stockmovement->_create(DolibarrApiAccess::$user, $product_id, $warehouse_id, $qty, $type, $price, $movementlabel, $movementcode, '', $dlc, $dluo, $lot) <= 0) {
throw new RestException(503, 'Error when create stock movement : '.$this->stockmovement->error);
}
@@ -342,7 +333,7 @@ class StockMovements extends DolibarrApi
private function _validate($data)
{
$stockmovement = array();
- foreach (Warehouses::$FIELDS as $field) {
+ foreach (self::$FIELDS as $field) {
if (!isset($data[$field]))
throw new RestException(400, "$field field missing");
$stockmovement[$field] = $data[$field];
diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
index 41d002eece8..bc4dd12e9d4 100644
--- a/htdocs/product/stock/class/mouvementstock.class.php
+++ b/htdocs/product/stock/class/mouvementstock.class.php
@@ -158,6 +158,8 @@ class MouvementStock extends CommonObject
$result = $product->fetch($fk_product);
if ($result < 0)
{
+ $this->error = $product->error;
+ $this->errors = $product->errors;
dol_print_error('', "Failed to fetch product");
return -1;
}
@@ -399,7 +401,8 @@ class MouvementStock extends CommonObject
}
else
{
- $this->errors[] = $this->db->lasterror();
+ $this->error = $this->db->lasterror();
+ $this->errors[] = $this->error;
$error = -1;
}
diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php
index a832188918c..514d87d9200 100644
--- a/htdocs/societe/card.php
+++ b/htdocs/societe/card.php
@@ -5,7 +5,7 @@
* Copyright (C) 2005 Eric Seigne
* Copyright (C) 2005-2017 Regis Houssin
* Copyright (C) 2008 Patrick Raguin
- * Copyright (C) 2010-2016 Juanjo Menent
+ * Copyright (C) 2010-2020 Juanjo Menent
* Copyright (C) 2011-2013 Alexandre Spangaro
* Copyright (C) 2015 Jean-François Ferry
* Copyright (C) 2015 Marcos García
@@ -1070,13 +1070,13 @@ else
$linkback = "";
print load_fiche_titre($langs->trans("NewThirdParty"), $linkback, 'building');
- if (!empty($conf->use_javascript_ajax) && !empty($conf->global->THIRDPARTY_SUGGEST_ALSO_ADDRESS_CREATION))
- {
- print "\n".''."\n";
+ print '' . "\n";
- print '';
- print " \n";
- }
+ print '';
+ print " \n";
+ } else {
+ print '' . "\n";
+ }
+ }
dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');