diff --git a/ChangeLog b/ChangeLog index 790d5b329b8..f5a53161ae1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -233,10 +233,8 @@ FIX: #18704 FIX: #20444 FIX: #20448 missing preg_replace for vat rate when adding a free line FIX: #20476 migration postgresql 13.0.x to 14.0.x packaging type -FIX: #20487 missing letter D in constant THIRDPARTIES_DISABLE_RELATED_… FIX: #20487 missing letter D in constant THIRDPARTIES_DISABLE_RELATED_OBJECT_TAB FIX: #20527 Accountancy - Unbalanced entry proposed when an employee are declared on a social contribution -FIX: #20527 Accountancy Unbalanced entry proposed when an employee are declared on social contribution FIX: #20621 signature online with proposal with n page. FIX: #20696 FIX: #20828 @@ -272,7 +270,7 @@ FIX: fourn/commande/card.php Added "$object" parameter to $formfile->showdocumen FIX: french traductions for payment methods FIX: hook for dol_format_address FIX: Index page for "Sales" give wrong URL link to Intervention -FIX: issue Dolibarr#21495 for v15 +FIX: issue Dolibarr #21495 for v15 FIX: label and get_substitutionarray_each_var_object on ODT generation FIX: load product stock in inventory lines FIX: missing morecss for multiselectarray diff --git a/dev/initdemo/initdemopassword.sh b/dev/initdemo/initdemopassword.sh index 37264fb8e4d..12b09a02186 100755 --- a/dev/initdemo/initdemopassword.sh +++ b/dev/initdemo/initdemopassword.sh @@ -174,7 +174,7 @@ if [ -s "$mydir/initdemopostsql.sql" ]; then echo A file initdemopostsql.sql was found, we execute it. mysql -P$port $base < "$mydir/initdemopostsql.sql" else - echo No file initdemopostsql.sql found, we extra sql action done. + echo No file initdemopostsql.sql found, so no extra sql action done. fi diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 895437ab58b..afd7724713d 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -81,22 +81,22 @@ $list_account[] = '---Others---'; $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT'; -if (!empty($conf->banque->enabled)) { +if (isModEnabled('banque')) { $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH'; } -if (!empty($conf->don->enabled)) { +if (isModEnabled('don')) { $list_account[] = 'DONATION_ACCOUNTINGACCOUNT'; } -if (!empty($conf->adherent->enabled)) { +if (isModEnabled('adherent')) { $list_account[] = 'ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT'; } -if (!empty($conf->loan->enabled)) { +if (isModEnabled('loan')) { $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL'; $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INTEREST'; $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE'; } $list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE'; -if (!empty($conf->societe->enabled)) { +if (isModEnabled('societe')) { $list_account[] = '---Deposits---'; } @@ -266,7 +266,7 @@ print $formaccounting->select_account(getDolGlobalString('ACCOUNTING_ACCOUNT_CUS print ''; print ''; -if (!empty($conf->societe->enabled) && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') != '-1') { +if (isModEnabled('societe') && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') != '-1') { print ''; print '' . img_picto('', 'bill', 'class="pictofixedwidth"') . $langs->trans("UseAuxiliaryAccountOnCustomerDeposit") . ''; if (getDolGlobalInt('ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT')) { diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php index 3dcab7a9c4c..c8282179fe5 100644 --- a/htdocs/adherents/document.php +++ b/htdocs/adherents/document.php @@ -128,7 +128,7 @@ if ($id > 0) { $totalsize += $file['size']; } - if (!empty($conf->notification->enabled)) { + if (isModEnabled('notification')) { $langs->load("mails"); } diff --git a/htdocs/adherents/htpasswd.php b/htdocs/adherents/htpasswd.php index 60639193295..0a7073f96b0 100644 --- a/htdocs/adherents/htpasswd.php +++ b/htdocs/adherents/htpasswd.php @@ -33,7 +33,7 @@ $sortfield = GETPOST('sortfield', 'alphanohtml'); $sortorder = GETPOST('sortorder', 'aZ09'); // Security check -if (empty($conf->adherent->enabled)) { +if (!isModEnabled('adherent')) { accessforbidden(); } if (empty($user->rights->adherent->export)) { diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 1995485eb4e..f9208daf70d 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -659,7 +659,7 @@ if ($sall) { // Filter on categories $moreforfilter = ''; -if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { +if (isModEnabled('categorie') && $user->rights->categorie->lire) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedlength"').$formother->select_categories(Categorie::TYPE_MEMBER, $search_categ, 'search_categ', 1); diff --git a/htdocs/adherents/partnership.php b/htdocs/adherents/partnership.php index a01e7d28ed2..bc21d4b6333 100644 --- a/htdocs/adherents/partnership.php +++ b/htdocs/adherents/partnership.php @@ -88,7 +88,7 @@ $upload_dir = $conf->partnership->multidir_output[isset($object->entity) ? $o if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') != 'member') { accessforbidden('Partnership module is not activated for members'); } -if (empty($conf->partnership->enabled)) { +if (!isModEnabled('partnership')) { accessforbidden(); } if (empty($permissiontoread)) { diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index 1a4f5873e33..4957d5fb513 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -190,7 +190,7 @@ foreach ($dirbarcode as $reldir) { // Select barcode numbering module -if ($conf->product->enabled) { +if (isModEnabled('product')) { print load_fiche_titre($langs->trans("BarCodeNumberManager")." (".$langs->trans("Product").")", '', ''); print '
'; @@ -252,7 +252,7 @@ if ($conf->product->enabled) { } // Select barcode numbering module -if ($conf->societe->enabled) { +if (isModEnabled('societe')) { print load_fiche_titre($langs->trans("BarCodeNumberManager")." (".$langs->trans("ThirdParty").")", '', ''); print '
'; @@ -450,7 +450,7 @@ if (!isset($_SERVER['WINDIR'])) { } // Module products -if (!empty($conf->product->enabled)) { +if (isModEnabled('product')) { print ''; print ''.$langs->trans("SetDefaultBarcodeTypeProducts").''; print ''; @@ -461,7 +461,7 @@ if (!empty($conf->product->enabled)) { } // Module thirdparty -if (!empty($conf->societe->enabled)) { +if (isModEnabled('societe')) { print ''; print ''.$langs->trans("SetDefaultBarcodeTypeThirdParties").''; print ''; diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index c72976f829e..af44c18bee6 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -466,7 +466,7 @@ print ''."\n"; // Barcode -if (!empty($conf->barcode->enabled)) { +if (isModEnabled('barcode')) { print ''; print ''; print ''; diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index bf4ac3f8979..9378fc28bbe 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -172,12 +172,12 @@ if ($action == 'add') { $action = 'create'; $error++; } - if (!$error && GETPOST('menuId') && GETPOST('type') == 'top') { + if (!$error && GETPOST('menuId', 'alphanohtml', 3) && GETPOST('type') == 'top') { setEventMessages($langs->trans("ErrorTopMenuMustHaveAParentWithId0"), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !GETPOST('menuId') && GETPOST('type') == 'left') { + if (!$error && !GETPOST('menuId', 'alphanohtml', 3) && GETPOST('type') == 'left') { setEventMessages($langs->trans("ErrorLeftMenuMustHaveAParentId"), null, 'errors'); $action = 'create'; $error++; diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 0ff1ddaca59..ad4befadad6 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -491,6 +491,17 @@ print '
'; print 'WEBSITE_MAIN_SECURITY_FORCECSP = '.(empty($conf->global->WEBSITE_MAIN_SECURITY_FORCECSP) ? ''.$langs->trans("Undefined").'' : $conf->global->WEBSITE_MAIN_SECURITY_FORCECSP).'   ('.$langs->trans("Example").": \"default-src 'self'; style-src: https://cdnjs.cloudflare.com https://fonts.googleapis.com; script-src: https://cdn.transifex.com https://www.googletagmanager.com; object-src https://youtube.com; frame-src https://youtube.com; img-src: *;\")
"; print '
'; +print 'MAIN_SECURITY_FORCERP = '.(empty($conf->global->MAIN_SECURITY_FORCERP) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_FORCERP).'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or")." \"same-origin\")
"; +print '
'; + +print 'WEBSITE_MAIN_SECURITY_FORCERP = '.(empty($conf->global->WEBSITE_MAIN_SECURITY_FORCERP) ? ''.$langs->trans("Undefined").'' : $conf->global->WEBSITE_MAIN_SECURITY_FORCERP).'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or")." \"strict-origin-when-cross-origin\")
"; +print '
'; + +print 'WEBSITE_MAIN_SECURITY_FORCESTS = '.(empty($conf->global->WEBSITE_MAIN_SECURITY_FORCESTS) ? ''.$langs->trans("Undefined").'' : $conf->global->WEBSITE_MAIN_SECURITY_FORCESTS).'   ('.$langs->trans("Example").": \"max-age=31536000; includeSubDomains\")
"; +print '
'; + +print 'WEBSITE_MAIN_SECURITY_FORCEPP = '.(empty($conf->global->WEBSITE_MAIN_SECURITY_FORCEPP) ? ''.$langs->trans("Undefined").'' : $conf->global->WEBSITE_MAIN_SECURITY_FORCEPP).'   ('.$langs->trans("Example").": \"camera: 'none'; microphone: 'none';\")
"; +print '
'; print '
'; diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php index ff0ecbf0d01..fe8ff50cf96 100644 --- a/htdocs/barcode/codeinit.php +++ b/htdocs/barcode/codeinit.php @@ -355,7 +355,7 @@ if (isModEnabled('societe')) { // For products -if ($conf->product->enabled || $conf->product->service) { +if (isModEnabled('product') || isModEnabled('service')) { print '
'; print ''; print ''; diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index ee619a589e3..5466fb54f8f 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -181,24 +181,10 @@ if (empty($reshook)) { } if (!$error) { - $bomline = new BOMLine($db); - $bomline->fk_bom = $id; - $bomline->fk_product = $idprod; - $bomline->fk_bom_child = $bom_child_id; - $bomline->qty = $qty; - $bomline->qty_frozen = (int) $qty_frozen; - $bomline->disable_stock_change = (int) $disable_stock_change; - $bomline->efficiency = $efficiency; + $result = $object->addLine($idprod, $qty, $qty_frozen, $disable_stock_change, $efficiency, -1, $bom_child_id, null); - // Rang to use - $rangmax = $object->line_max(0); - $ranktouse = $rangmax + 1; - - $bomline->position = ($ranktouse + 1); - - $result = $bomline->create($user); if ($result <= 0) { - setEventMessages($bomline->error, $bomline->errors, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $action = ''; } else { unset($_POST['idprod']); @@ -207,13 +193,11 @@ if (empty($reshook)) { unset($_POST['disable_stock_change']); $object->fetchLines(); - - $object->calculateCosts(); } } } - // Add line + // Update line if ($action == 'updateline' && $user->rights->bom->write) { $langs->load('errors'); $error = 0; @@ -229,26 +213,24 @@ if (empty($reshook)) { $error++; } - $bomline = new BOMLine($db); - $bomline->fetch($lineid); - $bomline->qty = $qty; - $bomline->qty_frozen = (int) $qty_frozen; - $bomline->disable_stock_change = (int) $disable_stock_change; - $bomline->efficiency = $efficiency; + if (!$error) { - $result = $bomline->update($user); - if ($result <= 0) { - setEventMessages($bomline->error, $bomline->errors, 'errors'); - $action = ''; - } else { - unset($_POST['idprod']); - unset($_POST['qty']); - unset($_POST['qty_frozen']); - unset($_POST['disable_stock_change']); + $bomline = new BOMLine($db); + $bomline->fetch($lineid); - $object->fetchLines(); + $result = $object->updateLine($lineid, $qty, (int)$qty_frozen, (int)$disable_stock_change, $efficiency, $bomline->position, $bomline->import_key); - $object->calculateCosts(); + if ($result <= 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $action = ''; + } else { + unset($_POST['idprod']); + unset($_POST['qty']); + unset($_POST['qty_frozen']); + unset($_POST['disable_stock_change']); + + $object->fetchLines(); + } } } } diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php index 91af888ffd8..fb7d175a229 100644 --- a/htdocs/bom/class/api_boms.class.php +++ b/htdocs/bom/class/api_boms.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2019 Maxime Kohlhaas * Copyright (C) 2020 Frédéric France + * Copyright (C) 2022 Christian Humpel * * 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 @@ -279,6 +280,177 @@ class Boms extends DolibarrApi ); } + /** + * Get lines of an BOM + * + * @param int $id Id of BOM + * + * @url GET {id}/lines + * + * @return array + */ + public function getLines($id) + { + if (!DolibarrApiAccess::$user->rights->bom->read) { + throw new RestException(401); + } + + $result = $this->bom->fetch($id); + if (!$result) { + throw new RestException(404, 'BOM not found'); + } + + if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $this->bom->getLinesArray(); + $result = array(); + foreach ($this->bom->lines as $line) { + array_push($result, $this->_cleanObjectDatas($line)); + } + return $result; + } + + /** + * Add a line to given BOM + * + * @param int $id Id of BOM to update + * @param array $request_data BOMLine data + * + * @url POST {id}/lines + * + * @return int + */ + public function postLine($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->bom->write) { + throw new RestException(401); + } + + $result = $this->bom->fetch($id); + if (!$result) { + throw new RestException(404, 'BOM not found'); + } + + if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $request_data = (object) $request_data; + + $updateRes = $this->bom->addLine( + $request_data->fk_product, + $request_data->qty, + $request_data->qty_frozen, + $request_data->disable_stock_change, + $request_data->efficiency, + $request_data->position, + $request_data->fk_bom_child, + $request_data->import_key + ); + + if ($updateRes > 0) { + return $updateRes; + } else { + throw new RestException(400, $this->bom->error); + } + } + + /** + * Update a line to given BOM + * + * @param int $id Id of BOM to update + * @param int $lineid Id of line to update + * @param array $request_data BOMLine data + * + * @url PUT {id}/lines/{lineid} + * + * @return array|bool + */ + public function putLine($id, $lineid, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->bom->write) { + throw new RestException(401); + } + + $result = $this->bom->fetch($id); + if (!$result) { + throw new RestException(404, 'BOM not found'); + } + + if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $request_data = (object) $request_data; + + $updateRes = $this->bom->updateLine( + $lineid, + $request_data->qty, + $request_data->qty_frozen, + $request_data->disable_stock_change, + $request_data->efficiency, + $request_data->position, + $request_data->import_key + ); + + if ($updateRes > 0) { + $result = $this->get($id); + unset($result->line); + return $this->_cleanObjectDatas($result); + } + return false; + } + + /** + * Delete a line to given BOM + * + * + * @param int $id Id of BOM to update + * @param int $lineid Id of line to delete + * + * @url DELETE {id}/lines/{lineid} + * + * @return int + * + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 + */ + public function deleteLine($id, $lineid) + { + if (!DolibarrApiAccess::$user->rights->bom->write) { + throw new RestException(401); + } + + $result = $this->bom->fetch($id); + if (!$result) { + throw new RestException(404, 'BOM not found'); + } + + if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + //Check the rowid is a line of current bom object + $lineIdIsFromObject = false; + foreach ($this->bom->lines as $bl) { + if ($bl->id == $lineid) { + $lineIdIsFromObject = true; + break; + } + } + if (!$lineIdIsFromObject) { + throw new RestException(500, 'Line to delete (rowid: '.$lineid.') is not a line of BOM (id: '.$this->bom->id.')'); + } + + $updateRes = $this->bom->deleteline(DolibarrApiAccess::$user, $lineid); + if ($updateRes > 0) { + return $this->get($id); + } else { + throw new RestException(405, $this->bom->error); + } + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 8adcac855c2..ec659502e60 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -502,6 +502,210 @@ class BOM extends CommonObject //return $this->deleteCommon($user, $notrigger, 1); } + /** + * Add an BOM line into database (linked to BOM) + * + * @param int $fk_product Id of product + * @param float $qty Quantity + * @param int $qty_frozen Frozen quantity + * @param int $disable_stock_change Disable stock change on using in MO + * @param float $efficiency Efficiency in MO + * @param int $position Position of BOM-Line in BOM-Lines + * @param int $fk_bom_child Id of BOM Child + * @param string $import_key Import Key + * @return int <0 if KO, Id of created object if OK + */ + public function addLine($fk_product, $qty, $qty_frozen = 0, $disable_stock_change = 0, $efficiency = 1.0, $position = -1, $fk_bom_child = null, $import_key = null) + { + + global $mysoc, $conf, $langs, $user; + + $logtext = "::addLine bomid=$this->id, qty=$qty, fk_product=$fk_product, qty_frozen=$qty_frozen, disable_stock_change=$disable_stock_change, efficiency=$efficiency"; + $logtext .= ", fk_bom_child=$fk_bom_child, import_key=$import_key"; + dol_syslog(get_class($this).$logtext, LOG_DEBUG); + + if ($this->statut == self::STATUS_DRAFT) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Clean parameters + if (empty($qty)) { + $qty = 0; + } + if (empty($qty_frozen)) { + $qty_frozen = 0; + } + if (empty($disable_stock_change)) { + $disable_stock_change = 0; + } + if (empty($efficiency)) { + $efficiency = 1.0; + } + if (empty($fk_bom_child)) { + $fk_bom_child = null; + } + if (empty($import_key)) { + $import_key = null; + } + if (empty($position)) { + $position = -1; + } + + $qty = price2num($qty); + $efficiency = price2num($efficiency); + $position = price2num($position); + + $this->db->begin(); + + // Rank to use + $rangMax = $this->line_max(); + $rankToUse = $position; + if ($rankToUse <= 0 or $rankToUse > $rangMax) { // New line after existing lines + $rankToUse = $rangMax + 1; + } else { // New line between the existing lines + foreach ($this->lines as $bl) { + if ($bl->position >= $rankToUse) { + $bl->position++; + $bl->update($user); + } + } + } + + // Insert line + $this->line = new BOMLine($this->db); + + $this->line->context = $this->context; + + $this->line->fk_bom = $this->id; + $this->line->fk_product = $fk_product; + $this->line->qty = $qty; + $this->line->qty_frozen = $qty_frozen; + $this->line->disable_stock_change = $disable_stock_change; + $this->line->efficiency = $efficiency; + $this->line->fk_bom_child = $fk_bom_child; + $this->line->import_key = $import_key; + $this->line->position = $rankToUse; + + $result = $this->line->create($user); + + if ($result > 0) { + $this->calculateCosts(); + $this->db->commit(); + return $result; + } else { + $this->error = $this->line->error; + dol_syslog(get_class($this)."::addLine error=".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } else { + dol_syslog(get_class($this)."::addLine status of BOM must be Draft to allow use of ->addLine()", LOG_ERR); + return -3; + } + } + + /** + * Update an BOM line into database + * + * @param int $rowid Id of line to update + * @param float $qty Quantity + * @param int $qty_frozen Frozen quantity + * @param int $disable_stock_change Disable stock change on using in MO + * @param float $efficiency Efficiency in MO + * @param int $position Position of BOM-Line in BOM-Lines + * @param int $fk_bom_child Id of BOM Child + * @param string $import_key Import Key + * @return int <0 if KO, Id of updated BOM-Line if OK + */ + public function updateLine($rowid, $qty, $qty_frozen = 0, $disable_stock_change = 0, $efficiency = 1.0, $position = -1, $import_key = null) + { + + global $mysoc, $conf, $langs, $user; + + $logtext = "::updateLine bomid=$this->id, qty=$qty, qty_frozen=$qty_frozen, disable_stock_change=$disable_stock_change, efficiency=$efficiency"; + $logtext .= ", import_key=$import_key"; + dol_syslog(get_class($this).$logtext, LOG_DEBUG); + + if ($this->statut == self::STATUS_DRAFT) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Clean parameters + if (empty($qty)) { + $qty = 0; + } + if (empty($qty_frozen)) { + $qty_frozen = 0; + } + if (empty($disable_stock_change)) { + $disable_stock_change = 0; + } + if (empty($efficiency)) { + $efficiency = 1.0; + } + if (empty($import_key)) { + $import_key = null; + } + if (empty($position)) { + $position = -1; + } + + $qty = price2num($qty); + $efficiency = price2num($efficiency); + $position = price2num($position); + + $this->db->begin(); + + //Fetch current line from the database and then clone the object and set it in $oldline property + $line = new BOMLine($this->db); + $line->fetch($rowid); + $line->fetch_optionals(); + + $staticLine = clone $line; + $line->oldcopy = $staticLine; + $this->line = $line; + $this->line->context = $this->context; + + // Rank to use + $rankToUse = (int) $position; + if ($rankToUse != $line->oldcopy->position) { // check if position have a new value + foreach ($this->lines as $bl) { + if ($bl->position >= $rankToUse AND $bl->position < ($line->oldcopy->position + 1)) { // move rank up + $bl->position++; + $bl->update($user); + } + if ($bl->position <= $rankToUse AND $bl->position > ($line->oldcopy->position)) { // move rank down + $bl->position--; + $bl->update($user); + } + } + } + + + $this->line->fk_bom = $this->id; + $this->line->qty = $qty; + $this->line->qty_frozen = $qty_frozen; + $this->line->disable_stock_change = $disable_stock_change; + $this->line->efficiency = $efficiency; + $this->line->import_key = $import_key; + $this->line->position = $rankToUse; + + $result = $this->line->update($user); + + if ($result > 0) { + $this->calculateCosts(); + $this->db->commit(); + return $result; + } else { + $this->error = $this->line->error; + dol_syslog(get_class($this)."::addLine error=".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } else { + dol_syslog(get_class($this)."::addLine status of BOM must be Draft to allow use of ->addLine()", LOG_ERR); + return -3; + } + } + /** * Delete a line of object in database * @@ -517,7 +721,38 @@ class BOM extends CommonObject return -2; } - return $this->deleteLineCommon($user, $idline, $notrigger); + $this->db->begin(); + + //Fetch current line from the database and then clone the object and set it in $oldline property + $line = new BOMLine($this->db); + $line->fetch($idline); + $line->fetch_optionals(); + + $staticLine = clone $line; + $line->oldcopy = $staticLine; + $this->line = $line; + $this->line->context = $this->context; + + $result = $this->line->delete($user, $notrigger); + + //Positions (rank) reordering + foreach ($this->lines as $bl) { + if ($bl->position > ($line->oldcopy->position)) { // move rank down + $bl->position--; + $bl->update($user); + } + } + + if ($result > 0) { + $this->calculateCosts(); + $this->db->commit(); + return $result; + } else { + $this->error = $this->line->error; + dol_syslog(get_class($this)."::addLine error=".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } } /** diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index c60f10be857..7fb2f0f129e 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -757,9 +757,10 @@ if ($type) { $sql .= " AND ca.id = ".((int) $type); } if ($status == '0') { + // To do (not started) $sql .= " AND a.percent = 0"; } -if ($status == '-1' || $status == 'na') { +if ($status == 'na') { // Not applicable $sql .= " AND a.percent = -1"; } diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 3dfe18a3581..9233d397152 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -68,6 +68,15 @@ $hookmanager->initHooks(array('bankcard', 'globalcard')); $id = GETPOST("id", 'int') ? GETPOST("id", 'int') : GETPOST('ref', 'alpha'); $fieldid = GETPOST("id", 'int') ? 'rowid' : 'ref'; +if (GETPOST("id", 'int') || GETPOST("ref")) { + if (GETPOST("id", 'int')) { + $object->fetch(GETPOST("id", 'int')); + } + if (GETPOST("ref")) { + $object->fetch(0, GETPOST("ref")); + } +} + $result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid); @@ -319,6 +328,7 @@ if (empty($reshook)) { } } + /* * View */ @@ -333,15 +343,15 @@ if (!empty($conf->accounting->enabled)) { $countrynotdefined = $langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')'; $help_url = 'EN:Module_Banks_and_Cash|FR:Module_Banques_et_Caisses|ES:Módulo_Bancos_y_Cajas|DE:Modul_Banken_und_Barbestände'; +if ($action == 'create') { + $title = $langs->trans("NewFinancialAccount"); +} elseif (!empty($object->ref)) { + $title = $object->ref." - ".$langs->trans("Card"); +} +llxHeader("", $title, $help_url); // Creation - if ($action == 'create') { - $object = new Account($db); - - $title = $langs->trans("NewFinancialAccount"); - llxHeader("", $title, $help_url); - print load_fiche_titre($langs->trans("NewFinancialAccount"), '', 'bank_account'); if ($conf->use_javascript_ajax) { @@ -597,25 +607,8 @@ if ($action == 'create') { print ''; } else { - /* ************************************************************************** */ - /* */ - /* Visu et edition */ - /* */ - /* ************************************************************************** */ - + // View and edit mode if ((GETPOST("id", 'int') || GETPOST("ref")) && $action != 'edit') { - $object = new Account($db); - if (GETPOST("id", 'int')) { - $object->fetch(GETPOST("id", 'int')); - } - if (GETPOST("ref")) { - $object->fetch(0, GETPOST("ref")); - $_GET["id"] = $object->id; - } - - $title = $object->ref." - ".$langs->trans("Card"); - llxHeader("", $title, $help_url); - // Show tabs $head = bank_prepare_head($object); print dol_get_fiche_head($head, 'bankname', $langs->trans("FinancialAccount"), -1, 'account'); @@ -758,7 +751,7 @@ if ($action == 'create') { } print ''.$langs->trans($ibankey).''; - print ''.$object->iban.' '; + print ''.getIbanHumanReadable($object).' '; if (!empty($object->iban)) { if (!checkIbanForAccount($object)) { print img_picto($langs->trans("IbanNotValid"), 'warning'); @@ -843,12 +836,6 @@ if ($action == 'create') { /* ************************************************************************** */ if (GETPOST('id', 'int') && $action == 'edit' && $user->rights->banque->configurer) { - $object = new Account($db); - $object->fetch(GETPOST('id', 'int')); - - $title = $object->ref." - ".$langs->trans("Card"); - llxHeader("", $title, $help_url); - print load_fiche_titre($langs->trans("EditFinancialAccount"), '', 'bank_account'); if ($conf->use_javascript_ajax) { diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 4c728adbfc8..b42ef184c8f 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1381,6 +1381,7 @@ class Account extends CommonObject public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0) { global $conf, $langs, $user; + include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; $result = ''; $label = img_picto('', $this->picto).' '.$langs->trans("BankAccount").''; @@ -1389,7 +1390,7 @@ class Account extends CommonObject } $label .= '
'.$langs->trans('Label').': '.$this->label; $label .= '
'.$langs->trans('AccountNumber').': '.$this->number; - $label .= '
'.$langs->trans('IBAN').': '.$this->iban; + $label .= '
'.$langs->trans('IBAN').': '.getIbanHumanReadable($this); $label .= '
'.$langs->trans('BIC').': '.$this->bic; $label .= '
'.$langs->trans("AccountCurrency").': '.$this->currency_code; diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 2b6b027d7ce..0130cfe10f0 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -128,7 +128,7 @@ if (GETPOST('cancel', 'alpha')) { if ($action == "reopen") { $result = $object->setStatut($object::STATUS_DRAFT, null, '', 'CASHFENCE_REOPEN'); if ($result < 0) { - setEventMessages($object->error, $object->error, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } $action = 'view'; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index f3cfc89dcc4..dd0b65d656a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1408,7 +1408,7 @@ class Form if (count($scrit) > 1) { $sql .= ")"; } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $sql .= " OR s.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; } $sql .= " OR s.code_client LIKE '".$this->db->escape($prefix.$filterkey)."%' OR s.code_fournisseur LIKE '".$this->db->escape($prefix.$filterkey)."%'"; @@ -2691,7 +2691,7 @@ class Form if (count($scrit) > 1) { $sql .= ")"; } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $sql .= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; } $sql .= ')'; @@ -3254,7 +3254,7 @@ class Form if (!empty($conf->global->PRODUCT_USE_UNITS)) { $sql .= ", u.label as unit_long, u.short_label as unit_short, p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units"; } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $sql .= ", pfp.barcode"; } $sql .= " FROM ".$this->db->prefix()."product as p"; @@ -3305,7 +3305,7 @@ class Form if (count($scrit) > 1) { $sql .= ")"; } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $sql .= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; $sql .= " OR pfp.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; } @@ -3402,7 +3402,7 @@ class Form if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) { $optlabel .= ' ('.$objp->ref_fourn.')'; } - if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) { + if (isModEnabled('barcode') && !empty($objp->barcode)) { $optlabel .= ' ('.$outbarcode.')'; } $optlabel .= ' - '.dol_trunc($label, $maxlengtharticle); @@ -3411,7 +3411,7 @@ class Form if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) { $outvallabel .= ' ('.$objRefFourn.')'; } - if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) { + if (isModEnabled('barcode') && !empty($objp->barcode)) { $outvallabel .= ' ('.$outbarcode.')'; } $outvallabel .= ' - '.dol_trunc($label, $maxlengtharticle); diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index a19c6e44a92..5dde1bc4360 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -290,6 +290,24 @@ function checkIbanForAccount(Account $account) } } +/** + * Returns the iban human readable + * + * @param Account $account Account object + * @return string + */ +function getIbanHumanReadable(Account $account) +{ + if ($account->getCountryCode() == 'FR') { + require_once DOL_DOCUMENT_ROOT.'/includes/php-iban/oophp-iban.php'; + $ibantoprint = preg_replace('/[^a-zA-Z0-9]/', '', $account->iban); + $iban = new PHP_IBAN\IBAN($ibantoprint); + return $iban->HumanFormat(); + } + + return $account->iban; +} + /** * Check account number informations for a bank account * diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8ef4fb4ede6..f2f60588b3c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3310,8 +3310,8 @@ function dol_print_phone($phone, $countrycode = '', $cid = 0, $socid = 0, $addli $newphone = substr($newphone, 0, 5).$separ.substr($newphone, 5, 3).$separ.substr($newphone, 8, 4); } } elseif (strtoupper($countrycode) == "MG") {//Madagascar - if (dol_strlen($phone) == 13) {//ex: +261_AB_CD_EF_GHI - $newphone = substr($newphone, 0, 4).$separ.substr($newphone, 4, 2).$separ.substr($newphone, 6, 2).$separ.substr($newphone, 8, 2).$separ.substr($newphone, 10, 3); + if (dol_strlen($phone) == 13) {//ex: +261_AB_CD_EFG_HI + $newphone = substr($newphone, 0, 4).$separ.substr($newphone, 4, 2).$separ.substr($newphone, 6, 2).$separ.substr($newphone, 8, 3).$separ.substr($newphone, 11, 2); } } elseif (strtoupper($countrycode) == "GB") {//Royaume uni if (dol_strlen($phone) == 13) {//ex: +44_ABCD_EFG_HIJ diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 3a8defb8db4..2a2f813011b 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -986,20 +986,20 @@ class pdf_espadon extends ModelePdfExpedition } // Show barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $posx = 105; } else { $posx = $this->marge_gauche + 3; } //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); } $pdf->SetDrawColor(128, 128, 128); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index ab9461d104f..de2c454de18 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -931,20 +931,20 @@ class pdf_rouget extends ModelePdfExpedition } // Show barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $posx = 105; } else { $posx = $this->marge_gauche + 3; } //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); } $pdf->SetDrawColor(128, 128, 128); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index b18d10a29b1..090fdd59fa3 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -209,7 +209,7 @@ class modProduct extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('e.ref'=>'DefaultWarehouse', 'p.tobatch'=>'ManageLotSerial', 'p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); } $keyforselect = 'product'; @@ -247,7 +247,7 @@ class modProduct extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('e.ref'=>'Text', 'p.tobatch'=>'Numeric', 'p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { @@ -266,7 +266,7 @@ class modProduct extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { @@ -281,7 +281,7 @@ class modProduct extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { @@ -404,7 +404,7 @@ class modProduct extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); } $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty', 'pa.incdec'=>'ComposedProductIncDecStock')); @@ -420,7 +420,7 @@ class modProduct extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); } $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('pa.qty'=>'Numeric')); @@ -436,7 +436,7 @@ class modProduct extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'virtualproduct', 'p.seuil_stock_alerte'=>'virtualproduct', 'p.desiredstock'=>'virtualproduct', 'p.pmp'=>'virtualproduct')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'virtualproduct')); } $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('pa.qty'=>"subproduct", 'pa.incdec'=>'subproduct')); @@ -629,7 +629,7 @@ class modProduct extends DolibarrModules if (is_object($mysoc) && $mysoc->useLocalTax(2)) { $this->import_fields_array[$r] = array_merge($this->import_fields_array[$r], array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->import_fields_array[$r] = array_merge($this->import_fields_array[$r], array('p.barcode'=>'BarCode')); } if (!empty($conf->global->PRODUCT_USE_UNITS)) { @@ -722,7 +722,7 @@ class modProduct extends DolibarrModules if (is_object($mysoc) && $mysoc->useLocalTax(2)) { $import_sample = array_merge($import_sample, array('p.localtax2_tx'=>'', 'p.localtax2_type'=>'')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $import_sample = array_merge($import_sample, array('p.barcode'=>'')); } if (!empty($conf->global->PRODUCT_USE_UNITS)) { @@ -745,7 +745,7 @@ class modProduct extends DolibarrModules } $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample); $this->import_updatekeys_array[$r] = array('p.ref'=>'Ref'); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->import_updatekeys_array[$r] = array_merge($this->import_updatekeys_array[$r], array('p.barcode'=>'BarCode')); //only show/allow barcode as update key if Barcode module enabled } diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index bdc3388da5c..8f4b697332b 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -174,7 +174,7 @@ class modService extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); } $keyforselect = 'product'; @@ -210,7 +210,7 @@ class modService extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { @@ -229,7 +229,7 @@ class modService extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { @@ -244,7 +244,7 @@ class modService extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { @@ -363,7 +363,7 @@ class modService extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); } $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty', 'pa.incdec'=>'ComposedProductIncDecStock')); @@ -379,7 +379,7 @@ class modService extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); } $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('pa.qty'=>'Numeric')); @@ -395,7 +395,7 @@ class modService extends DolibarrModules if (!empty($conf->stock->enabled)) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'virtualproduct', 'p.seuil_stock_alerte'=>'virtualproduct', 'p.desiredstock'=>'virtualproduct', 'p.pmp'=>'virtualproduct')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'virtualproduct')); } $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('pa.qty'=>"subproduct", 'pa.incdec'=>'subproduct')); @@ -576,7 +576,7 @@ class modService extends DolibarrModules if (is_object($mysoc) && $mysoc->useLocalTax(2)) { $this->import_fields_array[$r] = array_merge($this->import_fields_array[$r], array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->import_fields_array[$r] = array_merge($this->import_fields_array[$r], array('p.barcode'=>'BarCode')); } if (!empty($conf->global->PRODUCT_USE_UNITS)) { @@ -667,7 +667,7 @@ class modService extends DolibarrModules if (is_object($mysoc) && $mysoc->useLocalTax(2)) { $import_sample = array_merge($import_sample, array('p.localtax2_tx'=>'', 'p.localtax2_type'=>'')); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $import_sample = array_merge($import_sample, array('p.barcode'=>'')); } if (!empty($conf->global->PRODUCT_USE_UNITS)) { @@ -693,7 +693,7 @@ class modService extends DolibarrModules } $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample); $this->import_updatekeys_array[$r] = array('p.ref'=>'Ref'); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->import_updatekeys_array[$r] = array_merge($this->import_updatekeys_array[$r], array('p.barcode'=>'BarCode')); //only show/allow barcode as update key if Barcode module enabled } diff --git a/htdocs/core/modules/reception/doc/pdf_squille.modules.php b/htdocs/core/modules/reception/doc/pdf_squille.modules.php index 61fab1ab02d..886168c28a6 100644 --- a/htdocs/core/modules/reception/doc/pdf_squille.modules.php +++ b/htdocs/core/modules/reception/doc/pdf_squille.modules.php @@ -856,20 +856,20 @@ class pdf_squille extends ModelePdfReception } // Show barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $posx = 105; } else { $posx = $this->marge_gauche + 3; } //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for reception ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); } $pdf->SetDrawColor(128, 128, 128); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for reception ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index c00bf34621e..7722698593c 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -944,20 +944,20 @@ class pdf_eagle extends ModelePdfStockTransfer } // Show barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $posx = 105; } else { $posx = $this->marge_gauche + 3; } //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); } $pdf->SetDrawColor(128, 128, 128); - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); //$pdf->Image($logo,10, 5, 0, 24); diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php index 38698d32940..3bbfe225bee 100644 --- a/htdocs/core/website.inc.php +++ b/htdocs/core/website.inc.php @@ -129,13 +129,35 @@ if (!defined('USEDOLIBARRSERVER') && !defined('USEDOLIBARREDITOR')) { // Referrer-Policy if (!defined('WEBSITE_MAIN_SECURITY_FORCERP')) { - // The constant WEBSITE_MAIN_SECURITY_FORCECSP should never be defined by page, but the variable used just after may be + // The constant WEBSITE_MAIN_SECURITY_FORCERP should never be defined by page, but the variable used just after may be // For public web sites, we use the same default value than "strict-origin-when-cross-origin" $referrerpolicy = getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCERP', "strict-origin-when-cross-origin"); header("Referrer-Policy: ".$referrerpolicy); } + + // Strict-Transport-Security + if (!defined('WEBSITE_MAIN_SECURITY_FORCESTS')) { + // The constant WEBSITE_MAIN_SECURITY_FORCESTS should never be defined by page, but the variable used just after may be + + // Example: "max-age=31536000; includeSubDomains" + $sts = getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCESTS'); + if (!empty($sts)) { + header("Strict-Transport-Security: ".$sts); + } + } + + // Permissions-Policy (old name was Feature-Policy) + if (!defined('WEBSITE_MAIN_SECURITY_FORCEPP')) { + // The constant WEBSITE_MAIN_SECURITY_FORCEPP should never be defined by page, but the variable used just after may be + + // Example: "camera: 'none'; microphone: 'none';" + $pp = getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCEPP'); + if (!empty($pp)) { + header("Permissions-Policy: ".$pp); + } + } } // A lang was forced, so we change weblangs init diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index a84fa3109df..714622e8014 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -137,6 +137,11 @@ class Cronjob extends CommonObject */ public $processing; + /** + * @var int The job current PID + */ + public $pid; + /** * @var int ID */ @@ -422,6 +427,7 @@ class Cronjob extends CommonObject $sql .= " t.frequency,"; $sql .= " t.status,"; $sql .= " t.processing,"; + $sql .= " t.pid,"; $sql .= " t.fk_user_author,"; $sql .= " t.fk_user_mod,"; $sql .= " t.note as note_private,"; @@ -470,6 +476,7 @@ class Cronjob extends CommonObject $this->frequency = $obj->frequency; $this->status = $obj->status; $this->processing = $obj->processing; + $this->pid = $obj->pid; $this->fk_user_author = $obj->fk_user_author; $this->fk_user_mod = $obj->fk_user_mod; $this->note_private = $obj->note_private; @@ -530,6 +537,7 @@ class Cronjob extends CommonObject $sql .= " t.frequency,"; $sql .= " t.status,"; $sql .= " t.processing,"; + $sql .= " t.pid,"; $sql .= " t.fk_user_author,"; $sql .= " t.fk_user_mod,"; $sql .= " t.note as note_private,"; @@ -606,6 +614,7 @@ class Cronjob extends CommonObject $line->frequency = $obj->frequency; $line->status = $obj->status; $line->processing = $obj->processing; + $line->pid = $obj->pid; $line->fk_user_author = $obj->fk_user_author; $line->fk_user_mod = $obj->fk_user_mod; $line->note_private = $obj->note_private; @@ -708,6 +717,10 @@ class Cronjob extends CommonObject $this->processing = 0; } + if (empty($this->pid)) { + $this->pid = null; + } + // Check parameters // Put here code to add a control on parameters values if (dol_strlen($this->datenextrun) == 0) { @@ -773,6 +786,7 @@ class Cronjob extends CommonObject $sql .= " frequency=".(isset($this->frequency) ? $this->frequency : "null").","; $sql .= " status=".(isset($this->status) ? $this->status : "null").","; $sql .= " processing=".((isset($this->processing) && $this->processing > 0) ? $this->processing : "0").","; + $sql .= " pid=".(isset($this->pid) ? $this->pid : "null").","; $sql .= " fk_user_mod=".$user->id.","; $sql .= " note=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").","; $sql .= " nbrun=".((isset($this->nbrun) && $this->nbrun > 0) ? $this->nbrun : "null").","; @@ -925,6 +939,7 @@ class Cronjob extends CommonObject $this->frequency = ''; $this->status = 0; $this->processing = 0; + $this->pid = null; $this->fk_user_author = 0; $this->fk_user_mod = 0; $this->note_private = ''; @@ -1125,6 +1140,7 @@ class Cronjob extends CommonObject $this->lastoutput = ''; $this->lastresult = ''; $this->processing = 1; // To know job was started + $this->pid = dol_getmypid(); $this->nbrun = $this->nbrun + 1; $result = $this->update($user); // This include begin/commit if ($result < 0) { @@ -1316,6 +1332,7 @@ class Cronjob extends CommonObject $this->datelastresult = dol_now(); $this->processing = 0; + $this->pid = null; $result = $this->update($user); // This include begin/commit if ($result < 0) { dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 333315b98c5..cdab93e6caa 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -620,7 +620,7 @@ class ProductFournisseur extends Product $this->fourn_multicurrency_tx = $obj->multicurrency_tx; $this->fourn_multicurrency_id = $obj->fk_multicurrency; $this->fourn_multicurrency_code = $obj->multicurrency_code; - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $this->fourn_barcode = $obj->barcode; // deprecated $this->fourn_fk_barcode_type = $obj->fk_barcode_type; // deprecated $this->supplier_barcode = $obj->barcode; @@ -730,7 +730,7 @@ class ProductFournisseur extends Product $prodfourn->packaging = $record["packaging"]; - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $prodfourn->supplier_barcode = $record["barcode"]; $prodfourn->supplier_fk_barcode_type = $record["fk_barcode_type"]; } @@ -1178,7 +1178,7 @@ class ProductFournisseur extends Product $label .= "
".$langs->trans("ManageLotSerial").': '.$this->getLibStatut(0, 2); } } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $label .= '
'.$langs->trans('BarCode').': '.$this->barcode; } diff --git a/htdocs/index.php b/htdocs/index.php index 2a0a095b362..553fee4855f 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -255,19 +255,19 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { // Number of cheque to send if (isModEnabled('banque') && empty($conf->global->MAIN_DISABLE_BLOCK_BANK) && $user->hasRight('banque', 'lire') && !$user->socid) { if (empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT)) { - include_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; + include_once DOL_DOCUMENT_ROOT . '/compta/paiement/cheque/class/remisecheque.class.php'; $board = new RemiseCheque($db); $dashboardlines[$board->element] = $board->load_board($user); } if (isModEnabled('prelevement')) { include_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; $board = new BonPrelevement($db); - $dashboardlines[$board->element.'_direct_debit'] = $board->load_board($user, 'direct_debit'); + $dashboardlines[$board->element . '_direct_debit'] = $board->load_board($user, 'direct_debit'); } if (isModEnabled('paymentbybanktransfer')) { include_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; $board = new BonPrelevement($db); - $dashboardlines[$board->element.'_credit_transfer'] = $board->load_board($user, 'credit_transfer'); + $dashboardlines[$board->element . '_credit_transfer'] = $board->load_board($user, 'credit_transfer'); } } diff --git a/htdocs/install/doctemplates/websites/website_template-style01.jpg b/htdocs/install/doctemplates/websites/website_template-style01.jpg new file mode 100644 index 00000000000..5464bf5dd5d Binary files /dev/null and b/htdocs/install/doctemplates/websites/website_template-style01.jpg differ diff --git a/htdocs/install/doctemplates/websites/website_template-style01.png b/htdocs/install/doctemplates/websites/website_template-style01.png deleted file mode 100644 index 4e409583f92..00000000000 Binary files a/htdocs/install/doctemplates/websites/website_template-style01.png and /dev/null differ diff --git a/htdocs/install/doctemplates/websites/website_template-style01.zip b/htdocs/install/doctemplates/websites/website_template-style01.zip index 12c001b5d7f..52a4501cb7a 100644 Binary files a/htdocs/install/doctemplates/websites/website_template-style01.zip and b/htdocs/install/doctemplates/websites/website_template-style01.zip differ diff --git a/htdocs/install/doctemplates/websites/website_template-style03.zip b/htdocs/install/doctemplates/websites/website_template-style03.zip index 1d6af1e04f4..f831b789e34 100644 Binary files a/htdocs/install/doctemplates/websites/website_template-style03.zip and b/htdocs/install/doctemplates/websites/website_template-style03.zip differ diff --git a/htdocs/install/doctemplates/websites/website_template-style04.png b/htdocs/install/doctemplates/websites/website_template-style04.png new file mode 100644 index 00000000000..26325e7e795 Binary files /dev/null and b/htdocs/install/doctemplates/websites/website_template-style04.png differ diff --git a/htdocs/install/doctemplates/websites/website_template-style04.zip b/htdocs/install/doctemplates/websites/website_template-style04.zip new file mode 100644 index 00000000000..322c9d34ece Binary files /dev/null and b/htdocs/install/doctemplates/websites/website_template-style04.zip differ diff --git a/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql b/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql index 80f59680df5..a8e9ac3be80 100644 --- a/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql +++ b/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql @@ -47,6 +47,16 @@ INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, m INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('FR-ASCENSION', 0, 1, 'ascension', 0, 0, 0, 1); INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('FR-PENTECOST', 0, 1, 'pentecost', 0, 0, 0, 1); +-- Belgium only (2) +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-VICTORYDAY', 0, 2, '', 0, 5, 8, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-NATIONALDAY', 0, 2, '', 0, 7, 21, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-ASSOMPTION', 0, 2, '', 0, 8, 15, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-TOUSSAINT', 0, 2, '', 0, 11, 1, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-ARMISTICE', 0, 2, '', 0, 11, 11, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-EASTER', 0, 2, 'eastermonday', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-ASCENSION', 0, 2, 'ascension', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-PENTECOST', 0, 2, 'pentecost', 0, 0, 0, 1); + -- Italy (3) INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, year, month, day, active) VALUES('IT-LIBEAZIONE', 0, 3, 0, 4, 25, 1); INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, year, month, day, active) VALUES('IT-EPIPHANY', 0, 3, 0, 6, 1, 1); diff --git a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql index fc6fd86420a..efeac91172d 100644 --- a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql +++ b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql @@ -84,3 +84,14 @@ ALTER TABLE llx_societe ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; ALTER TABLE llx_ticket ADD COLUMN ip varchar(250); ALTER TABLE llx_ticket ADD email_date datetime after email_msgid; + +ALTER TABLE llx_cronjob ADD COLUMN pid integer; + +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-VICTORYDAY', 0, 2, '', 0, 5, 8, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-NATIONALDAY', 0, 2, '', 0, 7, 21, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-ASSOMPTION', 0, 2, '', 0, 8, 15, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-TOUSSAINT', 0, 2, '', 0, 11, 1, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-ARMISTICE', 0, 2, '', 0, 11, 11, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-EASTER', 0, 2, 'eastermonday', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-ASCENSION', 0, 2, 'ascension', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-PENTECOST', 0, 2, 'pentecost', 0, 0, 0, 1); diff --git a/htdocs/install/mysql/tables/llx_cronjob.sql b/htdocs/install/mysql/tables/llx_cronjob.sql index 27e8a31cc9a..012801c28bb 100644 --- a/htdocs/install/mysql/tables/llx_cronjob.sql +++ b/htdocs/install/mysql/tables/llx_cronjob.sql @@ -47,6 +47,7 @@ CREATE TABLE llx_cronjob autodelete integer DEFAULT 0, -- 0=Job is kept unchanged once nbrun > maxrun or date > dateend, 2=Job must be archived (archive = status 2) once nbrun > maxrun or date > dateend status integer NOT NULL DEFAULT 1, -- 0=disabled, 1=enabled, 2=archived processing integer NOT NULL DEFAULT 0, -- 1=process currently running + pid integer, -- The cronjob PID, NULL if not in processing test varchar(255) DEFAULT '1', fk_user_author integer DEFAULT NULL, fk_user_mod integer DEFAULT NULL, diff --git a/htdocs/mrp/js/lib_dispatch.js.php b/htdocs/mrp/js/lib_dispatch.js.php index e8ca84d7a4e..8470716ce8f 100644 --- a/htdocs/mrp/js/lib_dispatch.js.php +++ b/htdocs/mrp/js/lib_dispatch.js.php @@ -70,7 +70,7 @@ function addDispatchLine(index, type, mode) mode = mode || 'qtymissing' console.log("fourn/js/lib_dispatch.js.php Split line type="+type+" index="+index+" mode="+mode); - if(mode == 'qtymissingconsume') { + if(mode == 'qtymissingconsume' || mode == 'allmissingconsume') { var inputId = 'qtytoconsume'; var warehouseId = 'idwarehouse'; } @@ -94,16 +94,70 @@ function addDispatchLine(index, type, mode) console.log($("#qty_dispatched_"+index).val()); // If user did not reduced the qty to dispatch on old line, we keep only 1 on old line and the rest on new line if (qtyDispatched == qtyOrdered && qtyDispatched > 1) { - qtyDispatched = parseFloat($("#qty_dispatched_"+index).val()) + 1; - mode = 'lessone'; + qtyDispatched = parseFloat($("#qty_dispatched_" + index).val()) + 1; + + } + if(mode == 'allmissingconsume' || mode == 'alltoproduce') { + var qtymax = parseFloat($($row).data('max-qty')); + if(qtymax === 'undefined') qtymax = 1; } } - console.log("qtyDispatched="+qtyDispatched+" qtyOrdered="+qtyOrdered); + + if(mode == 'allmissingconsume' || mode == 'alltoproduce') { + var count = 0; + var qtyalreadyused = 0; + var error = 0; + + while (qtyalreadyused < qty) { + //If remaining qty needed is inferior to qty asked, qtymax = qty asked - qty already used + if ((qtyalreadyused + qtymax) > qty) qtymax = qty - qtyalreadyused; + //If first line, we replace value, not add line + if(count === 0){ + $("#"+inputId+"-"+index+"-"+nbrTrs).val(qtymax); + } else { + var res = addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, inputId, type, qtymax, mode, $row); + if(res === -1){ + error = 1; + break; + } + nbrTrs++; + } + qtyalreadyused = qtyalreadyused + qtymax; + count++; + $row = $("tr[name='" + type + '_' + index + "_1']").clone(true); + } + + if(error === 0) { + addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, inputId, type, '', mode, $row); + } + } + else addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, inputId, type, qty, mode, $row) + +} + +/** + * addDispatchTR + * Adds new table row for dispatching to multiple stock locations or multiple lot/serial + * + * @param qtyOrdered double + * @param qtyDispatched double + * @param index int + * @param nbrTrs int + * @param warehouseId int + * @param inputId int + * @param type string + * @param qty double + * @param mode string + * @param $row object + */ +function addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, inputId, type, qty, mode, $row) { if (qtyOrdered <= 1) { window.alert("Quantity can't be split"); + return -1; } else if (qtyDispatched >= qtyOrdered) { window.alert("No remain qty to dispatch"); + return -1; } else if (qtyDispatched < qtyOrdered) { //replace tr suffix nbr var re1 = new RegExp('_'+index+'_1', 'g'); @@ -128,24 +182,27 @@ function addDispatchLine(index, type, mode) /* Suffix of lines are: index _ trs.length */ $("#"+inputId+"-"+index+"-"+(nbrTrs+1)).focus(); if ($("#"+inputId+"-"+index+"-"+(nbrTrs)).val() == 0) { - $("#"+inputId+"-"+index+"-"+(nbrTrs)).val(1); + if(mode == 'allmissingconsume' || mode == 'alltoproduce') $("#"+inputId+"-"+index+"-"+(nbrTrs)).val(qty); + else $("#"+inputId+"-"+index+"-"+(nbrTrs)).val(1); } var totalonallines = 0; for (let i = 1; i <= nbrTrs; i++) { console.log(i+" = "+parseFloat($("#"+inputId+"-"+index+"-"+i).val())); totalonallines = totalonallines + parseFloat($("#"+inputId+"-"+index+"-"+i).val()); } - console.log("totalonallines="+totalonallines); - if (totalonallines == qtyOrdered && qtyOrdered > 1) { - var prevouslineqty = $("#"+inputId+"-"+index+"-"+nbrTrs).val(); - $("#"+inputId+"-"+index+"-"+(nbrTrs)).val(1); - $("#"+inputId+"-"+index+"-"+(nbrTrs+1)).val(prevouslineqty - 1); + + if(mode != 'allmissingconsume' && mode != 'alltoproduce') { + if (totalonallines == qtyOrdered && qtyOrdered > 1) { + var prevouslineqty = $("#" + inputId + "-" + index + "-" + nbrTrs).val(); + $("#" + inputId + "-" + index + "-" + (nbrTrs)).val(1); + $("#" + inputId + "-" + index + "-" + (nbrTrs + 1)).val(prevouslineqty - 1); + } } $("#qty_dispatched_"+index).val(qtyDispatched); //hide all buttons then show only the last one - $("tr[name^='"+type+"_'][name$='_"+index+"'] .splitbutton").hide(); - $("tr[name^='"+type+"_'][name$='_"+index+"']:last .splitbutton").show(); + $("tr[name^='"+type+"_"+index+"_'] .splitbutton").hide(); + $("tr[name^='"+type+"_"+index+"_']:last .splitbutton").show(); if (mode === 'lessone') { @@ -156,6 +213,10 @@ function addDispatchLine(index, type, mode) $("#"+inputId+"-"+index+(nbrTrs)).data('qty', qty); $("#"+inputId+"-"+index+(nbrTrs)).data('type', type); $("#"+inputId+"-"+index+(nbrTrs)).data('index', index); + if(mode == 'allmissingconsume' || mode == 'alltoproduce') { + let currentQtyDispatched = qtyDispatched+qty; + $row.find("input[id^='"+inputId+"']").val(qty); + } } } diff --git a/htdocs/mrp/mo_agenda.php b/htdocs/mrp/mo_agenda.php index 2e8b6691c0f..60ac81e20cd 100644 --- a/htdocs/mrp/mo_agenda.php +++ b/htdocs/mrp/mo_agenda.php @@ -209,7 +209,7 @@ if ($object->id > 0) { if (get_class($objthirdparty) == 'Societe') { $out .= '&socid='.$objthirdparty->id; } - $out .= (!empty($objcon->id) ? '&contactid='.$objcon->id : '').'&backtopage=1&percentage=-1'; + $out .= (!empty($objcon->id) ? '&contactid='.$objcon->id : '').'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id).'&percentage=-1'; //$out.=$langs->trans("AddAnAction").' '; //$out.=img_picto($langs->trans("AddAnAction"),'filenew'); //$out.=""; diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 6584c80cc37..d6fc14b33ae 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -772,6 +772,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($permissiontodelete) { print ''; } + + // Split + print ''; + + // SplitAll + print ''; + print ''; if ($action == 'addconsumeline') { @@ -855,7 +862,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; - print ''; + print ''; // Product print ''.$tmpproduct->getNomUrl(1); print '
'.$tmpproduct->label.''; @@ -935,6 +942,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; } + + // Split + print ''; + + // Split All + print ''; + print ''; // Show detailed of already consumed with js code to collapse @@ -1000,7 +1014,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (in_array($action, array('consumeorproduce', 'consumeandproduceall'))) { $i = 1; print ''."\n"; - print ''; + $maxQty = 1; + print ''; // Ref print ''.$langs->trans("ToConsume").''; $preselected = (GETPOSTISSET('qty-'.$line->id.'-'.$i) ? GETPOST('qty-'.$line->id.'-'.$i) : max(0, $line->qty - $alreadyconsumed)); @@ -1052,7 +1067,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print $formproduct->selectLotDataList('batch-'.$line->id.'-'.$i, 0, $line->fk_product, '', ''); $type = 'batch'; + print ''; print ' '.img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.((int) $line->id).', \''.dol_escape_js($type).'\', \'qtymissingconsume\')"'); + print ''; + print ''; + if (($action == 'consumeorproduce' || $action == 'consumeandproduceall')) print img_picto($langs->trans('SplitAllQuantity'), 'split.png', 'class="splitbutton splitallbutton field-error-icon" data-max-qty="1" onClick="addDispatchLine('.$line->id.', \'batch\', \'allmissingconsume\')"'); + print ''; } print ''; } @@ -1130,6 +1150,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; if ($collapse || in_array($action, array('consumeorproduce', 'consumeandproduceall'))) { print $langs->trans("Batch"); + + // Split + print ''; + + // Split All + print ''; } print ''; print ''; @@ -1293,13 +1319,20 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print ''; print ''; + + // Split + print ''; + + // Split All + print ''; } print ''; } if (in_array($action, array('consumeorproduce', 'consumeandproduceall'))) { print ''."\n"; - print ''; + $maxQty = 1; + print ''; print ''.$langs->trans("ToProduce").''; $preselected = (GETPOSTISSET('qtytoproduce-'.$line->id.'-'.$i) ? GETPOST('qtytoproduce-'.$line->id.'-'.$i) : max(0, $line->qty - $alreadyproduced)); if ($action == 'consumeorproduce' && !GETPOSTISSET('qtytoproduce-'.$line->id.'-'.$i)) { @@ -1346,7 +1379,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; if ($tmpproduct->status_batch) { $type = 'batch'; + print ''; print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.$line->id.', \''.$type.'\', \'qtymissing\')"'); + print ''; + + print ''; + if (($action == 'consumeorproduce' || $action == 'consumeandproduceall') && $tmpproduct->status_batch == 2) print img_picto($langs->trans('SplitAllQuantity'), 'split.png', 'class="splitbutton splitallbutton field-error-icon" onClick="addDispatchLine('.$line->id.', \'batch\', \'alltoproduce\')"'); // + print ''; } print ''; } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index d4baa9870ff..f0c765e59e9 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1228,7 +1228,7 @@ llxHeader('', $title, $help_url); // Load object modBarCodeProduct $res = 0; -if (!empty($conf->barcode->enabled) && !empty($conf->global->BARCODE_PRODUCT_ADDON_NUM)) { +if (isModEnabled('barcode') && !empty($conf->global->BARCODE_PRODUCT_ADDON_NUM)) { $module = strtolower($conf->global->BARCODE_PRODUCT_ADDON_NUM); $dirbarcode = array_merge(array('/core/modules/barcode/'), $conf->modules_parts['barcode']); foreach ($dirbarcode as $dirroot) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index acdb88da9f5..3bac43e1374 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -474,7 +474,7 @@ class Product extends CommonObject 'ref' =>array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>5), 'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>2, 'position'=>15), - 'barcode' =>array('type'=>'varchar(255)', 'label'=>'Barcode', 'enabled'=>'!empty($conf->barcode->enabled)', 'position'=>20, 'visible'=>-1, 'showoncombobox'=>3), + 'barcode' =>array('type'=>'varchar(255)', 'label'=>'Barcode', 'enabled'=>'isModEnabled("barcode")', 'position'=>20, 'visible'=>-1, 'showoncombobox'=>3), 'fk_barcode_type' => array('type'=>'integer', 'label'=>'BarcodeType', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>-1,), 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61), 'note' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62), @@ -913,7 +913,7 @@ class Product extends CommonObject { // phpcs:enable global $conf; - if (!empty($conf->barcode->enabled) && !empty($conf->global->BARCODE_PRODUCT_ADDON_NUM)) { + if (isModEnabled('barcode') && !empty($conf->global->BARCODE_PRODUCT_ADDON_NUM)) { $module = strtolower($conf->global->BARCODE_PRODUCT_ADDON_NUM); $dirsociete = array_merge(array('/core/modules/barcode/'), $conf->modules_parts['barcode']); @@ -4944,7 +4944,7 @@ class Product extends CommonObject $label .= "
".$langs->trans("ManageLotSerial").': '.$this->getLibStatut(0, 2); } } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $label .= '
'.$langs->trans('BarCode').': '.$this->barcode; } diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index bc6a1c36628..2e4962066e9 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -174,7 +174,7 @@ if ($action == 'search') { $params[] = 'pl.description'; $params[] = 'pl.note'; } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $params[] = 'p.barcode'; } $sql .= natural_search($params, $key); diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 7b3520cc707..db4fdedbc01 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -40,7 +40,7 @@ require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_expression.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; -if (!empty($conf->barcode->enabled)) { +if (isModEnabled('barcode')) { dol_include_once('/core/class/html.formbarcode.class.php'); } // Load translation files required by the page @@ -745,7 +745,7 @@ END; print ''; // Barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $formbarcode = new FormBarCode($db); // Barcode type @@ -913,10 +913,10 @@ END; 'pfp.multicurrency_unitprice'=>array('label'=>$langs->trans("UnitPriceHTCurrency"), 'enabled' => (!empty($conf->multicurrency->enabled)), 'checked'=>0, 'position'=>10), 'pfp.delivery_time_days'=>array('label'=>$langs->trans("NbDaysToDelivery"), 'checked'=>1, 'position'=>13), 'pfp.supplier_reputation'=>array('label'=>$langs->trans("ReputationForThisProduct"), 'checked'=>1, 'position'=>14), - 'pfp.fk_barcode_type'=>array('label'=>$langs->trans("BarcodeType"), 'enabled' => !empty($conf->barcode->enabled), 'checked'=>0, 'position'=>15), - 'pfp.barcode'=>array('label'=>$langs->trans("BarcodeValue"), 'enabled' => !empty($conf->barcode->enabled), 'checked'=>0, 'position'=>16), + 'pfp.fk_barcode_type'=>array('label'=>$langs->trans("BarcodeType"), 'enabled' => isModEnabled('barcode'), 'checked'=>0, 'position'=>15), + 'pfp.barcode'=>array('label'=>$langs->trans("BarcodeValue"), 'enabled' => isModEnabled('barcode'), 'checked'=>0, 'position'=>16), 'pfp.packaging'=>array('label'=>$langs->trans("PackagingForThisProduct"), 'enabled' => !empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING), 'checked'=>0, 'position'=>17), - 'pfp.tms'=>array('label'=>$langs->trans("DateModification"), 'enabled' => !empty($conf->barcode->enabled), 'checked'=>1, 'position'=>18), + 'pfp.tms'=>array('label'=>$langs->trans("DateModification"), 'enabled' => isModEnabled('barcode'), 'checked'=>1, 'position'=>18), ); // fetch optionals attributes and labels diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 00523c6bf3d..cdcfe74cb73 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -608,7 +608,7 @@ if ($object->id > 0) { if (!empty($conf->use_javascript_ajax)) { if ($permissiontoadd) { // Link to launch scan tool - if (!empty($conf->barcode->enabled) || !empty($conf->productbatch->enabled)) { + if (isModEnabled('barcode') || !empty($conf->productbatch->enabled)) { print ''.img_picto('', 'barcode', 'class="paddingrightonly"').$langs->trans("UpdateByScaning").''; } diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 8f2eed18829..4cc79472ada 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -179,7 +179,7 @@ if (!empty($conf->global->MAIN_MULTILANGS)) { $fieldstosearchall['pl.description'] = 'ProductDescriptionTranslated'; $fieldstosearchall['pl.note'] = 'ProductNoteTranslated'; } -if (!empty($conf->barcode->enabled)) { +if (isModEnabled('barcode')) { $fieldstosearchall['p.barcode'] = 'Gencod'; $fieldstosearchall['pfp.barcode'] = 'GencodBuyPrice'; } @@ -207,7 +207,7 @@ $arrayfields = array( 'thumbnail'=>array('label'=>'Photo', 'checked'=>0, 'position'=>10), 'p.label'=>array('label'=>"Label", 'checked'=>1, 'position'=>10), 'p.fk_product_type'=>array('label'=>"Type", 'checked'=>0, 'enabled'=>(!empty($conf->product->enabled) && !empty($conf->service->enabled)), 'position'=>11), - 'p.barcode'=>array('label'=>"Gencod", 'checked'=>1, 'enabled'=>(!empty($conf->barcode->enabled)), 'position'=>12), + 'p.barcode'=>array('label'=>"Gencod", 'checked'=>1, 'enabled'=>(isModEnabled('barcode')), 'position'=>12), 'p.duration'=>array('label'=>"Duration", 'checked'=>($contextpage != 'productlist'), 'enabled'=>(!empty($conf->service->enabled) && (string) $type == '1'), 'position'=>13), 'p.finished'=>array('label'=>"Nature", 'checked'=>0, 'enabled'=>(!empty($conf->product->enabled) && $type != '1'), 'position'=>19), 'p.weight'=>array('label'=>'Weight', 'checked'=>0, 'enabled'=>(!empty($conf->product->enabled) && $type != '1'), 'position'=>20), diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index 98b1d48014d..ad7be8d674b 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -942,12 +942,17 @@ if ($action == "transfert") { if ((empty($action) || $action == 'list') && $id > 0) { print "
\n"; - if ($user->rights->stock->mouvement->creer) { - print ''.$langs->trans("CorrectStock").''; - } + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if (empty($reshook)) { + if ($user->rights->stock->mouvement->creer) { + print ''.$langs->trans("CorrectStock").''; + } - if ($user->rights->stock->mouvement->creer) { - print ''.$langs->trans("TransferStock").''; + if ($user->rights->stock->mouvement->creer) { + print ''.$langs->trans("TransferStock").''; + } } print '

'; diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 91833e95271..c8d10444711 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -467,7 +467,7 @@ if ($usevirtualstock) { $sqlProductionToConsume .= " AND mp5.role IN ('toconsume', 'consummed')"; $sqlProductionToConsume .= " AND mm5.status IN (1,2))"; - $sqlProductionToProduce = "(SELECT GREATEST(0, ".$db->ifsql("SUM(".$db->ifsql("mp5.role = 'toproduce'", 'mp5.qty', '- mp5.qty').") IS NULL", "0", "SUM(".$db->ifsql("mp5.role = 'toconsume'", 'mp5.qty', '- mp5.qty').")").") as qty"; // We need the ifsql because if result is 0 for product p.rowid, we must return 0 and not NULL + $sqlProductionToProduce = "(SELECT GREATEST(0, ".$db->ifsql("SUM(".$db->ifsql("mp5.role = 'toproduce'", 'mp5.qty', '- mp5.qty').") IS NULL", "0", "SUM(".$db->ifsql("mp5.role = 'toproduce'", 'mp5.qty', '- mp5.qty').")").") as qty"; // We need the ifsql because if result is 0 for product p.rowid, we must return 0 and not NULL $sqlProductionToProduce .= " FROM ".MAIN_DB_PREFIX."mrp_mo as mm5,"; $sqlProductionToProduce .= " ".MAIN_DB_PREFIX."mrp_production as mp5"; $sqlProductionToProduce .= " WHERE mm5.rowid = mp5.fk_mo AND mm5.entity IN (".getEntity(!empty($conf->global->STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE) ? 'stock' : 'mo').")"; diff --git a/htdocs/societe/canvas/company/tpl/card_create.tpl.php b/htdocs/societe/canvas/company/tpl/card_create.tpl.php index 2deb1dba8b1..58752a1bc7b 100644 --- a/htdocs/societe/canvas/company/tpl/card_create.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_create.tpl.php @@ -105,7 +105,7 @@ if (empty($conf) || !is_object($conf)) { barcode->enabled)) { ?> +if (isModEnabled('barcode')) { ?> trans('Gencod'); ?> diff --git a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php index 35e38a10f0e..eb300cfdd4e 100644 --- a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php @@ -120,7 +120,7 @@ if ($this->control->tpl['fournisseur']) { } } -if (!empty($conf->barcode->enabled)) { ?> +if (isModEnabled('barcode')) { ?> trans('Gencod'); ?> diff --git a/htdocs/societe/canvas/company/tpl/card_view.tpl.php b/htdocs/societe/canvas/company/tpl/card_view.tpl.php index e57421bf8b5..0c6f2caf1e1 100644 --- a/htdocs/societe/canvas/company/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_view.tpl.php @@ -79,7 +79,7 @@ print dol_get_fiche_head($head, 'card', $langs->trans("ThirdParty"), 0, 'company -barcode->enabled)) { ?> + trans('Gencod'); ?> control->tpl['barcode']; ?> diff --git a/htdocs/societe/canvas/individual/tpl/card_create.tpl.php b/htdocs/societe/canvas/individual/tpl/card_create.tpl.php index 0010b87ff90..1c8b51dac7c 100644 --- a/htdocs/societe/canvas/individual/tpl/card_create.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_create.tpl.php @@ -113,7 +113,7 @@ if (empty($conf) || !is_object($conf)) { barcode->enabled)) { ?> +if (isModEnabled('barcode')) { ?> trans('Gencod'); ?> diff --git a/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php b/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php index 7a43f256b45..56192bbe4e7 100644 --- a/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php @@ -117,7 +117,7 @@ if ($this->control->tpl['fournisseur']) { } ?> -barcode->enabled)) { ?> + trans('Gencod'); ?> diff --git a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php index 16cd9f1e637..bfbf6271711 100644 --- a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php @@ -74,7 +74,7 @@ if ($this->control->tpl['action_delete']) { -barcode->enabled)) { ?> + trans('Gencod'); ?> control->tpl['barcode']; ?> diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index d5f8a685155..4ca09e031d6 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1510,7 +1510,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; // Barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { print ''.$form->editfieldkey('Gencod', 'barcode', '', $object, 0).''; print ''; print img_picto('', 'barcode', 'class="pictofixedwidth"'); @@ -2207,7 +2207,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } // Barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { print ''.$form->editfieldkey('Gencod', 'barcode', '', $object, 0).''; print ''; print img_picto('', 'barcode'); @@ -2687,7 +2687,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } // Barcode - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { print ''; print $langs->trans('Gencod').''.showValueWithClipboardCPButton(dol_escape_htmltag($object->barcode)); print ''; diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 3e7e1ac2080..e79c39a1955 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -97,6 +97,10 @@ class Contacts extends DolibarrApi $this->contact->fetchRoles(); } + if (isModEnabled('mailing')) { + $this->contact->getNoEmail(); + } + return $this->_cleanObjectDatas($this->contact); } @@ -141,6 +145,10 @@ class Contacts extends DolibarrApi $this->contact->fetchRoles(); } + if (isModEnabled('mailing')) { + $this->contact->getNoEmail(); + } + return $this->_cleanObjectDatas($this->contact); } @@ -250,6 +258,9 @@ class Contacts extends DolibarrApi if ($includeroles) { $contact_static->fetchRoles(); } + if (isModEnabled('mailing')) { + $contact_static->getNoEmail(); + } $obj_ret[] = $this->_cleanObjectDatas($contact_static); } @@ -285,6 +296,9 @@ class Contacts extends DolibarrApi if ($this->contact->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating contact", array_merge(array($this->contact->error), $this->contact->errors)); } + if (isModEnabled('mailing') && !empty($this->contact->email) && isset($this->contact->no_email)) { + $this->contact->setNoEmail($this->contact->no_email); + } return $this->contact->id; } @@ -317,6 +331,10 @@ class Contacts extends DolibarrApi $this->contact->$field = $value; } + if (isModEnabled('mailing') && !empty($this->contact->email) && isset($this->contact->no_email)) { + $this->contact->setNoEmail($this->contact->no_email); + } + if ($this->contact->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) { return $this->get($id); } diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 43cfaa16998..1c41b7ee186 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1581,6 +1581,7 @@ class Societe extends CommonObject $lmember->phone = $this->phone; $lmember->state_id = $this->state_id; $lmember->country_id = $this->country_id; + $lmember->default_lang = $this->default_lang; $result = $lmember->update($user, 0, 1, 1, 1); // Use nosync to 1 to avoid cyclic updates if ($result < 0) { diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 07591d7db9d..aad8d3edc3e 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -187,7 +187,7 @@ if (($tmp = $langs->transnoentities("ProfId5".$mysoc->country_code)) && $tmp != if (($tmp = $langs->transnoentities("ProfId6".$mysoc->country_code)) && $tmp != "ProfId6".$mysoc->country_code && $tmp != '-') { $fieldstosearchall['s.idprof6'] = 'ProfId6'; } -if (!empty($conf->barcode->enabled)) { +if (isModEnabled('barcode')) { $fieldstosearchall['s.barcode'] = 'Gencod'; } // Personalized search criterias. Example: $conf->global->THIRDPARTY_QUICKSEARCH_ON_FIELDS = 's.nom=ThirdPartyName;s.name_alias=AliasNameShort;s.code_client=CustomerCode' @@ -217,7 +217,7 @@ $arrayfields = array( 's.rowid'=>array('label'=>"TechnicalID", 'position'=>1, 'checked'=>(!empty($conf->global->MAIN_SHOW_TECHNICAL_ID)), 'enabled'=>(!empty($conf->global->MAIN_SHOW_TECHNICAL_ID))), 's.nom'=>array('label'=>"ThirdPartyName", 'position'=>2, 'checked'=>1), 's.name_alias'=>array('label'=>"AliasNameShort", 'position'=>3, 'checked'=>1), - 's.barcode'=>array('label'=>"Gencod", 'position'=>5, 'checked'=>1, 'enabled'=>(!empty($conf->barcode->enabled))), + 's.barcode'=>array('label'=>"Gencod", 'position'=>5, 'checked'=>1, 'enabled'=>(isModEnabled('barcode'))), 's.code_client'=>array('label'=>"CustomerCodeShort", 'position'=>10, 'checked'=>$checkedcustomercode), 's.code_fournisseur'=>array('label'=>"SupplierCodeShort", 'position'=>11, 'checked'=>$checkedsuppliercode, 'enabled'=>((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled))), 's.code_compta'=>array('label'=>"CustomerAccountancyCodeShort", 'position'=>13, 'checked'=>$checkedcustomeraccountcode), @@ -638,7 +638,7 @@ if ($search_type == '0') { if ($search_status != '' && $search_status >= 0) { $sql .= natural_search("s.status", $search_status, 2); } -if (!empty($conf->barcode->enabled) && $search_barcode) { +if (isModEnabled('barcode') && $search_barcode) { $sql .= natural_search("s.barcode", $search_barcode); } if ($search_price_level && $search_price_level != '-1') { diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index 849c5c56481..a21bf3de219 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -82,7 +82,7 @@ if ($action == 'set') { $res = dolibarr_set_const($db, "TAKEPOS_SUMUP_AFFILIATE", GETPOST('TAKEPOS_SUMUP_AFFILIATE', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_SUMUP_APPID", GETPOST('TAKEPOS_SUMUP_APPID', 'alpha'), 'chaine', 0, '', $conf->entity); } - if (!empty($conf->barcode->enabled)) { + if (isModEnabled('barcode')) { $res = dolibarr_set_const($db, 'TAKEPOS_BARCODE_RULE_TO_INSERT_PRODUCT', GETPOST('TAKEPOS_BARCODE_RULE_TO_INSERT_PRODUCT', 'alpha'), 'chaine', 0, '', $conf->entity); } @@ -388,7 +388,7 @@ print ajax_constantonoff("TAKEPOS_SHOW_HT", array(), $conf->entity, 0, 0, 1, 0); print "\n"; // Barcode rule to insert product -if (!empty($conf->barcode->enabled)) { +if (isModEnabled('barcode')) { print ''; print $form->textwithpicto($langs->trans("TakeposBarcodeRuleToInsertProduct"), $langs->trans("TakeposBarcodeRuleToInsertProductDesc")); print ''; diff --git a/htdocs/takepos/ajax/ajax.php b/htdocs/takepos/ajax/ajax.php index 9f7483319b3..a2698e05cd5 100644 --- a/htdocs/takepos/ajax/ajax.php +++ b/htdocs/takepos/ajax/ajax.php @@ -58,11 +58,14 @@ if (empty($user->rights->takepos->run)) { // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array of hooks $hookmanager->initHooks(array('takeposproductsearch')); // new context for product search hooks + /* * View */ if ($action == 'getProducts') { + top_httphead('application/json'); + $object = new Categorie($db); if ($category == "supplements") { $category = getDolGlobalInt('TAKEPOS_SUPPLEMENTS_CATEGORY'); @@ -88,9 +91,11 @@ if ($action == 'getProducts') { } echo json_encode($res); } else { - echo 'Failed to load category with id='.$category; + echo 'Failed to load category with id='.dol_escape_htmltag($category); } } elseif ($action == 'search' && $term != '') { + top_httphead('application/json'); + // Change thirdparty with barcode require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; @@ -123,7 +128,7 @@ if ($action == 'getProducts') { } $barcode_rules = getDolGlobalString('TAKEPOS_BARCODE_RULE_TO_INSERT_PRODUCT'); - if (!empty($conf->barcode->enabled) && !empty($barcode_rules)) { + if (isModEnabled('barcode') && !empty($barcode_rules)) { $barcode_rules_list = array(); // get barcode rules @@ -329,8 +334,8 @@ if ($action == 'getProducts') { require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; $printer = new dolReceiptPrinter($db); // check printer for terminal - if ($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term} > 0) { - $printer->initPrinter($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term}); + if (getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0) { + $printer->initPrinter(getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term)); // open cashdrawer $printer->pulse(); $printer->close(); @@ -340,12 +345,14 @@ if ($action == 'getProducts') { require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $printer = new dolReceiptPrinter($db); // check printer for terminal - if (($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term} > 0 || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term} > 0) { + if ((getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0 || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") && getDolGlobalInt('TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term) > 0) { $object = new Facture($db); $object->fetch($id); - $ret = $printer->sendToPrinter($object, $conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term}, $conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term}); + $ret = $printer->sendToPrinter($object, getDolGlobalString('TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term), getDolGlobalString('TAKEPOS_PRINTER_TO_USE'.$term)); } } elseif ($action == 'getInvoice') { + top_httphead('application/json'); + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $object = new Facture($db); @@ -359,5 +366,5 @@ if ($action == 'getProducts') { require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; $printer = new dolReceiptPrinter($db); - $printer->sendToPrinter($object, $conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term}, $conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term}); + $printer->sendToPrinter($object, getDolGlobalString('TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term), getDolGlobalString('TAKEPOS_PRINTER_TO_USE'.$term)); } diff --git a/htdocs/takepos/floors.php b/htdocs/takepos/floors.php index 9dc4f843b5b..868719112b5 100644 --- a/htdocs/takepos/floors.php +++ b/htdocs/takepos/floors.php @@ -81,6 +81,8 @@ if ($action == "getTables") { } $rows[] = $row; } + + top_httphead('application/json'); echo json_encode($rows); exit; } @@ -119,13 +121,18 @@ if ($action == "add") { */ // Title +$head = ''; $title = 'TakePOS - Dolibarr '.DOL_VERSION; if (!empty($conf->global->MAIN_APPLICATION_TITLE)) { $title = 'TakePOS - '.$conf->global->MAIN_APPLICATION_TITLE; } -top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); +$arrayofcss = array('/takepos/css/pos.css.php?a=xxx'); + +top_htmlhead($head, $title, 0, 0, '', $arrayofcss); + ?> - + +