';
@@ -8527,11 +8528,6 @@ class Form
if (empty($conf->expedition->enabled)) {
continue; // Do not show if module disabled
}
- } elseif ($objecttype == 'mo') {
- $tplpath = 'mrp/mo';
- if (empty($conf->mrp->enabled)) {
- continue; // Do not show if module disabled
- }
} elseif ($objecttype == 'ficheinter') {
$tplpath = 'fichinter';
if (empty($conf->ficheinter->enabled)) {
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 27da527c093..e2bcda01b6a 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -370,6 +370,32 @@ function GETPOSTISSET($paramname)
return $isset;
}
+/**
+ * Return true if the parameter $paramname is submit from a POST OR GET as an array.
+ * Can be used before GETPOST to know if the $check param of GETPOST need to check an array or a string
+ *
+ * @param string $paramname Name or parameter to test
+ * @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get)
+ * @return bool True if we have just submit a POST or GET request with the parameter provided (even if param is empty)
+ */
+function GETPOSTISARRAY($paramname, $method = 0)
+{
+ // for $method test need return the same $val as GETPOST
+ if (empty($method)) {
+ $val = isset($_GET[$paramname]) ? $_GET[$paramname] : (isset($_POST[$paramname]) ? $_POST[$paramname] : '');
+ } elseif ($method == 1) {
+ $val = isset($_GET[$paramname]) ? $_GET[$paramname] : '';
+ } elseif ($method == 2) {
+ $val = isset($_POST[$paramname]) ? $_POST[$paramname] : '';
+ } elseif ($method == 3) {
+ $val = isset($_POST[$paramname]) ? $_POST[$paramname] : (isset($_GET[$paramname]) ? $_GET[$paramname] : '');
+ } else {
+ $val = 'BadFirstParameterForGETPOST';
+ }
+
+ return is_array($val);
+}
+
/**
* Return value of a param into GET or POST supervariable.
* Use the property $user->default_values[path]['createform'] and/or $user->default_values[path]['filters'] and/or $user->default_values[path]['sortorder']
@@ -660,11 +686,11 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null
$tmpcheck = 'alphanohtml';
}
foreach ($out as $outkey => $outval) {
- $out[$outkey] = checkVal($outval, $tmpcheck, $filter, $options);
+ $out[$outkey] = sanitizeVal($outval, $tmpcheck, $filter, $options);
}
}
} else {
- $out = checkVal($out, $check, $filter, $options);
+ $out = sanitizeVal($out, $check, $filter, $options);
}
// Sanitizing for special parameters.
@@ -713,9 +739,11 @@ function GETPOSTINT($paramname, $method = 0)
return (int) GETPOST($paramname, 'int', $method, null, null, 0);
}
+
/**
- * Return a value after checking on a rule. A sanitization may also have been done.
+ * Return a sanitized or empty value after checking value against a rule.
*
+ * @deprecated
* @param string|array $out Value to check/clear.
* @param string $check Type of check/sanitizing
* @param int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails)
@@ -723,9 +751,24 @@ function GETPOSTINT($paramname, $method = 0)
* @return string|array Value sanitized (string or array). It may be '' if format check fails.
*/
function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options = null)
+{
+ return sanitizeVal($out, $check, $filter, $options);
+}
+
+/**
+ * Return a sanitized or empty value after checking value against a rule.
+ *
+ * @param string|array $out Value to check/clear.
+ * @param string $check Type of check/sanitizing
+ * @param int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails)
+ * @param mixed $options Options to pass to filter_var when $check is set to 'custom'
+ * @return string|array Value sanitized (string or array). It may be '' if format check fails.
+ */
+function sanitizeVal($out = '', $check = 'alphanohtml', $filter = null, $options = null)
{
global $conf;
+ // TODO : use class "Validate" to perform tests (and add missing tests) if needed for factorize
// Check is done after replacement
switch ($check) {
case 'none':
diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
index 3dc1ab6c4fd..b3788d776a0 100644
--- a/htdocs/core/menus/standard/eldy.lib.php
+++ b/htdocs/core/menus/standard/eldy.lib.php
@@ -807,7 +807,6 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
if ($mainmenu == 'hrm') {
get_left_menu_hrm($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user);
}
-
/*
* Menu TOOLS
*/
@@ -2262,19 +2261,19 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
// Load translation files required by the page
$langs->loadLangs(array("holiday", "trips"));
- $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'holiday', 'class="pictofixedwidth"'));
- $newmenu->add("/holiday/card.php?mainmenu=hrm&leftmenu=holiday&action=create", $langs->trans("New"), 1, $user->rights->holiday->write);
- $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->holiday->read);
- if ($usemenuhider || empty($leftmenu) || $leftmenu == "hrm") {
- $newmenu->add("/holiday/list.php?search_status=1&mainmenu=hrm&leftmenu=hrm", $langs->trans("DraftCP"), 2, $user->rights->holiday->read);
- $newmenu->add("/holiday/list.php?search_status=2&mainmenu=hrm&leftmenu=hrm", $langs->trans("ToReviewCP"), 2, $user->rights->holiday->read);
- $newmenu->add("/holiday/list.php?search_status=3&mainmenu=hrm&leftmenu=hrm", $langs->trans("ApprovedCP"), 2, $user->rights->holiday->read);
- $newmenu->add("/holiday/list.php?search_status=4&mainmenu=hrm&leftmenu=hrm", $langs->trans("CancelCP"), 2, $user->rights->holiday->read);
- $newmenu->add("/holiday/list.php?search_status=5&mainmenu=hrm&leftmenu=hrm", $langs->trans("RefuseCP"), 2, $user->rights->holiday->read);
+ $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'holiday', 0, '', '', '', img_picto('', 'holiday', 'class="pictofixedwidth"'));
+ $newmenu->add("/holiday/card.php?mainmenu=hrm&leftmenu=holiday&action=create", $langs->trans("New"), 1, $user->rights->holiday->write, '', $mainmenu);
+ $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("List"), 1, $user->rights->holiday->read, '', $mainmenu);
+ if ($usemenuhider || empty($leftmenu) || $leftmenu == "holiday") {
+ $newmenu->add("/holiday/list.php?search_status=1&mainmenu=hrm&leftmenu=holiday", $langs->trans("DraftCP"), 2, $user->rights->holiday->read, '', $mainmenu, 'holiday_sm');
+ $newmenu->add("/holiday/list.php?search_status=2&mainmenu=hrm&leftmenu=holiday", $langs->trans("ToReviewCP"), 2, $user->rights->holiday->read, '', $mainmenu, 'holiday_sm');
+ $newmenu->add("/holiday/list.php?search_status=3&mainmenu=hrm&leftmenu=holiday", $langs->trans("ApprovedCP"), 2, $user->rights->holiday->read, '', $mainmenu, 'holiday_sm');
+ $newmenu->add("/holiday/list.php?search_status=4&mainmenu=hrm&leftmenu=holiday", $langs->trans("CancelCP"), 2, $user->rights->holiday->read, '', $mainmenu, 'holiday_sm');
+ $newmenu->add("/holiday/list.php?search_status=5&mainmenu=hrm&leftmenu=holiday", $langs->trans("RefuseCP"), 2, $user->rights->holiday->read, '', $mainmenu, 'holiday_sm');
}
- $newmenu->add("/holiday/define_holiday.php?mainmenu=hrm&action=request", $langs->trans("MenuConfCP"), 1, $user->rights->holiday->read);
- $newmenu->add("/holiday/month_report.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("MenuReportMonth"), 1, $user->rights->holiday->readall);
- $newmenu->add("/holiday/view_log.php?mainmenu=hrm&leftmenu=holiday&action=request", $langs->trans("MenuLogCP"), 1, $user->rights->holiday->define_holiday);
+ $newmenu->add("/holiday/define_holiday.php?mainmenu=hrm&action=request", $langs->trans("MenuConfCP"), 1, $user->rights->holiday->read, '', $mainmenu, 'holiday_sm');
+ $newmenu->add("/holiday/month_report.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("MenuReportMonth"), 1, $user->rights->holiday->readall, '', $mainmenu, 'holiday_sm');
+ $newmenu->add("/holiday/view_log.php?mainmenu=hrm&leftmenu=holiday&action=request", $langs->trans("MenuLogCP"), 1, $user->rights->holiday->define_holiday, '', $mainmenu, 'holiday_sm');
}
// Trips and expenses (old module)
@@ -2316,6 +2315,7 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
}
}
+
/**
* Get left Menu TOOLS
*
diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php
index 2c59b6b3172..b43ead29e7f 100644
--- a/htdocs/core/modules/modResource.class.php
+++ b/htdocs/core/modules/modResource.class.php
@@ -91,7 +91,7 @@ class modResource extends DolibarrModules
// Dependencies
// List of modules id that must be enabled if this module is enabled
- $this->depends = array('modResource');
+ $this->depends = array();
// List of modules id to disable if this one is disabled
$this->requiredby = array('modPlace');
// Minimum version of PHP required by module
diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php
index 4ba40384648..0c3d98f03a6 100644
--- a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php
+++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php
@@ -48,7 +48,7 @@ if (!empty($extrafieldsobjectkey) && !empty($search_array_options) && is_array($
}
$sql .= ")";
}
- } elseif ($crit != '' && (!in_array($typ, array('select', 'sellist')) || $crit != '0') && (!in_array($typ, array('link')) || $crit != '-1')) {
+ } elseif ($crit != '' && (!in_array($typ, array('select', 'sellist', 'select')) || $crit != '0') && (!in_array($typ, array('link')) || $crit != '-1')) {
$mode_search = 0;
if (in_array($typ, array('int', 'double', 'real', 'price'))) {
$mode_search = 1; // Search on a numeric
@@ -59,13 +59,14 @@ if (!empty($extrafieldsobjectkey) && !empty($search_array_options) && is_array($
if (in_array($typ, array('sellist')) && !is_numeric($crit)) {
$mode_search = 0;// Search on a foreign key string
}
- if (in_array($typ, array('chkbxlst', 'checkbox'))) {
+ if (in_array($typ, array('chkbxlst', 'checkbox', 'select'))) {
$mode_search = 4; // Search on a multiselect field with sql type = text
}
if (is_array($crit)) {
$crit = implode(' ', $crit); // natural_search() expects a string
- } elseif ($typ === 'select' and is_string($crit) and strpos($crit, ' ') === false) {
- $sql .= " AND (".$extrafieldsobjectprefix.$tmpkey." = '".$db->escape($crit)."')";
+ } elseif ($typ === 'select' and is_string($crit) and strpos($crit, ',') === false) {
+ $critSelect = "'".implode("','", array_map(array($db, 'escape'), explode(',', $crit)))."'";
+ $sql .= " AND (".$extrafieldsobjectprefix.$tmpkey." IN (".$db->sanitize($critSelect, 1).") )";
continue;
}
$sql .= natural_search($extrafieldsobjectprefix.$tmpkey, $crit, $mode_search);
diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php
index 508db07c65e..19a3577d5f1 100644
--- a/htdocs/emailcollector/class/emailcollector.class.php
+++ b/htdocs/emailcollector/class/emailcollector.class.php
@@ -901,9 +901,17 @@ class EmailCollector extends CommonObject
// Overwrite param $tmpproperty
$valueextracted = isset($regforval[count($regforval) - 1]) ?trim($regforval[count($regforval) - 1]) : null;
if (strtolower($sourcefield) == 'header') {
- $object->$tmpproperty = $this->decodeSMTPSubject($valueextracted);
+ if (preg_match('/^options_/', $tmpproperty)) {
+ $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $this->decodeSMTPSubject($valueextracted);
+ } else {
+ $object->$tmpproperty = $this->decodeSMTPSubject($valueextracted);
+ }
} else {
- $object->$tmpproperty = $valueextracted;
+ if (preg_match('/^options_/', $tmpproperty)) {
+ $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $this->decodeSMTPSubject($valueextracted);
+ } else {
+ $object->$tmpproperty = $this->decodeSMTPSubject($valueextracted);
+ }
}
} else {
// Regex not found
diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php
index 402fbdc04d1..357683ef35a 100644
--- a/htdocs/expedition/class/api_shipments.class.php
+++ b/htdocs/expedition/class/api_shipments.class.php
@@ -279,8 +279,8 @@ class Shipments extends DolibarrApi
$request_data = (object) $request_data;
- $request_data->desc = checkVal($request_data->desc, 'restricthtml');
- $request_data->label = checkVal($request_data->label);
+ $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
+ $request_data->label = sanitizeVal($request_data->label);
$updateRes = $this->shipment->addline(
$request_data->desc,
@@ -347,8 +347,8 @@ class Shipments extends DolibarrApi
$request_data = (object) $request_data;
- $request_data->desc = checkVal($request_data->desc, 'restricthtml');
- $request_data->label = checkVal($request_data->label);
+ $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
+ $request_data->label = sanitizeVal($request_data->label);
$updateRes = $this->shipment->updateline(
$lineid,
diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php
index 37319a3ec71..876b08f18f0 100644
--- a/htdocs/expensereport/class/api_expensereports.class.php
+++ b/htdocs/expensereport/class/api_expensereports.class.php
@@ -251,8 +251,8 @@ class ExpenseReports extends DolibarrApi
$request_data = (object) $request_data;
- $request_data->desc = checkVal($request_data->desc, 'restricthtml');
- $request_data->label = checkVal($request_data->label);
+ $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
+ $request_data->label = sanitizeVal($request_data->label);
$updateRes = $this->expensereport->addline(
$request_data->desc,
@@ -319,8 +319,8 @@ class ExpenseReports extends DolibarrApi
$request_data = (object) $request_data;
- $request_data->desc = checkVal($request_data->desc, 'restricthtml');
- $request_data->label = checkVal($request_data->label);
+ $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
+ $request_data->label = sanitizeVal($request_data->label);
$updateRes = $this->expensereport->updateline(
$lineid,
diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php
index f25192578be..883ba7ea11e 100644
--- a/htdocs/exports/class/export.class.php
+++ b/htdocs/exports/class/export.class.php
@@ -302,7 +302,7 @@ class Export
public function build_filterQuery($TypeField, $NameField, $ValueField)
{
// phpcs:enable
- $NameField = checkVal($NameField, 'aZ09');
+ $NameField = sanitizeVal($NameField, 'aZ09');
$szFilterQuery = '';
//print $TypeField." ".$NameField." ".$ValueField;
diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php
index eeb5261ef19..b7ee235c907 100644
--- a/htdocs/fichinter/card.php
+++ b/htdocs/fichinter/card.php
@@ -5,7 +5,7 @@
* Copyright (C) 2011-2020 Juanjo Menent
* Copyright (C) 2013 Florian Henry
* Copyright (C) 2014-2018 Ferran Marcet
- * Copyright (C) 2014-2018 Charlene Benke
+ * Copyright (C) 2014-2022 Charlene Benke
* Copyright (C) 2015-2016 Abbes Bahfir
* Copyright (C) 2018 Philippe Grand
* Copyright (C) 2020 Frédéric France
@@ -65,6 +65,7 @@ $mesg = GETPOST('msg', 'alpha');
$origin = GETPOST('origin', 'alpha');
$originid = (GETPOST('originid', 'int') ?GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility
$note_public = GETPOST('note_public', 'restricthtml');
+$note_private = GETPOST('note_private', 'restricthtml');
$lineid = GETPOST('line_id', 'int');
$error = 0;
@@ -79,6 +80,7 @@ $hookmanager->initHooks(array('interventioncard', 'globalcard'));
$object = new Fichinter($db);
$extrafields = new ExtraFields($db);
+$objectsrc = null;
$extrafields->fetch_name_optionals_label($object->table_element);
diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php
index 9497a3daa5f..418d8fa6600 100644
--- a/htdocs/fourn/class/api_supplier_invoices.class.php
+++ b/htdocs/fourn/class/api_supplier_invoices.class.php
@@ -558,8 +558,8 @@ class SupplierInvoices extends DolibarrApi
$request_data = (object) $request_data;
- $request_data->description = checkVal($request_data->description, 'restricthtml');
- $request_data->ref_supplier = checkVal($request_data->ref_supplier);
+ $request_data->description = sanitizeVal($request_data->description, 'restricthtml');
+ $request_data->ref_supplier = sanitizeVal($request_data->ref_supplier);
$updateRes = $this->invoice->addline(
$request_data->description,
@@ -625,8 +625,8 @@ class SupplierInvoices extends DolibarrApi
$request_data = (object) $request_data;
- $request_data->description = checkVal($request_data->description, 'restricthtml');
- $request_data->ref_supplier = checkVal($request_data->ref_supplier);
+ $request_data->description = sanitizeVal($request_data->description, 'restricthtml');
+ $request_data->ref_supplier = sanitizeVal($request_data->ref_supplier);
$updateRes = $this->invoice->updateline(
$lineid,
diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql
index b041e07b95f..d78fea4ad4d 100644
--- a/htdocs/install/mysql/data/llx_c_tva.sql
+++ b/htdocs/install/mysql/data/llx_c_tva.sql
@@ -400,5 +400,7 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (23
--delete from llx_c_tva where rowid = 1181; -- to delete a record that does not follow rules for rowid (fk_pays+'1')
--insert into llx_c_tva(rowid, fk_pays, taux, recuperableonly, note, active) SELECT CONCAT(c.rowid, '1'), c.rowid, 0, 0, 'No VAT', 1 from llx_c_country as c where c.rowid not in (select fk_pays from llx_c_tva);
-
-
+-- BURUNDI (id country=61) -- https://www.objectif-import-export.fr/fr/marches-internationaux/fiche-pays/burundi/presentation-fiscalite
+insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2335,61, '0','0','No VAT',1);
+insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2336,61, '10','0','VAT 10%',1);
+insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2337,61, '18','0','VAT 18%',1);
diff --git a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php
index 5d26fa90137..b95a5717932 100644
--- a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php
+++ b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php
@@ -19,6 +19,7 @@
use Luracast\Restler\RestException;
dol_include_once('/knowledgemanagement/class/knowledgerecord.class.php');
+dol_include_once('/categories/class/categorie.class.php');
@@ -85,6 +86,39 @@ class KnowledgeManagement extends DolibarrApi
return $this->_cleanObjectDatas($this->knowledgerecord);
}
+ /**
+ * Get categories for a knowledgerecord object
+ *
+ * @param int $id ID of knowledgerecord object
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ *
+ * @return mixed
+ *
+ * @url GET /knowledgerecords/{id}/categories
+ */
+ public function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
+ {
+ if (!DolibarrApiAccess::$user->rights->categorie->lire) {
+ throw new RestException(401);
+ }
+
+ $categories = new Categorie($this->db);
+
+ $result = $categories->getListForItem($id, 'knowledgemanagement', $sortfield, $sortorder, $limit, $page);
+
+ if (empty($result)) {
+ throw new RestException(404, 'No category found');
+ }
+
+ if ($result < 0) {
+ throw new RestException(503, 'Error when retrieve category list : '.array_merge(array($categories->error), $categories->errors));
+ }
+
+ return $result;
+ }
/**
* List knowledgerecords
@@ -218,7 +252,7 @@ class KnowledgeManagement extends DolibarrApi
}
// Clean data
- // $this->knowledgerecord->abc = checkVal($this->knowledgerecord->abc, 'alphanohtml');
+ // $this->knowledgerecord->abc = sanitizeVal($this->knowledgerecord->abc, 'alphanohtml');
if ($this->knowledgerecord->create(DolibarrApiAccess::$user)<0) {
throw new RestException(500, "Error creating KnowledgeRecord", array_merge(array($this->knowledgerecord->error), $this->knowledgerecord->errors));
@@ -260,7 +294,7 @@ class KnowledgeManagement extends DolibarrApi
}
// Clean data
- // $this->knowledgerecord->abc = checkVal($this->knowledgerecord->abc, 'alphanohtml');
+ // $this->knowledgerecord->abc = sanitizeVal($this->knowledgerecord->abc, 'alphanohtml');
if ($this->knowledgerecord->update(DolibarrApiAccess::$user, false) > 0) {
return $this->get($id);
diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang
index 224273d84e6..7f29b774b29 100644
--- a/htdocs/langs/en_US/mrp.lang
+++ b/htdocs/langs/en_US/mrp.lang
@@ -109,6 +109,6 @@ THMEstimatedHelp=This rate makes it possible to define a forecast cost of the it
BOM=Bill Of Materials
CollapseBOMHelp=You can define the default display of the details of the nomenclature in the configuration of the BOM module
MOAndLines=Manufacturing Orders and lines
-BOMNetNeeds=Net Needs
-TreeStructure=Tree structure
-GroupByProduct=Group by product
\ No newline at end of file
+MoChildGenerate=Generate Child Mo
+ParentMo=MO Parent
+MOChild=MO Child
diff --git a/htdocs/langs/en_US/receiptprinter.lang b/htdocs/langs/en_US/receiptprinter.lang
index eb115682726..2b4fe7d6125 100644
--- a/htdocs/langs/en_US/receiptprinter.lang
+++ b/htdocs/langs/en_US/receiptprinter.lang
@@ -55,6 +55,8 @@ DOL_DEFAULT_HEIGHT_WIDTH=Default height and width size
DOL_UNDERLINE=Enable underline
DOL_UNDERLINE_DISABLED=Disable underline
DOL_BEEP=Beep sound
+DOL_BEEP_ALTERNATIVE=Beep sound (alternative mode)
+DOL_PRINT_CURR_DATE=Print current date/time
DOL_PRINT_TEXT=Print text
DateInvoiceWithTime=Invoice date and time
YearInvoice=Invoice year
diff --git a/htdocs/langs/it_IT/receiptprinter.lang b/htdocs/langs/it_IT/receiptprinter.lang
index 49621049ddf..566f762bbbd 100644
--- a/htdocs/langs/it_IT/receiptprinter.lang
+++ b/htdocs/langs/it_IT/receiptprinter.lang
@@ -55,6 +55,8 @@ DOL_DEFAULT_HEIGHT_WIDTH=Altezza e larghezza predefinite
DOL_UNDERLINE=Abilita sottolineatura
DOL_UNDERLINE_DISABLED=Disabilita la sottolineatura
DOL_BEEP=Suono di Beep
+DOL_BEEP_ALTERNATIVE=Suono di Beep (modalità alternativa)
+DOL_PRINT_CURR_DATE=Stampa la data/ora corrente
DOL_PRINT_TEXT=Stampa il testo
DateInvoiceWithTime=Data e ora della fattura
YearInvoice=Anno della fattura
diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php
index 04bf641930d..736fd9ddc38 100644
--- a/htdocs/modulebuilder/template/class/api_mymodule.class.php
+++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php
@@ -218,7 +218,7 @@ class MyModuleApi extends DolibarrApi
}
// Clean data
- // $this->myobject->abc = checkVal($this->myobject->abc, 'alphanohtml');
+ // $this->myobject->abc = sanitizeVal($this->myobject->abc, 'alphanohtml');
if ($this->myobject->create(DolibarrApiAccess::$user)<0) {
throw new RestException(500, "Error creating MyObject", array_merge(array($this->myobject->error), $this->myobject->errors));
@@ -260,7 +260,7 @@ class MyModuleApi extends DolibarrApi
}
// Clean data
- // $this->myobject->abc = checkVal($this->myobject->abc, 'alphanohtml');
+ // $this->myobject->abc = sanitizeVal($this->myobject->abc, 'alphanohtml');
if ($this->myobject->update(DolibarrApiAccess::$user, false) > 0) {
return $this->get($id);
diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php
index f742a04a619..b99d03050ce 100644
--- a/htdocs/mrp/class/mo.class.php
+++ b/htdocs/mrp/class/mo.class.php
@@ -120,6 +120,7 @@ class Mo extends CommonObject
'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,),
'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>1010),
'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>2, 'position'=>1000, 'default'=>0, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '2'=>'InProgress', '3'=>'StatusMOProduced', '9'=>'Canceled')),
+ 'fk_parent_line' => array('type'=>'integer:MoLine:mrp/class/mo.class.php', 'label'=>'ParentMo', 'enabled'=>1, 'visible'=>0, 'position'=>1020, 'default'=>0, 'notnull'=>0, 'index'=>1,'showoncombobox'=>0),
);
public $rowid;
public $entity;
@@ -201,6 +202,11 @@ class Mo extends CommonObject
*/
public $lines = array();
+ /**
+ * @var integer Mo parent line
+ * */
+
+ public $fk_parent_line;
/**
@@ -1267,15 +1273,18 @@ class Mo extends CommonObject
/**
* Create an array of lines
- *
+ * @param string $rolefilter string lines role filter
* @return array|int array of lines if OK, <0 if KO
*/
- public function getLinesArray()
+ public function getLinesArray($rolefilter = '')
{
$this->lines = array();
$objectline = new MoLine($this->db);
- $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_mo = '.((int) $this->id)));
+
+ $TFilters = array('customsql'=>'fk_mo = '.((int) $this->id));
+ if (!empty($rolefilter)) $TFilters['role'] = $rolefilter;
+ $result = $objectline->fetchAll('ASC', 'position', 0, 0, $TFilters);
if (is_numeric($result)) {
$this->error = $this->error;
@@ -1380,6 +1389,13 @@ class Mo extends CommonObject
$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE) ? '- '.$langs->trans("StockOnReception").'
' : '');
print '';
+ // Product or sub-bom
+ print '| '.$langs->trans('Description');
+ if (!empty($conf->global->BOM_SUB_BOM)) {
+ print ' '.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").' ';
+ print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").' ';
+ }
+ print ' | ';
print ''.$langs->trans('Ref').' | ';
print ''.$langs->trans('Qty');
if ($this->bom->bomtype == 0) {
@@ -1392,9 +1408,9 @@ class Mo extends CommonObject
print ' | '.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).' | ';
print ''.$langs->trans('QtyFrozen').' | ';
print ''.$langs->trans('DisableStockChange').' | ';
- //print ''.$langs->trans('Efficiency').' | ';
+ print ''.$langs->trans('MoChildGenerate').' | ';
//print ''.$form->showCheckAddButtons('checkforselect', 1).' | ';
- print ' | ';
+ // print ' | ';
print '
';
$i = 0;
@@ -1478,6 +1494,81 @@ class Mo extends CommonObject
return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
}
+
+
+ /**
+ * Function used to return childs of Mo
+ *
+ * @return array if OK, -1 if KO
+ */
+ public function getMoChilds()
+ {
+
+ $TMoChilds = array();
+ $error = 0;
+
+ $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."mrp_mo as mo_child";
+ $sql.= " WHERE fk_parent_line IN ";
+ $sql.= " (SELECT rowid FROM ".MAIN_DB_PREFIX."mrp_production as line_parent";
+ $sql.= " WHERE fk_mo=".((int) $this->id).")";
+
+ $resql = $this->db->query($sql);
+
+ if ($resql) {
+ if ($this->db->num_rows($resql) > 0) {
+ while ($obj = $this->db->fetch_object($resql)) {
+ $MoChild = new Mo($this->db);
+ $res = $MoChild->fetch($obj->rowid);
+ if ($res > 0) $TMoChilds[$MoChild->id] = $MoChild;
+ else $error++;
+ }
+ }
+ } else {
+ $error++;
+ }
+
+ if ($error) {
+ return -1;
+ } else {
+ return $TMoChilds;
+ }
+ }
+
+ /**
+ * Function used to return childs of Mo
+ *
+ * @return object Mo if OK, -1 if KO, 0 if not exist
+ */
+ public function getMoParent()
+ {
+
+ $MoParent = new Mo($this->db);
+ $error = 0;
+
+ $sql = "SELECT lineparent.fk_mo as id_moparent FROM ".MAIN_DB_PREFIX."mrp_mo as mo";
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."mrp_production lineparent ON mo.fk_parent_line = lineparent.rowid";
+ $sql.= " WHERE mo.rowid = ".((int) $this->id);
+
+ $resql = $this->db->query($sql);
+
+ if ($resql) {
+ if ($this->db->num_rows($resql) > 0) {
+ $obj = $this->db->fetch_object($resql);
+ $res = $MoParent->fetch($obj->id_moparent);
+ if ($res < 0) $error++;
+ } else {
+ return 0;
+ }
+ } else {
+ $error++;
+ }
+
+ if ($error) {
+ return -1;
+ } else {
+ return $MoParent;
+ }
+ }
}
/**
@@ -1671,7 +1762,7 @@ class MoLine extends CommonObjectLine
if ($resql) {
$num = $this->db->num_rows($resql);
$i = 0;
- while ($i < min($limit, $num)) {
+ while ($i < ($limit ? min($limit, $num) : $num)) {
$obj = $this->db->fetch_object($resql);
$record = new self($this->db);
diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php
index 48f64b2601c..70aebccad16 100644
--- a/htdocs/mrp/mo_card.php
+++ b/htdocs/mrp/mo_card.php
@@ -31,6 +31,8 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php';
require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
+require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php';
+
// Load translation files required by the page
$langs->loadLangs(array("mrp", "other"));
@@ -44,6 +46,7 @@ $cancel = GETPOST('cancel', 'aZ09');
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'mocard'; // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha');
$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
+$TBomLineId = GETPOST('bomlineid', 'array');
//$lineid = GETPOST('lineid', 'int');
// Initialize technical objects
@@ -128,9 +131,41 @@ if (empty($reshook)) {
if ($cancel && !empty($backtopageforcancel)) {
$backtopage = $backtopageforcancel;
}
-
$triggermodname = 'MRP_MO_MODIFY'; // Name of trigger action code to execute when we modify record
+ //Create MO with Childs
+ if ($action == 'add' && empty($id) && !empty($TBomLineId)) {
+ $noback = 0;
+ include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
+
+ $mo_parent = $object;
+
+ $moline = new MoLine($db);
+ $objectbomchildline = new BOMLine($db);
+
+ foreach ($TBomLineId as $id_bom_line) {
+ $object = new Mo($db);
+
+ $objectbomchildline->fetch($id_bom_line);
+
+ $TMoLines = $moline->fetchAll('DESC', 'rowid', '1', '', array('origin_id' => $id_bom_line));
+
+ foreach ($TMoLines as $moline) {
+ $_POST['fk_bom'] = $objectbomchildline->fk_bom_child;
+ $_POST['fk_parent_line'] = $moline->id;
+ $_POST['qty'] = $moline->qty;
+ $_POST['fk_product'] = $moline->fk_product;
+ }
+
+ include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
+
+ $res = $object->add_object_linked('mo', $mo_parent->id);
+ }
+
+ header("Location: ".dol_buildpath('/mrp/mo_list.php', 1));
+ exit;
+ }
+
// Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
@@ -240,10 +275,12 @@ if ($action == 'create') {
print dol_get_fiche_end();
+ print mrpCollapseBomManagement();
+
?>