diff --git a/ChangeLog b/ChangeLog
index fea73254f20..3b81e0555d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -380,6 +380,77 @@ Following changes may create regressions for some external modules, but were nec
* The jquery plugin/dependency multiselect has been removed. It was not used by Dolibarr core.
+***** ChangeLog for 10.0.7 compared to 10.0.6 *****
+FIX: 10.0 - missing translations for "orders" homepage "orders" box
+FIX: 10.0 - status missing from last customer invoices box when using MAIN_STATUS_USES_CSS
+FIX: 10.0 - translations for "orders" not loaded in the homepage box
+FIX: #10309
+FIX: #12875
+FIX: #12932
+FIX: #12966
+FIX: #12973
+FIX: #13304
+FIX: advanced target emailing sql and ergonomy
+FIX: an external user can not approved
+FIX: Bad translation for productlot EatBy and SellBy
+FIX: better check
+FIX: better method to check user rights AND usergroup rights !
+FIX: CA by prod list filter
+FIX: can be a string or integer
+FIX: Check on unicity on prof id was not triggered sometimes
+FIX: clone of purchase order
+FIX: compatibility with multicompany (avoid duplicate data)
+FIX: complex export model loading
+FIX: date filter not used if no operator
+FIX: date order was -1D and desc with label repetition
+FIX: default lang selection when filter
+FIX: dom and missing param
+FIX: drafts are now implemented for stats
+FIX: Error in log for email sending with smtps was not complete
+FIX: Extrafield position in export field list must respect "pos" field
+FIX: FEC export format
+FIX: FEC export have specific name
+FIX: fetching account on current entity
+FIX: Filenames must not contains non ascii char or we will get non ascii
+FIX: fk_type subscription list via api REST
+FIX: Force FEC export to txt format
+FIX: get remain to pay with rounding decimals
+FIX: Invert isSellerInEEC and isBuyerInEEC
+FIX: keep assigned users in session when loading projects and tasks
+FIX: length, width and height units coherence in product table
+FIX: links in products/services index
+FIX: Mail smtps truncated if content has a line with single .
+FIX: missing array option
+FIX: missing global $conf
+FIX: missing hook parameter
+FIX: Missing Linked objects Fichinter Ref. in PDF formats
+FIX: missing "statut" for getNomUrl() function
+FIX: multicompany for discount
+FIX: must be == and not =
+FIX: Problem with column label in subscription list
+FIX: regex for include or exclude categories in full arbo
+FIX: Remove unexisting link
+FIX: remove unused var, $usercancreate can be change by Multicompany
+FIX: require category class in extrafield
+FIX: round MT in accountancy books
+FIX: search with '0'
+FIX: send expense report mail in HTML format
+FIX: SQL request and phpunit
+FIX: substitute lines dates values on doc generator (ODT, ...)
+FIX: test on 0 better than isset
+FIX: The "automatic bind" was linked EEC to export accountancy code
+FIX: thirdparty alias name desappeared if we change country with THIRDPARTY_SUGGEST_ALSO_ADDRESS_CREATION conf
+FIX: timezone must be tzserver and not tzuser as well as on contract card
+FIX: typo on ckeck method
+FIX: use "usergroup" instead "user"
+FIX: Visualization rights correction on last modified contacts box
+FIX: Warning on admin/export_files
+FIX: We want to be able to import data for extrafields of entity 0 too
+FIX: when we filter a list on a view status, we want this filter to be on bookmark that we create
+FIX: wrong test
+FIX: XSS vulnerability in description of list of audit events.
+FIX: z-index for moretabsList with constant MAIN_MAXTABS_IN_CARD
+
***** ChangeLog for 10.0.6 compared to 10.0.5 *****
FIX Regression of 10.0.5 to create/edit proposals and orders.
FIX: #12760 #12763 #12755 #12765 #12751
diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php
index 7497ededc8f..c9b7ee42fcf 100644
--- a/htdocs/adherents/list.php
+++ b/htdocs/adherents/list.php
@@ -52,6 +52,7 @@ $search_lastname = GETPOST("search_lastname", 'alpha');
$search_firstname = GETPOST("search_firstname", 'alpha');
$search_gender = GETPOST("search_gender", 'alpha');
$search_civility = GETPOST("search_civility", 'alpha');
+$search_company = GETPOST('search_company', 'alphanohtml');
$search_login = GETPOST("search_login", 'alpha');
$search_address = GETPOST("search_address", 'alpha');
$search_zip = GETPOST("search_zip", 'alpha');
@@ -254,6 +255,7 @@ $sql = "SELECT d.rowid, d.login, d.lastname, d.firstname, d.gender, d.societe as
$sql .= " d.civility, d.datefin, d.address, d.zip, d.town, d.state_id, d.country,";
$sql .= " d.email, d.phone, d.phone_perso, d.phone_mobile, d.skype, d.birth, d.public, d.photo,";
$sql .= " d.fk_adherent_type as type_id, d.morphy, d.statut, d.datec as date_creation, d.tms as date_update,";
+$sql .= " s.nom,";
$sql .= " t.libelle as type, t.subscription,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";
// Add fields from extrafields
@@ -269,6 +271,7 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count
if (!empty($search_categ) || !empty($catid)) $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_member as cm ON d.rowid = cm.fk_member"; // We need this table joined to the select in order to filter by categ
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = d.country)";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = d.state_id)";
+$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on (s.rowid = d.fk_soc)";
$sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
$sql .= " WHERE d.fk_adherent_type = t.rowid ";
if ($catid > 0) $sql .= " AND cm.fk_categorie = ".$db->escape($catid);
@@ -289,6 +292,7 @@ if ($search_firstname) $sql .= natural_search("d.firstname", $search_firstname);
if ($search_lastname) $sql .= natural_search(array("d.firstname", "d.lastname", "d.societe"), $search_lastname);
if ($search_gender != '' && $search_gender != '-1') $sql .= " AND d.gender = '".$search_gender."'";
if ($search_login) $sql .= natural_search("d.login", $search_login);
+if ($search_company) $sql .= natural_search("s.nom", $search_company);
if ($search_email) $sql .= natural_search("d.email", $search_email);
if ($search_town) $sql .= natural_search("d.town", $search_town);
if ($search_zip) $sql .= natural_search("d.zip", $search_zip);
diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php
index f6a2871a5c0..a582584ae7f 100644
--- a/htdocs/adherents/subscription/list.php
+++ b/htdocs/adherents/subscription/list.php
@@ -33,6 +33,7 @@ $langs->loadLangs(array("members", "companies"));
$action = GETPOST('action', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
+$contextpage = GETPOST('contextpage', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
@@ -116,7 +117,6 @@ if (empty($reshook))
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) // All tests are required to be compatible with all browsers
{
- $search = "";
$search_type = "";
$search_ref = "";
$search_lastname = "";
@@ -338,7 +338,7 @@ if (!empty($arrayfields['t.libelle']['checked']))
if (!empty($arrayfields['d.bank']['checked']))
{
print '
';
- $form->select_comptes($search_account, 'search_account', 0, '', 1);
+ $form->select_comptes($search_account, 'search_account', 0, '', 1, '', 0, 'maxwidth150');
print ' ';
}
@@ -446,7 +446,7 @@ while ($i < min($num, $limit))
// Type
if (!empty($arrayfields['d.fk_type']['checked']))
{
- print '';
+ print ' ';
if ($typeid > 0)
{
print $adht->getNomUrl(1);
@@ -466,14 +466,14 @@ while ($i < min($num, $limit))
// Firstname
if (!empty($arrayfields['d.firstname']['checked']))
{
- print ' '.$adherent->firstname.' ';
+ print ''.$adherent->firstname.' ';
if (!$i) $totalarray['nbfield']++;
}
// Login
if (!empty($arrayfields['d.login']['checked']))
{
- print ''.$adherent->login.' ';
+ print ''.$adherent->login.' ';
if (!$i) $totalarray['nbfield']++;
}
@@ -489,7 +489,7 @@ while ($i < min($num, $limit))
// Banque
if (!empty($arrayfields['d.bank']['checked']))
{
- print "";
+ print ' ';
if ($obj->fk_account > 0)
{
$accountstatic->id = $obj->fk_account;
diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php
index d6981448ea6..0d9775e0fbd 100644
--- a/htdocs/admin/defaultvalues.php
+++ b/htdocs/admin/defaultvalues.php
@@ -38,6 +38,7 @@ if (!$user->admin) accessforbidden();
$id = GETPOST('rowid', 'int');
$action = GETPOST('action', 'alpha');
+$optioncss = GETPOST('optionscss', 'alphanohtml');
$mode = GETPOST('mode', 'aZ09') ?GETPOST('mode', 'aZ09') : 'createform'; // 'createform', 'filters', 'sortorder', 'focus'
@@ -212,10 +213,10 @@ print " \n";
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage);
if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit);
-if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
-if ($defaulturl) $param .= '&defaulturl='.urlencode($defaulturl);
-if ($defaultkey) $param .= '&defaultkey='.urlencode($defaultkey);
-if ($defaultvalue) $param .= '&defaultvalue='.urlencode($defaultvalue);
+if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
+if ($defaulturl) $param .= '&defaulturl='.urlencode($defaulturl);
+if ($defaultkey) $param .= '&defaultkey='.urlencode($defaultkey);
+if ($defaultvalue) $param .= '&defaultvalue='.urlencode($defaultvalue);
print ' ';
+ // List of existing properties
foreach ($properties as $propkey => $propval)
{
/* If from Reflection
@@ -2637,7 +2710,7 @@ elseif (! empty($module))
print $propenabled?$propenabled:'';
print '';
print '';
- print $propvisible?$propvisible:'';
+ print $propvisible?$propvisible:'0';
print ' ';
print '';
print $propnoteditable?$propnoteditable:'';
diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
index 596e47e12c0..97997a57542 100644
--- a/htdocs/modulebuilder/template/class/myobject.class.php
+++ b/htdocs/modulebuilder/template/class/myobject.class.php
@@ -551,29 +551,31 @@ class MyObject extends CommonObject
}
$this->newref = $num;
- // Validate
- $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
- $sql .= " SET ref = '".$this->db->escape($num)."',";
- $sql .= " status = ".self::STATUS_VALIDATED.",";
- $sql .= " date_validation = '".$this->db->idate($now)."',";
- $sql .= " fk_user_valid = ".$user->id;
- $sql .= " WHERE rowid = ".$this->id;
+ if (! empty($num)) {
+ // Validate
+ $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
+ $sql .= " SET ref = '".$this->db->escape($num)."',";
+ $sql .= " status = ".self::STATUS_VALIDATED;
+ if (! empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
+ if (! empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".$user->id;
+ $sql .= " WHERE rowid = ".$this->id;
- dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
- $resql = $this->db->query($sql);
- if (!$resql)
- {
- dol_print_error($this->db);
- $this->error = $this->db->lasterror();
- $error++;
- }
+ dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if (!$resql)
+ {
+ dol_print_error($this->db);
+ $this->error = $this->db->lasterror();
+ $error++;
+ }
- if (!$error && !$notrigger)
- {
- // Call trigger
- $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
- if ($result < 0) $error++;
- // End call triggers
+ if (!$error && !$notrigger)
+ {
+ // Call trigger
+ $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
+ if ($result < 0) $error++;
+ // End call triggers
+ }
}
if (!$error)
@@ -920,7 +922,7 @@ class MyObject extends CommonObject
$langs->load("mymodule@myobject");
if (empty($conf->global->MYMODULE_MYOBJECT_ADDON)) {
- $conf->global->MYMODULE_MYOBJECT_ADDON = 'mod_mymobject_standard';
+ $conf->global->MYMODULE_MYOBJECT_ADDON = 'mod_myobject_standard';
}
if (!empty($conf->global->MYMODULE_MYOBJECT_ADDON))
@@ -946,23 +948,28 @@ class MyObject extends CommonObject
return '';
}
- $obj = new $classname();
- $numref = $obj->getNextValue($this);
+ if (class_exists($classname)) {
+ $obj = new $classname();
+ $numref = $obj->getNextValue($this);
- if ($numref != "")
- {
- return $numref;
- }
- else
- {
- $this->error = $obj->error;
- //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
+ if ($numref != '' && $numref != '-1')
+ {
+ return $numref;
+ }
+ else
+ {
+ $this->error = $obj->error;
+ //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
+ return "";
+ }
+ } else {
+ print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
return "";
}
}
else
{
- print $langs->trans("Error")." ".$langs->trans("Error_MYMODULE_MYOBJECT_ADDON_NotDefined");
+ print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
return "";
}
}
@@ -982,6 +989,9 @@ class MyObject extends CommonObject
{
global $conf, $langs;
+ $result = 0;
+ $includedocgeneration = 0;
+
$langs->load("mymodule@mymodule");
if (!dol_strlen($modele)) {
@@ -996,7 +1006,11 @@ class MyObject extends CommonObject
$modelpath = "core/modules/mymodule/doc/";
- return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
+ if ($includedocgeneration) {
+ $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
+ }
+
+ return $result;
}
/**
diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php
index 26866a6b9f1..8ae1284c918 100644
--- a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php
+++ b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php
@@ -98,15 +98,20 @@ class mod_myobject_advanced extends ModeleNumRefMyObject
*/
public function getExample()
{
- global $conf,$langs,$mysoc;
+ global $conf, $db, $langs, $mysoc;
- $old_code_client=$mysoc->code_client;
+ $object = new MyObject($db);
+ $object->initAsSpecimen();
+
+ /*$old_code_client=$mysoc->code_client;
$old_code_type=$mysoc->typent_code;
$mysoc->code_client='CCCCCCCCCC';
- $mysoc->typent_code='TTTTTTTTTT';
- $numExample = $this->getNextValue($mysoc, '');
- $mysoc->code_client=$old_code_client;
- $mysoc->typent_code=$old_code_type;
+ $mysoc->typent_code='TTTTTTTTTT';*/
+
+ $numExample = $this->getNextValue($object, '');
+
+ /*$mysoc->code_client=$old_code_client;
+ $mysoc->typent_code=$old_code_type;*/
if (! $numExample)
{
diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php
index e18e7636b6d..a213fee7174 100644
--- a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php
+++ b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php
@@ -76,9 +76,10 @@ class mod_myobject_standard extends ModeleNumRefMyObject
* Checks if the numbers already in force in the data base do not
* cause conflicts that would prevent this numbering from working.
*
- * @return boolean false if conflict, true if ok
+ * @param Object $object Object we need next value for
+ * @return boolean false if conflict, true if ok
*/
- public function canBeActivated()
+ public function canBeActivated($object)
{
global $conf,$langs,$db;
@@ -88,7 +89,12 @@ class mod_myobject_standard extends ModeleNumRefMyObject
$sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
$sql.= " FROM ".MAIN_DB_PREFIX."mymodule_myobject";
$sql.= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
- $sql.= " AND entity = ".$conf->entity;
+ if ($object->ismultientitymanaged == 1) {
+ $sql.= " AND entity = ".$conf->entity;
+ }
+ elseif ($object->ismultientitymanaged == 2) {
+ // TODO
+ }
$resql=$db->query($sql);
if ($resql)
@@ -121,7 +127,12 @@ class mod_myobject_standard extends ModeleNumRefMyObject
$sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
$sql.= " FROM ".MAIN_DB_PREFIX."mymodule_myobject";
$sql.= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
- $sql.= " AND entity = ".$conf->entity;
+ if ($object->ismultientitymanaged == 1) {
+ $sql.= " AND entity = ".$conf->entity;
+ }
+ elseif ($object->ismultientitymanaged == 2) {
+ // TODO
+ }
$resql=$db->query($sql);
if ($resql)
diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php
index 93eb7560aaa..97adff0558f 100644
--- a/htdocs/modulebuilder/template/myobject_card.php
+++ b/htdocs/modulebuilder/template/myobject_card.php
@@ -290,7 +290,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
if ($action == 'clone') {
// Create an array for form
$formquestion = array();
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneMyObject', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
+ $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
}
// Confirmation of action xxxx
@@ -581,7 +581,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
}
//Select mail models is same action as presend
- /*
if (GETPOST('modelselected')) $action = 'presend';
// Presend form
@@ -591,7 +590,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$trackid = 'myobject'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
- */
}
// End of page
diff --git a/htdocs/product/card.php b/htdocs/product/card.php
index f4e959a9459..ad793f4f7d3 100644
--- a/htdocs/product/card.php
+++ b/htdocs/product/card.php
@@ -1272,7 +1272,13 @@ else
// Accountancy_code_buy
print ' '.$langs->trans("ProductAccountancyBuyCode").' ';
print '';
- print $formaccounting->select_account(GETPOST('accountancy_code_buy', 'alpha'), 'accountancy_code_buy', 1, null, 1, 1, '');
+ if($type == 0)
+ {
+ $accountancy_code_buy = (GETPOST('accountancy_code_buy', 'alpha')?(GETPOST('accountancy_code_buy', 'alpha')):$conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT);
+ } else {
+ $accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha');
+ }
+ print $formaccounting->select_account($accountancy_code_buy, 'accountancy_code_buy', 1, null, 1, 1, '');
print ' ';
}
else // For external software
diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php
index 1e189026366..0cf6b344abf 100644
--- a/htdocs/product/class/api_products.class.php
+++ b/htdocs/product/class/api_products.class.php
@@ -796,11 +796,11 @@ class Products extends DolibarrApi
}
if ($result) {
- $this->productsupplier->fetch($id, $ref);
- $this->productsupplier->list_product_fournisseur_price($id, '', '', 0, 0);
+ $product_fourn = new ProductFournisseur($this->db);
+ $product_fourn_list = $product_fourn->list_product_fournisseur_price($this->product->id, '', '', 0, 0);
}
- return $this->_cleanObjectDatas($this->productsupplier);
+ return $this->_cleanObjectDatas($product_fourn_list);
}
/**
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index bfdc9338b87..f8b71082b21 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -1013,12 +1013,13 @@ class Product extends CommonObject
$sql .= ", accountancy_code_sell= '".$this->db->escape($this->accountancy_code_sell)."'";
$sql .= ", accountancy_code_sell_intra= '".$this->db->escape($this->accountancy_code_sell_intra)."'";
$sql .= ", accountancy_code_sell_export= '".$this->db->escape($this->accountancy_code_sell_export)."'";
- $sql .= ", desiredstock = ".((isset($this->desiredstock) && $this->desiredstock != '') ? (int) $this->desiredstock : "null");
+ $sql .= ", desiredstock = ".((isset($this->desiredstock) && is_numeric($this->desiredstock)) ? (int) $this->desiredstock : "null");
$sql .= ", cost_price = ".($this->cost_price != '' ? $this->db->escape($this->cost_price) : 'null');
$sql .= ", fk_unit= ".(!$this->fk_unit ? 'NULL' : (int) $this->fk_unit);
$sql .= ", price_autogen = ".(!$this->price_autogen ? 0 : 1);
$sql .= ", fk_price_expression = ".($this->fk_price_expression != 0 ? (int) $this->fk_price_expression : 'NULL');
$sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id : 'NULL');
+
// stock field is not here because it is a denormalized value from product_stock.
$sql .= " WHERE rowid = ".$id;
diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
index 7b92af43ef0..e0266172463 100644
--- a/htdocs/product/stock/class/mouvementstock.class.php
+++ b/htdocs/product/stock/class/mouvementstock.class.php
@@ -109,7 +109,7 @@ class MouvementStock extends CommonObject
* @param string $batch batch number
* @param boolean $skip_batch If set to true, stock movement is done without impacting batch record
* @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use)
- * @return int <0 if KO, 0 if fk_product is null, >0 if OK
+ * @return int <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK
*/
public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0)
{
@@ -155,13 +155,15 @@ class MouvementStock extends CommonObject
$product = new Product($this->db);
$result=$product->fetch($fk_product);
- if ($result < 0)
- {
+ if ($result < 0) {
$this->error = $product->error;
$this->errors = $product->errors;
dol_print_error('', "Failed to fetch product");
return -1;
}
+ if ($product->id <= 0) { // Can happen if database is corrupted
+ return 0;
+ }
$this->db->begin();
diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php
index 2ad465bdedb..ae5c936ef1e 100644
--- a/htdocs/product/stock/replenish.php
+++ b/htdocs/product/stock/replenish.php
@@ -702,7 +702,10 @@ while ($i < ($limit ? min($num, $limit) : $num))
//depending on conf, use either physical stock or
//virtual stock to compute the stock to buy value
- $stocktobuy = max(max($desiredstock, $alertstock) - $stock - $ordered, 0);
+
+ if(empty($usevirtualstock)) $stocktobuy = max(max($desiredstock, $alertstock) - $stock - $ordered, 0);
+ else $stocktobuy = max(max($desiredstock, $alertstock) - $stock, 0); //ordered is already in $stock in virtual mode
+
$disabled = '';
if ($ordered > 0)
{
diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php
index 6f41426ee80..3c2d68f653d 100644
--- a/htdocs/supplier_proposal/class/supplier_proposal.class.php
+++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php
@@ -1800,25 +1800,25 @@ class SupplierProposal extends CommonObject
*/
public function updateOrCreatePriceFournisseur($user)
{
- $productsupplier = new ProductFournisseur($this->db);
+ global $conf;
dol_syslog(get_class($this)."::updateOrCreatePriceFournisseur", LOG_DEBUG);
foreach ($this->lines as $product)
{
if ($product->subprice <= 0) continue;
+ $productsupplier = new ProductFournisseur($this->db);
- $idProductFourn = $productsupplier->find_min_price_product_fournisseur($product->fk_product, $product->qty);
- $res = $productsupplier->fetch($idProductFourn);
+ $multicurrency_tx = 1;
+ $fk_multicurrency = 0;
- if ($productsupplier->id) {
- if ($productsupplier->fourn_qty == $product->qty) {
- $this->updatePriceFournisseur($productsupplier->product_fourn_price_id, $product, $user);
- } else {
- $this->createPriceFournisseur($product, $user);
- }
- } else {
- $this->createPriceFournisseur($product, $user);
- }
+ if(empty($this->thirdparty)) $this->fetch_thirdparty();
+
+ $ref_fourn = $product->ref_fourn;
+ if(empty($ref_fourn)) $ref_fourn = $product->ref_supplier;
+ if(!empty($conf->multicurrency->enabled) && !empty($product->multicurrency_code)) list($fk_multicurrency, $multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $product->multicurrency_code);
+ $productsupplier->id = $product->fk_product;
+
+ $productsupplier->update_buyprice($product->qty, $product->subprice, $user, 'HT', $this->thirdparty, '', $ref_fourn, $product->tva_tx, 0, 0, 0, $product->info_bits, '', '', array(), '', $product->multicurrency_subprice, 'HT', $multicurrency_tx, $product->multicurrency_code, '', '', '');
}
return 1;
@@ -1856,11 +1856,12 @@ class SupplierProposal extends CommonObject
*/
public function createPriceFournisseur($product, $user)
{
- $price=price2num($product->subprice*$product->qty, 'MU');
+ global $conf;
+
+ $price=price2num($product->subprice*$product->qty, 'MU');
$qty=price2num($product->qty);
$unitPrice = price2num($product->subprice, 'MU');
$now=dol_now();
-
$values = array(
"'".$this->db->idate($now)."'",
$product->fk_product,
@@ -1872,9 +1873,28 @@ class SupplierProposal extends CommonObject
$product->tva_tx,
$user->id
);
+ if (!empty($conf->multicurrency->enabled)) {
+ if (!empty($product->multicurrency_code)) {
+ include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
+ $multicurrency = new MultiCurrency($this->db); //need to fetch because empty fk_multicurrency and rate
+ $multicurrency->fetch(0, $product->multicurrency_code);
+ if(! empty($multicurrency->id)) {
+ $values[] = $multicurrency->id;
+ $values[] = "'".$product->multicurrency_code."'";
+ $values[] = $product->multicurrency_subprice;
+ $values[] = $product->multicurrency_total_ht;
+ $values[] = $multicurrency->rate->rate;
+ }
+ else {
+ for($i = 0; $i < 5; $i++) $values[] = 'NULL';
+ }
+ }
+ }
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_fournisseur_price ';
- $sql .= '(datec, fk_product, fk_soc, ref_fourn, price, quantity, unitprice, tva_tx, fk_user) VALUES ('.implode(',', $values).')';
+ $sql .= '(datec, fk_product, fk_soc, ref_fourn, price, quantity, unitprice, tva_tx, fk_user';
+ if(!empty($conf->multicurrency->enabled) && !empty($product->multicurrency_code)) $sql .= ',fk_multicurrency, multicurrency_code, multicurrency_unitprice, multicurrency_price, multicurrency_tx';
+ $sql .= ') VALUES ('.implode(',', $values).')';
$resql = $this->db->query($sql);
if (!$resql) {
diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
index e800689b15d..189e5a56cec 100644
--- a/htdocs/theme/md/style.css.php
+++ b/htdocs/theme/md/style.css.php
@@ -47,7 +47,7 @@ if (defined('THEME_ONLY_CONSTANT')) return;
session_cache_limiter('public');
-require_once '../../main.inc.php';
+require_once __DIR__.'/../../main.inc.php'; // __DIR__ allow this script to be included in custom themes
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
// Load user to have $user->conf loaded (not done into main because of NOLOGIN constant defined)
diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php
index 8ca8bd22bfe..d59581fa914 100644
--- a/htdocs/ticket/card.php
+++ b/htdocs/ticket/card.php
@@ -637,7 +637,7 @@ if ($action == 'create' || $action == 'presend')
$defaultref = '';
}
- $formticket->showForm(1);
+ $formticket->showForm(1, 'create');
}
if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'presend' || $action == 'presend_addmessage' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen'
diff --git a/htdocs/user/card.php b/htdocs/user/card.php
index d12f6064131..152103cc5db 100644
--- a/htdocs/user/card.php
+++ b/htdocs/user/card.php
@@ -1243,13 +1243,8 @@ if ($action == 'create' || $action == 'adduserldap')
}
// Other attributes
- $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
- $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- print $hookmanager->resPrint;
- if (empty($reshook))
- {
- print $object->showOptionals($extrafields, 'edit');
- }
+ $parameters = array('colspan' => ' colspan="3"');
+ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
// Note
print '';
@@ -2515,74 +2510,6 @@ else
}
}
- // // Skype
- // if (! empty($conf->socialnetworks->enabled))
- // {
- // print ' '.$langs->trans("Skype").' ';
- // print '';
- // if ($caneditfield && empty($object->ldap_sid))
- // {
- // print ' ';
- // }
- // else
- // {
- // print ' ';
- // print $object->skype;
- // }
- // print ' ';
- // }
-
- // // Twitter
- // if (! empty($conf->socialnetworks->enabled))
- // {
- // print ''.$langs->trans("Twitter").' ';
- // print '';
- // if ($caneditfield && empty($object->ldap_sid))
- // {
- // print ' ';
- // }
- // else
- // {
- // print ' ';
- // print $object->twitter;
- // }
- // print ' ';
- // }
-
- // // Facebook
- // if (! empty($conf->socialnetworks->enabled))
- // {
- // print ''.$langs->trans("Facebook").' ';
- // print '';
- // if ($caneditfield && empty($object->ldap_sid))
- // {
- // print ' ';
- // }
- // else
- // {
- // print ' ';
- // print $object->facebook;
- // }
- // print ' ';
- // }
-
- // // LinkedIn
- // if (! empty($conf->socialnetworks->enabled))
- // {
- // print ''.$langs->trans("LinkedIn").' ';
- // print '';
- // if ($caneditfield && empty($object->ldap_sid))
- // {
- // print ' ';
- // }
- // else
- // {
- // print ' ';
- // print $object->linkedin;
- // }
- // print ' ';
- // }
-
// OpenID url
if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->file->main_authentication) && !empty($conf->global->MAIN_OPENIDURL_PERUSER))
{
@@ -2738,12 +2665,12 @@ else
// Other attributes
$parameters = array('colspan' => ' colspan="2"');
+ //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; // We do not use common tpl here because we need a special test on $caneditfield
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
if (empty($reshook))
{
- if ($caneditfield)
- {
+ if ($caneditfield) {
print $object->showOptionals($extrafields, 'edit');
} else {
print $object->showOptionals($extrafields, 'view');
diff --git a/scripts/user/migrate_picture_path.php b/scripts/user/migrate_picture_path.php
new file mode 100755
index 00000000000..b0ca99dd977
--- /dev/null
+++ b/scripts/user/migrate_picture_path.php
@@ -0,0 +1,129 @@
+#!/usr/bin/env php
+
+ * Copyright (C) 2015 Jean Heimburger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file scripts/product/migrate_picture_path.php
+ * \ingroup scripts
+ * \brief Migrate pictures from old system prior to 3.7 to new path for 3.7+
+ */
+$sapi_type = php_sapi_name();
+$script_file = basename(__FILE__);
+$path = __DIR__ . '/';
+
+// Test if batch mode
+if (substr($sapi_type, 0, 3) == 'cgi') {
+ echo "Error: You are using PHP for CGI. To execute " . $script_file . " from command line, you must use PHP for CLI mode.\n";
+ exit(- 1);
+}
+
+@set_time_limit(0); // No timeout for this script
+define('EVEN_IF_ONLY_LOGIN_ALLOWED', 1); // Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only".
+
+// Include and load Dolibarr environment variables
+require_once $path . "../../htdocs/master.inc.php";
+require_once DOL_DOCUMENT_ROOT . "/user/class/user.class.php";
+require_once DOL_DOCUMENT_ROOT . "/core/lib/files.lib.php";
+// After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file).
+// $user is created but empty.
+
+// $langs->setDefaultLang('en_US'); // To change default language of $langs
+$langs->load("main"); // To load language file for default language
+
+// Global variables
+$version = DOL_VERSION;
+$error = 0;
+$forcecommit = 0;
+
+print "***** " . $script_file . " (" . $version . ") pid=" . dol_getmypid() . " *****\n";
+dol_syslog($script_file . " launched with arg " . join(',', $argv));
+
+if (! isset($argv[1]) || $argv[1] != 'user') {
+ print "Usage: $script_file user\n";
+ exit(- 1);
+}
+
+print '--- start' . "\n";
+
+// Case to migrate products path
+if ($argv[1] == 'user') {
+ $u = new User($db);
+
+ $sql = "SELECT rowid as uid from " . MAIN_DB_PREFIX . "user"; // Get list of all products
+ $resql = $db->query($sql);
+ if ($resql) {
+ while ($obj = $db->fetch_object($resql)) {
+ $u->fetch($obj->uid);
+ print " migrating user id=" . $u->id . " ref=" . $u->ref . "\n";
+ migrate_user_filespath($u);
+ }
+ } else {
+ print "\n sql error " . $sql;
+ exit();
+ }
+}
+
+$db->close(); // Close $db database opened handler
+
+exit($error);
+
+
+/**
+ * Migrate file from old path to new one for user $u
+ *
+ * @param User $u Object user
+ * @return void
+ */
+function migrate_user_filespath($u)
+{
+ global $conf;
+
+ // Les fichiers joints des users sont toujours sur l'entité 1
+ $dir = $conf->user->dir_output;
+ $origin = $dir . '/' . get_exdir($u->id, 2, 0, 0, $u, 'user');
+ $destin = $dir . '/' . $u->id;
+
+ $error = 0;
+
+ $origin_osencoded = dol_osencode($origin);
+ $destin_osencoded = dol_osencode($destin);
+ dol_mkdir($destin);
+
+ if (dol_is_dir($origin)) {
+ $handle = opendir($origin_osencoded);
+ if (is_resource($handle)) {
+ while (($file = readdir($handle)) !== false) {
+ if ($file != '.' && $file != '..' && is_dir($origin_osencoded . '/' . $file)) {
+ $thumbs = opendir($origin_osencoded . '/' . $file);
+ if (is_resource($thumbs)) {
+ dol_mkdir($destin . '/' . $file);
+ while (($thumb = readdir($thumbs)) !== false) {
+ dol_move($origin . '/' . $file . '/' . $thumb, $destin . '/' . $file . '/' . $thumb);
+ }
+ // dol_delete_dir($origin.'/'.$file);
+ }
+ } else {
+ if (dol_is_file($origin . '/' . $file)) {
+ dol_move($origin . '/' . $file, $destin . '/' . $file);
+ }
+ }
+ }
+ }
+ }
+}