diff --git a/ChangeLog b/ChangeLog index cbd76fe7c37..33459d4f234 100644 --- a/ChangeLog +++ b/ChangeLog @@ -53,14 +53,11 @@ NEW: Add column "Total HT" to products array on document creation card NEW: Add configuration for text color of button action NEW: Add entity filter in exports NEW: Show the event block on recurring invoices #20870 -NEW: Add filter "opportunity status" on statistics of projects. NEW: Add firstname, lastname and max number of attendees for module "Event Organization" NEW: Add margin info in proposal and order list NEW: Add massaction "Edit Extrafield" for Product NEW: Add more fields to detect duplicate during import of thirdparties NEW: Add option to foce delivery on email for purchase order receipt to yes -NEW: Add param border table for md theme -NEW: Add param color button action NEW: Add possibility to create contract from invoice NEW: Add possibility with constant MAIN_LOGIN_BADCHARUNAUTHORIZED to define bad character unauthorized into login name NEW: Add private and public notes on tax files. @@ -70,12 +67,10 @@ NEW: allow cut&paste as real numeric value to excel NEW: A public form to send a message and create a lead is available NEW: automatically set totally received status in reception NEW: Auto set invoice paid when adding credit not and remain to pay is 0 -NEW: Can change value of AWP during the inventory NEW: Can enter price with tax for predefined products on purchase objects NEW: Can filter on a thirdparty on product statistics NEW: Can removed doc templates from setup page of thirdparty NEW: Can use ! to make a search that exclude a string -NEW: Change in theme colors does not need to use the refresh button NEW: clean values and amount in FEC import NEW: const MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND for mailing mass action NEW: Contact filter project list @@ -94,25 +89,26 @@ NEW: JS inventory autocalc input NEW: language support for more emailing target selectors NEW: leave requests: add field into type dictionary to block request if balance is negative NEW: Mass action "Close shipments" -NEW: Module BOM - Add tabs for nets Bom -NEW: Module BOM - Add the possibility to add sub-BOMs to BOM +NEW: Module BOM - add tabs for nets Bom +NEW: Module BOM - add the possibility to add sub-BOMs to BOM NEW: Module Recruitment - Add a public page with list of all open job positions. NEW: Module Recruitment - Add a tab with list of application on the jobposition file. -NEW: More mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...) NEW: Add option to move checkbox column as first column on Thirdparty list (only few screens) NEW: payment conditions enabling semi-automatic deposit creation (Issue #18439) NEW: possibility to consume multiple batch NEW: Reverse movement product consumption NEW: Send email to the supplier order contact NEW: add permission to report time on timesheet -NEW: Knowledge Management - Add status "Obsolete" to KM articles +NEW: Knowledge Management - add status "Obsolete" to KM articles NEW: MRP - split consumption line on MO -NEW: MRP - Display physical and virtual stock of the products when creating OF from a BOM -NEW: MRP - Display product ref in "Object link" product tab for BOM +NEW: MRP - display physical and virtual stock of the products when creating OF from a BOM +NEW: MRP - display product ref in "Object link" product tab for BOM +NEW: Projects - add filter "opportunity status" on statistics of projects. NEW: Proposals - option update prices on proposal cloning NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level NEW: Stocks - stock filter in reassort lists NEW: Stocks - stock limit in stock export CSV +NEW: Stocks - Inventory - can change value of AWP during the inventory NEW: Supplier order - Show ref supplier of reception in linked object block NEW: support user_modif in order NEW: Surveys - Show number of votes into the label of tab "Results" of a survey @@ -122,6 +118,10 @@ NEW: TakePOS - show product reference NEW: TakePOS - add constant to hide categories NEW: TakePOS - add constant to show category description NEW: TakePOS - add constant to show only the products in stock +NEW: Themes - add param color button action +NEW: Themes - Change in theme colors does not need to use the refresh button +NEW: Themes - more mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...) +NEW: Themes - MD - add param border table for md theme NEW: Third-Parties - Add rules "customer accountancy code" is mandatory to validate invoice NEW: Third-Parties - Can set the parent company during the creation of thirdparty (action=add of societe/card.php) NEW: Tickets - create Third-party with contact if not found on public ticket diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index a76fa1945c2..71e80f703af 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -480,8 +480,8 @@ if (empty($reshook)) { // Mass actions $objectclass = 'Bookkeeping'; $objectlabel = 'Bookkeeping'; - $permissiontoread = $user->rights->societe->lire; - $permissiontodelete = $user->rights->societe->supprimer; + $permissiontoread = $user->hasRight('societe', 'lire'); + $permissiontodelete = $user->hasRight('societe', 'supprimer'); $permissiontoadd = $user->rights->societe->creer; $uploaddir = $conf->societe->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index ba94415782f..e417f21832c 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -395,8 +395,8 @@ if (empty($reshook)) { // Mass actions $objectclass = 'Bookkeeping'; $objectlabel = 'Bookkeeping'; - $permissiontoread = $user->rights->societe->lire; - $permissiontodelete = $user->rights->societe->supprimer; + $permissiontoread = $user->hasRight('societe', 'lire'); + $permissiontodelete = $user->hasRight('societe', 'supprimer'); $permissiontoadd = $user->rights->societe->creer; $uploaddir = $conf->societe->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php index 8831f06fd06..26c39df5b63 100644 --- a/htdocs/adherents/admin/website.php +++ b/htdocs/adherents/admin/website.php @@ -59,6 +59,7 @@ if ($action == 'update') { $public = GETPOST('MEMBER_ENABLE_PUBLIC'); $amount = price2num(GETPOST('MEMBER_NEWFORM_AMOUNT'), 'MT', 2); $editamount = GETPOST('MEMBER_NEWFORM_EDITAMOUNT'); + $publiccounters = GETPOST('MEMBER_COUNTERS_ARE_PUBLIC'); $payonline = GETPOST('MEMBER_NEWFORM_PAYONLINE'); $forcetype = GETPOST('MEMBER_NEWFORM_FORCETYPE', 'int'); $forcemorphy = GETPOST('MEMBER_NEWFORM_FORCEMORPHY', 'aZ09'); @@ -66,6 +67,7 @@ if ($action == 'update') { $res = dolibarr_set_const($db, "MEMBER_ENABLE_PUBLIC", $public, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "MEMBER_NEWFORM_AMOUNT", $amount, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "MEMBER_NEWFORM_EDITAMOUNT", $editamount, 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "MEMBER_COUNTERS_ARE_PUBLIC", $publiccounters, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "MEMBER_NEWFORM_PAYONLINE", $payonline, 'chaine', 0, '', $conf->entity); if ($forcetype < 0) { $res = dolibarr_del_const($db, "MEMBER_NEWFORM_FORCETYPE", $conf->entity); @@ -237,6 +239,13 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) { print $form->selectyesno("MEMBER_NEWFORM_EDITAMOUNT", (!empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT) ? $conf->global->MEMBER_NEWFORM_EDITAMOUNT : 0), 1); print "\n"; + // SHow counter of validated members publicly + print ''; + print $langs->trans("MemberCountersArePublic"); + print ''; + print $form->selectyesno("MEMBER_COUNTERS_ARE_PUBLIC", (!empty($conf->global->MEMBER_COUNTERS_ARE_PUBLIC) ? $conf->global->MEMBER_COUNTERS_ARE_PUBLIC : 0), 1); + print "\n"; + // Jump to an online payment page print ''; print $langs->trans("MEMBER_NEWFORM_PAYONLINE"); diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index b02d05ca478..303e6f3cfec 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -186,7 +186,7 @@ if (isModEnabled('adherent') && !empty($user->rights->adherent->lire)) { if (isModEnabled('recruitment') && !empty($user->rights->recruitment->recruitmentjobposition->read)) { $elementList['recruitmentcandidature_send'] = img_picto('', 'recruitmentcandidature', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('RecruitmentCandidatures')); } -if (isModEnabled("societe") && !empty($user->rights->societe->lire)) { +if (isModEnabled("societe") && $user->hasRight('societe', 'lire')) { $elementList['thirdparty'] = img_picto('', 'company', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToThirdparty')); } if (isModEnabled('project')) { diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index d4d652f3e74..2c7653c3bb3 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -272,7 +272,7 @@ class Documents extends DolibarrApi if ($modulepart == 'societe' || $modulepart == 'thirdparty') { require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index 96caac1dbb4..373effecbe8 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -397,7 +397,7 @@ if (!empty($user->rights->produit->lire) || !empty($user->rights->service->lire) print ''; } -if (!empty($user->rights->societe->lire)) { +if ($user->hasRight('societe', 'lire')) { print ''; print '
'; print '
'; diff --git a/htdocs/bom/ajax/ajax.php b/htdocs/bom/ajax/ajax.php new file mode 100644 index 00000000000..9a55c609252 --- /dev/null +++ b/htdocs/bom/ajax/ajax.php @@ -0,0 +1,67 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/bom/ajax/ajax.php + * \brief Ajax component for BOM. + */ + +if (!defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); // Disables token renewal +} +if (!defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); +} +if (!defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (!defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); +} +if (!defined('NOBROWSERNOTIF')) { + define('NOBROWSERNOTIF', '1'); +} + +include_once '../../main.inc.php'; // Load $user and permissions +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php'; + + +$action = GETPOST('action', 'aZ09'); +$idproduct = GETPOST('idproduct', 'int'); + + +/* + * View + */ + +top_httphead(); + +if ($action == 'getDurationUnitByProduct' && $user->hasRight('product', 'lire')) { + $product = new Product($db); + $res = $product->fetch($idproduct); + + $cUnit = new CUnits($db); + $fk_unit = $cUnit->getUnitFromCode($product->duration_unit, 'short_label', 'time'); + + echo json_encode($fk_unit); + exit(); +} diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 2cf2b3a4dd3..294d57fea9c 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -17,9 +17,9 @@ */ /** - * \file htdocs/bom/bom_card.php - * \ingroup bom - * \brief Page to create/edit/view bom + * \file htdocs/bom/bom_card.php + * \ingroup bom + * \brief Page to create/edit/view BOM */ // Load Dolibarr environment @@ -32,7 +32,9 @@ require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("mrp", "other")); +$langs->loadLangs(array('mrp', 'other')); + +global $filtertype; // Get parameters $id = GETPOST('id', 'int'); @@ -158,14 +160,14 @@ if (empty($reshook)) { $idprod = $bom_child->fk_product; } } else { - $idprod = (int) GETPOST('idprod', 'int'); + $idprod = (!empty(GETPOST('idprodservice', 'int')) ? GETPOST('idprodservice', 'int') : (int) GETPOST('idprod', 'int')); } $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); $qty_frozen = price2num(GETPOST('qty_frozen', 'alpha'), 'MS'); $disable_stock_change = GETPOST('disable_stock_change', 'int'); $efficiency = price2num(GETPOST('efficiency', 'alpha')); - + $fk_unit = GETPOST('fk_unit', 'alphanohtml'); if ($qty == '') { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; @@ -191,19 +193,22 @@ if (empty($reshook)) { } if (!$error) { - $result = $object->addLine($idprod, $qty, $qty_frozen, $disable_stock_change, $efficiency, -1, $bom_child_id, null); + $result = $object->addLine($idprod, $qty, $qty_frozen, $disable_stock_change, $efficiency, -1, $bom_child_id, null, $fk_unit); if ($result <= 0) { setEventMessages($object->error, $object->errors, 'errors'); $action = ''; } else { unset($_POST['idprod']); + unset($_POST['idprodservice']); unset($_POST['qty']); unset($_POST['qty_frozen']); unset($_POST['disable_stock_change']); - - $object->fetchLines(); } + + $object->fetchLines(); + + $object->calculateCosts(); } } @@ -217,6 +222,7 @@ if (empty($reshook)) { $qty_frozen = price2num(GETPOST('qty_frozen', 'alpha'), 'MS'); $disable_stock_change = GETPOST('disable_stock_change', 'int'); $efficiency = price2num(GETPOST('efficiency', 'alpha')); + $fk_unit = GETPOST('fk_unit', 'alphanohtml'); if ($qty == '') { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); @@ -227,248 +233,250 @@ if (empty($reshook)) { $bomline = new BOMLine($db); $bomline->fetch($lineid); - $result = $object->updateLine($lineid, $qty, (int) $qty_frozen, (int) $disable_stock_change, $efficiency, $bomline->position, $bomline->import_key); + $result = $object->updateLine($lineid, $qty, (int) $qty_frozen, (int) $disable_stock_change, $efficiency, $bomline->position, $bomline->import_key, $fk_unit); if ($result <= 0) { setEventMessages($object->error, $object->errors, 'errors'); $action = ''; } else { unset($_POST['idprod']); + unset($_POST['idprodservice']); unset($_POST['qty']); unset($_POST['qty_frozen']); unset($_POST['disable_stock_change']); - - $object->fetchLines(); } + + $object->fetchLines(); + + $object->calculateCosts(); } } -} -/* - * View - */ + /* + * View + */ -$form = new Form($db); -$formfile = new FormFile($db); + $form = new Form($db); + $formfile = new FormFile($db); -$title = $langs->trans('BOM'); -$help_url ='EN:Module_BOM'; -llxHeader('', $title, $help_url); + $title = $langs->trans('BOM'); + $help_url ='EN:Module_BOM'; + llxHeader('', $title, $help_url); -// Part to create -if ($action == 'create') { - print load_fiche_titre($langs->trans("NewBOM"), '', 'bom'); + // Part to create + if ($action == 'create') { + print load_fiche_titre($langs->trans("NewBOM"), '', 'bom'); - print '
'; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; - print dol_get_fiche_head(array(), ''); + print dol_get_fiche_head(array(), ''); - print ''."\n"; + print '
'."\n"; - // Common attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; + // Common attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; - print '
'."\n"; + print ''."\n"; - print dol_get_fiche_end(); + print dol_get_fiche_end(); - print $form->buttonsSaveCancel("Create"); + print $form->buttonsSaveCancel("Create"); - print '
'; -} - -// Part to edit record -if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans("BillOfMaterials"), '', 'cubes'); - - print '
'; - print ''; - print ''; - print ''; - print ''; - - print dol_get_fiche_head(); - - //$object->fields['keyfield']['disabled'] = 1; - - print ''."\n"; - - // Common attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; - - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; - - print '
'; - - print dol_get_fiche_end(); - - print $form->buttonsSaveCancel("Create"); - - print '
'; -} - -// Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { - $head = bomPrepareHead($object); - print dol_get_fiche_head($head, 'card', $langs->trans("BillOfMaterials"), -1, 'bom'); - - $formconfirm = ''; - - // Confirmation to delete - if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBillOfMaterials'), $langs->trans('ConfirmDeleteBillOfMaterials'), 'confirm_delete', '', 0, 1); - } - // Confirmation to delete line - if ($action == 'deleteline') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + print ''; } - // Confirmation of validation - if ($action == 'validate') { - // We check that object has a temporary ref - $ref = substr($object->ref, 1, 4); - if ($ref == 'PROV') { - $object->fetch_product(); - $numref = $object->getNextNumRef($object->product); - } else { - $numref = $object->ref; + // Part to edit record + if (($id || $ref) && $action == 'edit') { + print load_fiche_titre($langs->trans("BillOfMaterials"), '', 'cubes'); + + print '
'; + print ''; + print ''; + print ''; + print ''; + + print dol_get_fiche_head(); + + //$object->fields['keyfield']['disabled'] = 1; + + print ''."\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; + + print '
'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel("Create"); + + print '
'; + } + + // Part to show record + if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $head = bomPrepareHead($object); + print dol_get_fiche_head($head, 'card', $langs->trans("BillOfMaterials"), -1, 'bom'); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBillOfMaterials'), $langs->trans('ConfirmDeleteBillOfMaterials'), 'confirm_delete', '', 0, 1); + } + // Confirmation to delete line + if ($action == 'deleteline') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); } - $text = $langs->trans('ConfirmValidateBom', $numref); - /*if (!empty($conf->notification->enabled)) - { + // Confirmation of validation + if ($action == 'validate') { + // We check that object has a temporary ref + $ref = substr($object->ref, 1, 4); + if ($ref == 'PROV') { + $object->fetch_product(); + $numref = $object->getNextNumRef($object->product); + } else { + $numref = $object->ref; + } + + $text = $langs->trans('ConfirmValidateBom', $numref); + /*if (! empty($conf->notification->enabled)) + { require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php'; $notify = new Notify($db); $text .= '
'; $text .= $notify->confirmMessage('BOM_VALIDATE', $object->socid, $object); - }*/ + }*/ - $formquestion = array(); - if (!empty($conf->bom->enabled)) { - $langs->load("mrp"); - $forcecombo = 0; - if ($conf->browser->name == 'ie') { - $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy - } - $formquestion = array( + $formquestion = array(); + if (!empty($conf->bom->enabled)) { + $langs->load("mrp"); + $forcecombo = 0; + if ($conf->browser->name == 'ie') { + $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy + } + $formquestion = array( // 'text' => $langs->trans("ConfirmClone"), // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - ); + ); + } + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220); } - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220); - } - - // Confirmation of closing - if ($action == 'close') { - $text = $langs->trans('ConfirmCloseBom', $object->ref); - /*if (!empty($conf->notification->enabled)) - { + // Confirmation of closing + if ($action == 'close') { + $text = $langs->trans('ConfirmCloseBom', $object->ref); + /*if (! empty($conf->notification->enabled)) + { require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php'; $notify = new Notify($db); $text .= '
'; $text .= $notify->confirmMessage('BOM_CLOSE', $object->socid, $object); - }*/ + }*/ - $formquestion = array(); - if (!empty($conf->bom->enabled)) { - $langs->load("mrp"); - $forcecombo = 0; - if ($conf->browser->name == 'ie') { - $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy - } - $formquestion = array( + $formquestion = array(); + if (!empty($conf->bom->enabled)) { + $langs->load("mrp"); + $forcecombo = 0; + if ($conf->browser->name == 'ie') { + $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy + } + $formquestion = array( // 'text' => $langs->trans("ConfirmClone"), // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - ); + ); + } + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $text, 'confirm_close', $formquestion, 0, 1, 220); } - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $text, 'confirm_close', $formquestion, 0, 1, 220); - } + // Confirmation of reopen + if ($action == 'reopen') { + $text = $langs->trans('ConfirmReopenBom', $object->ref); + /*if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php'; + $notify = new Notify($db); + $text .= '
'; + $text .= $notify->confirmMessage('BOM_CLOSE', $object->socid, $object); + }*/ - // Confirmation of reopen - if ($action == 'reopen') { - $text = $langs->trans('ConfirmReopenBom', $object->ref); - /*if (!empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php'; - $notify = new Notify($db); - $text .= '
'; - $text .= $notify->confirmMessage('BOM_CLOSE', $object->socid, $object); - }*/ - - $formquestion = array(); - if (!empty($conf->bom->enabled)) { - $langs->load("mrp"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $forcecombo = 0; - if ($conf->browser->name == 'ie') { - $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy - } - $formquestion = array( + $formquestion = array(); + if (!empty($conf->bom->enabled)) { + $langs->load("mrp"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $forcecombo = 0; + if ($conf->browser->name == 'ie') { + $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy + } + $formquestion = array( // 'text' => $langs->trans("ConfirmClone"), // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - ); + ); + } + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $text, 'confirm_reopen', $formquestion, 0, 1, 220); } - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $text, 'confirm_reopen', $formquestion, 0, 1, 220); - } + // Clone confirmation + if ($action == 'clone') { + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneBillOfMaterials', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } - // Clone confirmation - if ($action == 'clone') { - // Create an array for form - $formquestion = array(); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneBillOfMaterials', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); - } + // Confirmation of action xxxx + if ($action == 'setdraft') { + $text = $langs->trans('ConfirmSetToDraft', $object->ref); - // Confirmation of action xxxx - if ($action == 'setdraft') { - $text = $langs->trans('ConfirmSetToDraft', $object->ref); + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SetToDraft'), $text, 'confirm_setdraft', $formquestion, 0, 1, 220); + } - $formquestion = array(); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SetToDraft'), $text, 'confirm_setdraft', $formquestion, 0, 1, 220); - } + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } - // Call Hook formConfirm - $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); - $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if (empty($reshook)) { - $formconfirm .= $hookmanager->resPrint; - } elseif ($reshook > 0) { - $formconfirm = $hookmanager->resPrint; - } - - // Print form confirm - print $formconfirm; + // Print form confirm + print $formconfirm; - // Object card - // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; - $morehtmlref = '
'; - /* - // Ref bis - $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->bom->creer, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->bom->creer, 'string', '', null, null, '', 1); - // Thirdparty - $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); - // Project - if (isModEnabled('project')) - { + $morehtmlref = '
'; + /* + // Ref bis + $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->bom->creer, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->bom->creer, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); + // Project + if (isModEnabled('project')) + { $langs->load("projects"); $morehtmlref.='
'.$langs->trans('Project') . ' '; if ($permissiontoadd) @@ -487,7 +495,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); } } else { - if (!empty($object->fk_project)) { + if (! empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); $morehtmlref.=$proj->getNomUrl(); @@ -495,76 +503,133 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtmlref.=''; } } - } - */ - $morehtmlref .= '
'; + } + */ + $morehtmlref .= '
'; - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - print '
'; - print '
'; - print '
'; - print ''."\n"; + print '
'; + print '
'; + print '
'; + print '
'."\n"; - // Common attributes - $keyforbreak = 'duration'; - include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; - $object->calculateCosts(); - print ''; - print ''; + // Common attributes + $keyforbreak = 'duration'; + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + $object->calculateCosts(); + print ''; + print ''; - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; - print '
'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).'
'.$langs->trans("UnitCost").''.price($object->unit_cost).'
'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).'
'.$langs->trans("UnitCost").''.price($object->unit_cost).'
'; - print '
'; - print '
'; + print ''; + print '
'; + print ''; - print '
'; + print '
'; - print dol_get_fiche_end(); + print dol_get_fiche_end(); - /* - * Lines - */ + /* + * Lines + */ - if (!empty($object->table_element_line)) { - print '
- - + if (!empty($object->table_element_line)) { + //Products + $res = $object->fetchLinesbytypeproduct(0); + $object->calculateCosts(); + + print ($res == 0 && $object->status >= $object::STATUS_VALIDATED) ? '' : load_fiche_titre($langs->trans('BOMProductsList'), '', 'product'); + + print ' + + - + '; - if (!empty($conf->use_javascript_ajax) && $object->status == 0) { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } + if (!empty($conf->use_javascript_ajax) && $object->status == 0) { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } - print '
'; - if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { - print ''; - } + print '
'; + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print '
'; + } - if (!empty($object->lines)) { - $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1, '/bom/tpl'); - } + if (!empty($object->lines)) { + $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1, '/bom/tpl'); + } - // Form to add new line - if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') { - if ($action != 'editline') { - // Add products/services form + // Form to add new line + if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') { + if ($action != 'editline') { + // Add products/services form - $parameters = array(); - $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - if (empty($reshook)) + $parameters = array(); + $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + if (empty($reshook)) $object->formAddObjectLine(1, $mysoc, null, '/bom/tpl'); + } + } + + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print '
'; + } + print '
'; + + print "
\n"; + + mrpCollapseBomManagement(); + + + //Services + $filtertype = 1; + $res = $object->fetchLinesbytypeproduct(1); + $object->calculateCosts(); + + print ($res == 0 && $object->status >= $object::STATUS_VALIDATED) ? '' : load_fiche_titre($langs->trans('BOMServicesList'), '', 'service'); + + print '
+ + + + + '; + + if (!empty($conf->use_javascript_ajax) && $object->status == 0) { + $tagidfortablednd = 'tablelinesservice'; + include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; + } + + print '
'; + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print ''; + } + + if (!empty($object->lines)) { + $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1, '/bom/tpl'); + } + + // Form to add new line + if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') { + if ($action != 'editline') { + // Add services form + $parameters = array(); + $reshook = $hookmanager->executeHooks('formAddObjectServiceLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + if (empty($reshook)) + $object->formAddObjectLine(1, $mysoc, null, '/bom/tpl'); + } } } @@ -578,6 +643,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea mrpCollapseBomManagement(); } + $res = $object->fetchLines(); // Buttons for actions diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 7ff9627f25b..ddb589a567d 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -23,6 +23,8 @@ // Put here all includes required by your class file require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; @@ -399,6 +401,58 @@ class BOM extends CommonObject return $result; } + /** + * Load object lines in memory from the database by type of product + * + * @param int $typeproduct 0 type product, 1 type service + + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetchLinesbytypeproduct($typeproduct = 0) + { + $this->lines = array(); + + $objectlineclassname = get_class($this).'Line'; + if (!class_exists($objectlineclassname)) { + $this->error = 'Error, class '.$objectlineclassname.' not found during call of fetchLinesCommon'; + return -1; + } + + $objectline = new $objectlineclassname($this->db); + + $sql = "SELECT ".$objectline->getFieldList('l'); + $sql .= " FROM ".$this->db->prefix().$objectline->table_element." as l"; + $sql .= " LEFT JOIN ".$this->db->prefix()."product as p ON p.rowid = l.fk_product"; + $sql .= " WHERE l.fk_".$this->db->escape($this->element)." = ".((int) $this->id); + $sql .= " AND p.fk_product_type = ". ((int) $typeproduct); + if (isset($objectline->fields['position'])) { + $sql .= $this->db->order('position', 'ASC'); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num_rows = $this->db->num_rows($resql); + $i = 0; + while ($i < $num_rows) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $newline = new $objectlineclassname($this->db); + $newline->setVarsFromFetchObj($obj); + + $this->lines[] = $newline; + } + $i++; + } + + return $num_rows; + } else { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->error; + return -1; + } + } + + /** * Load list of objects in memory from the database. * @@ -515,7 +569,7 @@ class BOM extends CommonObject * @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) + 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, $fk_unit = '') { global $mysoc, $conf, $langs, $user; @@ -583,6 +637,7 @@ class BOM extends CommonObject $this->line->fk_bom_child = $fk_bom_child; $this->line->import_key = $import_key; $this->line->position = $rankToUse; + $this->line->fk_unit = $fk_unit; $result = $this->line->create($user); @@ -612,9 +667,10 @@ class BOM extends CommonObject * @param float $efficiency Efficiency in MO * @param int $position Position of BOM-Line in BOM-Lines * @param string $import_key Import Key + * @param int $fk_unit Unit of line * @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) + public function updateLine($rowid, $qty, $qty_frozen = 0, $disable_stock_change = 0, $efficiency = 1.0, $position = -1, $import_key = null, $fk_unit = 0) { global $mysoc, $conf, $langs, $user; @@ -684,6 +740,7 @@ class BOM extends CommonObject $this->line->efficiency = $efficiency; $this->line->import_key = $import_key; $this->line->position = $rankToUse; + if(!empty($fk_unit)) $this->line->fk_unit = $fk_unit; $result = $this->line->update($user); @@ -1260,6 +1317,8 @@ class BOM extends CommonObject */ public function calculateCosts() { + global $conf; + include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $this->unit_cost = 0; $this->total_cost = 0; @@ -1272,38 +1331,62 @@ class BOM extends CommonObject foreach ($this->lines as &$line) { $tmpproduct->cost_price = 0; $tmpproduct->pmp = 0; + $result = $tmpproduct->fetch($line->fk_product, '', '', '', 0, 1, 1); // We discard selling price and language loading - if (empty($line->fk_bom_child)) { - $result = $tmpproduct->fetch($line->fk_product, '', '', '', 0, 1, 1); // We discard selling price and language loading - if ($result < 0) { - $this->error = $tmpproduct->error; - return -1; - } - $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); - if (empty($line->unit_cost)) { - if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { - $line->unit_cost = $productFournisseur->fourn_unitprice; + if ($tmpproduct->type == $tmpproduct::TYPE_PRODUCT) { + if (empty($line->fk_bom_child)) { + if ($result < 0) { + $this->error = $tmpproduct->error; + return -1; + } + $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); + if (empty($line->unit_cost)) { + if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { + $line->unit_cost = $productFournisseur->fourn_unitprice; + } + } + + $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); + + $this->total_cost += $line->total_cost; + } else { + $bom_child = new BOM($this->db); + $res = $bom_child->fetch($line->fk_bom_child); + if ($res > 0) { + $bom_child->calculateCosts(); + $line->childBom[] = $bom_child; + $this->total_cost += $bom_child->total_cost * $line->qty; + } else { + $this->error = $bom_child->error; + return -2; } } + } else { + //Convert qty to hour + $unit = measuringUnitString($line->fk_unit, '', '', 1); + $qty = convertDurationtoHour($line->qty, $unit); - $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); + if ($conf->workstation->enabled) { + if ($tmpproduct->fk_default_workstation) { + $workstation = new Workstation($this->db); + $res = $workstation->fetch($tmpproduct->fk_default_workstation); + + if ($res > 0) $line->total_cost = price2num($qty * ($workstation->thm_operator_estimated + $workstation->thm_machine_estimated), 'MT'); + else { + $this->error = $workstation->error; + return -3; + } + } + } else { + $line->total_cost = price2num($qty * $tmpproduct->cost_price, 'MT'); + } $this->total_cost += $line->total_cost; - } else { - $bom_child= new BOM($this->db); - $res = $bom_child->fetch($line->fk_bom_child); - if ($res>0) { - $bom_child->calculateCosts(); - $line->childBom[] = $bom_child; - $this->total_cost += $bom_child->total_cost * $line->qty; - } else { - $this->error = $bom_child->error; - return -2; - } } } $this->total_cost = price2num($this->total_cost, 'MT'); + if ($this->qty > 0) { $this->unit_cost = price2num($this->total_cost / $this->qty, 'MU'); } elseif ($this->qty < 0) { @@ -1478,6 +1561,7 @@ class BOMLine extends CommonObjectLine 'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'), 'disable_stock_change' => array('type'=>'smallint', 'label'=>'DisableStockChange', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>108, 'css'=>'maxwidth50imp', 'help'=>'DisableStockChangeHelp'), 'efficiency' => array('type'=>'double(24,8)', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'position'=>110, 'notnull'=>1, 'css'=>'maxwidth50imp', 'help'=>'ValueOfEfficiencyConsumedMeans'), + 'fk_unit' => array('type'=>'integer', 'label'=>'Unit', 'enabled'=>1, 'visible'=>1, 'position'=>120, 'notnull'=>-1,), 'position' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>1, 'visible'=>0, 'default'=>0, 'position'=>200, 'notnull'=>1,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,), ); diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index e895d534fac..41aeec4b96f 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -29,6 +29,8 @@ * $forceall (0 by default, 1 for supplier invoices/orders) */ +require_once DOL_DOCUMENT_ROOT."/product/class/html.formproduct.class.php"; + // Protection to avoid direct call of template if (empty($object) || !is_object($object)) { print "Error: this template page cannot be called directly as an URL"; @@ -36,12 +38,18 @@ if (empty($object) || !is_object($object)) { } -global $forceall, $forcetoshowtitlelines; +global $forceall, $forcetoshowtitlelines, $filtertype; if (empty($forceall)) { $forceall = 0; } +if (empty($filtertype)) $filtertype = 0; +if (!empty($object->element) && $object->element == 'contrat' && empty($conf->global->STOCK_SUPPORT_SERVICES)) { + $filtertype = -1; +} + +$formproduct = new FormProduct($object->db); // Define colspan for the button 'Add' $colspan = 3; // Columns: total ht + col edit + col delete @@ -53,6 +61,7 @@ $objectline = new BOMLine($this->db); print "\n"; $nolinesbefore = (count($this->lines) == 0 || $forcetoshowtitlelines); + if ($nolinesbefore) { print ''; if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { @@ -62,16 +71,24 @@ if ($nolinesbefore) { print '
'.$langs->trans('AddNewLine').''; print ''; print ''; - if (!empty($conf->global->PRODUCT_USE_UNITS)) { - print ''; + + if ($filtertype != 1) { + if (!empty($conf->global->PRODUCT_USE_UNITS)) { + print ''; + } + print ''; + print ''; + print ''; + } else { + print ''; + if ($conf->workstation->enabled) print ''; + print ''; } - print ''; - print ''; - print ''; - print ''; + + print ''; print ''; } print ''; @@ -88,25 +105,23 @@ print ''; -if (!empty($conf->global->PRODUCT_USE_UNITS)) { +if ($filtertype != 1) { + if (!empty($conf->global->PRODUCT_USE_UNITS)) { + $coldisplay++; + print ''; + } + $coldisplay++; - print ''; + + + $coldisplay++; + print ''; + + $coldisplay++; + print ''; + + $coldisplay++; + print ''; +} else { + $coldisplay++; + require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php'; + $cUnit = new CUnits($this->db); + $fk_unit_default = $cUnit->getUnitFromCode('h', 'short_label', 'time'); + print ''; + + $coldisplay++; + print ''; + + $coldisplay++; + print ''; } -$coldisplay++; -print ''; + $coldisplay += $colspan; + print ''; + print ''; -$coldisplay++; -print ''; - -$coldisplay++; -print ''; - -$coldisplay++; -print ''; - -$coldisplay += $colspan; -print ''; -print ''; if (is_object($objectline)) { print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', 1, 'line'); @@ -175,6 +212,27 @@ jQuery(document).ready(function() { } } }); + + //change unit selected if we change service selected + + $('#idprodservice').change(function(){ + var idproduct = $(this).val(); + + $.ajax({ + url : "" + ,type: 'POST' + ,data: { + 'action': 'getDurationUnitByProduct' + ,'idproduct' : idproduct + } + }).done(function(data) { + + console.log(data); + var data = JSON.parse(data); + $("#fk_unit").val(data).change(); + }); + }); + }); diff --git a/htdocs/bom/tpl/objectline_edit.tpl.php b/htdocs/bom/tpl/objectline_edit.tpl.php index e5f24fa994f..0ce88fa359c 100644 --- a/htdocs/bom/tpl/objectline_edit.tpl.php +++ b/htdocs/bom/tpl/objectline_edit.tpl.php @@ -31,6 +31,9 @@ * $inputalsopricewithtax (0 by default, 1 to also show column with unit price including tax) */ +require_once DOL_DOCUMENT_ROOT."/product/class/html.formproduct.class.php"; + + // Protection to avoid direct call of template if (empty($object) || !is_object($object)) { print "Error, template page can't be called as URL"; @@ -38,12 +41,16 @@ if (empty($object) || !is_object($object)) { } -global $forceall; +global $forceall, $filtertype; if (empty($forceall)) { $forceall = 0; } +if (empty($filtertype)) $filtertype = 0; + +$formproduct = new FormProduct($object->db); + // Define colspan for the button 'Add' $colspan = 3; // Columns: total ht + col edit + col delete @@ -108,28 +115,43 @@ if (($line->info_bits & 2) != 2) { } print ''; -if (!empty($conf->global->PRODUCT_USE_UNITS)) { +if ($filtertype != 1) { + if (!empty($conf->global->PRODUCT_USE_UNITS)) { + $coldisplay++; + print ''; + } + $coldisplay++; - print ''; + + $coldisplay++; + print ''; + + $coldisplay++; + print ''; + + $coldisplay++; + print ''; +} else { + $coldisplay++; + print ''; + + $coldisplay++; + print ''; + + $coldisplay++; + print ''; } -$coldisplay++; -print ''; - -$coldisplay++; -print ''; - -$coldisplay++; -print ''; - -$coldisplay++; -print ''; - $coldisplay += $colspan; print ''; // Qty -print ''; +print ''; -if (!empty($conf->global->PRODUCT_USE_UNITS)) { - print ''; +if ($filtertype != 1) { + if (!empty($conf->global->PRODUCT_USE_UNITS)) { + print ''; + } + + // Qty frozen + print ''; + + // Disable stock change + print ''; + + // Efficiency + print ''; + + // Cost + print ''; +} else { + print ''; + + if ($conf->workstation->enabled) print ''; + + // Cost + print ''; } -// Qty frozen -print ''; -// Disable stock change -print ''; -// Efficiency -print ''; - -// Cost -print ''; print ''; // No width to allow autodim diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 61b394a3b0f..a3b9df0bdf0 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -34,12 +34,17 @@ * $type, $text, $description, $line */ +require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; + // Protection to avoid direct call of template if (empty($object) || !is_object($object)) { print "Error, template page can't be called as URL"; exit; } +global $filtertype; +if (empty($filtertype)) $filtertype = 0; + global $forceall, $senderissupplier, $inputalsopricewithtax, $outputalsopricetotalwithtax, $langs; @@ -60,7 +65,9 @@ if (empty($outputalsopricetotalwithtax)) { } // add html5 elements -$domData = ' data-element="'.$line->element.'"'; +if ($filtertype == 1) $domData = ' data-element="'.$line->element.'service"'; +else $domData = ' data-element="'.$line->element.'"'; + $domData .= ' data-id="'.$line->id.'"'; $domData .= ' data-qty="'.$line->qty.'"'; $domData .= ' data-product_type="'.$line->product_type.'"'; @@ -100,29 +107,54 @@ $coldisplay++; echo price($line->qty, 0, '', 0, 0); // Yes, it is a quantity, not a price, but we just want the formating role of function price print ''; -if (!empty($conf->global->PRODUCT_USE_UNITS)) { - print ''; } + + print ''; + print ''; + + print ''; +} else { + //Unité + print ''; + + //Poste de travail + if ($conf->workstation->enabled) { + $workstation = new Workstation($object->db); + $res = $workstation->fetch($tmpproduct->fk_default_workstation); + + print ''; + } } - -print ''; -print ''; - -print ''; - $total_cost = 0; print ''; if ($num == 0) { - print ''; + print ''; } else { while ($obj = $db->fetch_object($resql)) { $user = new User($db); diff --git a/htdocs/hrm/admin/admin_establishment.php b/htdocs/hrm/admin/admin_establishment.php index f28c0285e1f..00722526e9d 100644 --- a/htdocs/hrm/admin/admin_establishment.php +++ b/htdocs/hrm/admin/admin_establishment.php @@ -16,10 +16,12 @@ */ /** - * \file htdocs/hrm/admin/admin_establishment.php - * \ingroup HRM - * \brief HRM Establishment module setup page + * \file htdocs/hrm/admin/admin_establishment.php + * \ingroup HRM + * \brief HRM Establishment module setup page */ + +// Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm.lib.php'; require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php'; @@ -29,8 +31,9 @@ $langs->loadLangs(array('admin', 'hrm')); $error = 0; +// Permissions $permissiontoread = $user->admin; -$permissiontoadd = $user->admin; +$permissiontoadd = $user->admin; // Security check - Protection if external user //if ($user->socid > 0) accessforbidden(); diff --git a/htdocs/hrm/admin/admin_hrm.php b/htdocs/hrm/admin/admin_hrm.php index 6763fb43f8e..dc8d20403a3 100644 --- a/htdocs/hrm/admin/admin_hrm.php +++ b/htdocs/hrm/admin/admin_hrm.php @@ -16,10 +16,12 @@ */ /** - * \file htdocs/hrm/admin/admin_hrm.php - * \ingroup HRM - * \brief HRM module setup page + * \file htdocs/hrm/admin/admin_hrm.php + * \ingroup HRM + * \brief HRM module setup page */ + +// Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/hrm.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; @@ -27,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'hrm')); +// Get Parameters $action = GETPOST('action', 'aZ09'); // Other parameters HRM_* @@ -34,8 +37,9 @@ $list = array( // 'HRM_EMAIL_EXTERNAL_SERVICE' // To prevent your public accountant for example ); +// Permissions $permissiontoread = $user->admin; -$permissiontoadd = $user->admin; +$permissiontoadd = $user->admin; // Security check - Protection if external user //if ($user->socid > 0) accessforbidden(); diff --git a/htdocs/hrm/job_agenda.php b/htdocs/hrm/job_agenda.php index b6ce99c9801..808ceea430f 100644 --- a/htdocs/hrm/job_agenda.php +++ b/htdocs/hrm/job_agenda.php @@ -20,24 +20,24 @@ */ /** - * \file job_agenda.php - * \ingroup hrm - * \brief Tab of events on Job + * \file htdocs/hrm/job_agenda.php + * \ingroup hrm + * \brief Tab of events on Job */ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("hrm", "other")); +$langs->loadLangs(array('hrm', 'other')); // Get parameters $id = GETPOST('id', 'int'); @@ -87,8 +87,9 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->hrm->multidir_output[$object->entity]."/".$object->id; } +// Permissions $permissiontoread = $user->rights->hrm->all->read; -$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); diff --git a/htdocs/hrm/position_card.php b/htdocs/hrm/position_card.php index 746e1265a0b..168756d9851 100644 --- a/htdocs/hrm/position_card.php +++ b/htdocs/hrm/position_card.php @@ -337,7 +337,7 @@ function displayPositionCard(&$object) // */ // $filedir = $conf->societe->multidir_output[$object->entity].'/'.$object->id; // $urlsource = $_SERVER["PHP_SELF"]."?socid=".$object->id; -// $genallowed = $user->rights->societe->lire; +// $genallowed = $user->hasRight('societe', 'lire'); // $delallowed = $user->rights->societe->creer; // // print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); diff --git a/htdocs/hrm/position_document.php b/htdocs/hrm/position_document.php index c51f2204441..30f33453c03 100644 --- a/htdocs/hrm/position_document.php +++ b/htdocs/hrm/position_document.php @@ -20,9 +20,9 @@ */ /** - * \file position_document.php - * \ingroup hrm - * \brief Tab for documents linked to Position + * \file htdocs/hrm/position_document.php + * \ingroup hrm + * \brief Tab for documents linked to Position */ // Load Dolibarr environment @@ -39,13 +39,13 @@ require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; // Load translation files required by the page $langs->loadLangs(array("hrm", "companies", "other", "mails")); - +// Get parameters $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm'); $id = (GETPOST('socid', 'int') ? GETPOST('socid', 'int') : GETPOST('id', 'int')); $ref = GETPOST('ref', 'alpha'); -// Get parameters +// Get parameters for pagination $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); @@ -79,8 +79,9 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->hrm->multidir_output[$object->entity ? $object->entity : $conf->entity]."/position/".get_exdir(0, 0, 0, 1, $object); } +// Permissions $permissiontoread = $user->rights->hrm->all->read; -$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); 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 01cbb851d51..4d7bca3f7c9 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 @@ -147,8 +147,14 @@ ALTER TABLE llx_user CHANGE COLUMN note note_private text; UPDATE llx_c_effectif SET code='EF101-500', libelle='101 - 500' WHERE code='EF100-500'; + +ALTER TABLE llx_product ADD COLUMN fk_default_workstation integer DEFAULT NULL; +ALTER TABLE llx_bom_bomline ADD COLUMN fk_unit integer DEFAULT NULL; + ALTER TABLE llx_rights_def ADD COLUMN tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +UPDATE llx_establishment SET name='' WHERE name IS NULL; +ALTER TABLE llx_establishment CHANGE name label varchar(255) NOT NULL; ALTER TABLE llx_don ADD UNIQUE INDEX idx_don_uk_ref (ref, entity); @@ -170,3 +176,4 @@ create table llx_element_categorie ALTER TABLE llx_element_categorie ADD UNIQUE INDEX idx_element_categorie_idx (fk_element, fk_categorie); ALTER TABLE llx_element_categorie ADD CONSTRAINT fk_element_categorie_fk_categorie FOREIGN KEY (fk_categorie) REFERENCES llx_fk_categorie(rowid); + diff --git a/htdocs/install/mysql/tables/llx_bom_bomline.sql b/htdocs/install/mysql/tables/llx_bom_bomline.sql index e7eae15fc15..eae1f6c6662 100644 --- a/htdocs/install/mysql/tables/llx_bom_bomline.sql +++ b/htdocs/install/mysql/tables/llx_bom_bomline.sql @@ -25,6 +25,7 @@ CREATE TABLE llx_bom_bomline( qty_frozen smallint DEFAULT 0, disable_stock_change smallint DEFAULT 0, efficiency double(24,8) NOT NULL DEFAULT 1, + fk_unit integer NULL, position integer NOT NULL DEFAULT 0 -- END MODULEBUILDER FIELDS ) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_establishment.sql b/htdocs/install/mysql/tables/llx_establishment.sql index 7159a53059c..1b0d2668cb0 100644 --- a/htdocs/install/mysql/tables/llx_establishment.sql +++ b/htdocs/install/mysql/tables/llx_establishment.sql @@ -22,6 +22,7 @@ CREATE TABLE llx_establishment ( rowid integer NOT NULL auto_increment PRIMARY KEY, entity integer NOT NULL DEFAULT 1, + label varchar(255) NOT NULL, ref varchar(30), name varchar(128), address varchar(255), diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index a234ae8ddb1..266b561f466 100644 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -108,4 +108,5 @@ create table llx_product mandatory_period tinyint DEFAULT 0, -- is used to signal to the user that the start and end dates are mandatory for this type of product the fk_product_type == 1 (service) (non-blocking action) fk_default_bom integer DEFAULT NULL + fk_default_workstation integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 598045dd7eb..8d8fe6268ff 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2314,3 +2314,5 @@ CIDLookupURL=The module brings an URL that can be used by an external tool to ge ScriptIsEmpty=The script is empty ShowHideTheNRequests=Show/hide the %s SQL request(s) DefinedAPathForAntivirusCommandIntoSetup=Define a path for an antivirus program into %s +TriggerCodes=Triggerable events +TriggerCodeInfo=Enter here the trigger code(s) that must generate a post of a web request (only external URL are allowed). You can enter several trigger codes separated by a comma. diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index e4ca610c44f..aebe3affdae 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -15,6 +15,7 @@ ErrorMemberIsAlreadyLinkedToThisThirdParty=Another member (name: %s, logi ErrorUserPermissionAllowsToLinksToItselfOnly=For security reasons, you must be granted permissions to edit all users to be able to link a member to a user that is not yours. SetLinkToUser=Link to a Dolibarr user SetLinkToThirdParty=Link to a Dolibarr third party +MemberCountersArePublic=Counters of valid members are public MembersCards=Generation of cards for members MembersList=List of members MembersListToValid=List of draft members (to be validated) diff --git a/htdocs/langs/fr_FR/mrp.lang b/htdocs/langs/fr_FR/mrp.lang index 709ff68b963..2a905a76530 100644 --- a/htdocs/langs/fr_FR/mrp.lang +++ b/htdocs/langs/fr_FR/mrp.lang @@ -82,6 +82,9 @@ ProductsToProduce=Produits à produire UnitCost=Coût unitaire TotalCost=Coût total BOMTotalCost=Le coût de production de cette nomenclature basé sur chaque quantité et produit à consommer (utilise le prix de revient si défini, sinon le PMP si défini, sinon le meilleur prix d'achat) +BOMTotalCostService=Si le module "Poste de travail" est activé, alors le calcul est "quantité (convertie en heures) x thm du poste de travail", sinon "quantité (convertie en heures) x prix de revient du service" +BOMProductsList=Liste des composants +BOMServicesList=Liste des services GoOnTabProductionToProduceFirst=Vous devez avoir la production pour clôturer un Ordre de Fabrication (voir onglet '%s'). Mais vous pouvez l'annuler. ErrorAVirtualProductCantBeUsedIntoABomOrMo=Un kit ne peut pas être utilisé dans une Nomenclature ou un Ordre de fabrication. Workstation=Poste de travail @@ -91,6 +94,7 @@ WorkstationSetup = Configuration du module Poste de travail WorkstationSetupPage = Configuration du module Poste de travail WorkstationList=Liste des postes de travail WorkstationCreate=Ajouter un nouveau poste de travail +DefaultWorkstation=Poste de travail par défaut ConfirmEnableWorkstation=Voulez-vous vraiment activer le poste de travail %s? EnableAWorkstation=Activer le module Poste de travail ConfirmDisableWorkstation=Voulez-vous vraiment désactiver la station de travail %s? diff --git a/htdocs/margin/index.php b/htdocs/margin/index.php index 8363cd331c4..79595d5a8ee 100644 --- a/htdocs/margin/index.php +++ b/htdocs/margin/index.php @@ -27,7 +27,7 @@ require '../main.inc.php'; if ($user->rights->produit->lire) { $page = 'productMargins'; -} elseif ($user->rights->societe->lire) { +} elseif ($user->hasRight('societe', 'lire')) { $page = 'customerMargins'; } else { $page = 'agentMargins'; diff --git a/htdocs/margin/lib/margins.lib.php b/htdocs/margin/lib/margins.lib.php index 802541b98ca..10e449026fa 100644 --- a/htdocs/margin/lib/margins.lib.php +++ b/htdocs/margin/lib/margins.lib.php @@ -71,7 +71,7 @@ function marges_prepare_head() $h++; } - if ($user->rights->societe->lire) { + if ($user->hasRight('societe', 'lire')) { $head[$h][0] = DOL_URL_ROOT."/margin/customerMargins.php"; $head[$h][1] = $langs->trans("CustomerMargins"); $head[$h][2] = 'customerMargins'; diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 973eb6ba915..169d764b80b 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -71,7 +71,7 @@ class modMyModule extends DolibarrModules $this->editor_name = 'Editor name'; $this->editor_url = 'https://www.example.com'; - // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' + // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z' $this->version = '1.0'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 86a5635e9de..5d1613b05f2 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -55,6 +55,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php' require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; if (isModEnabled('propal')) { require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; @@ -558,6 +559,7 @@ if (empty($reshook)) { $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->fk_default_warehouse = GETPOST('fk_default_warehouse'); + $object->fk_default_workstation = GETPOST('fk_default_workstation'); $object->seuil_stock_alerte = GETPOST('seuil_stock_alerte') ?GETPOST('seuil_stock_alerte') : 0; $object->desiredstock = GETPOST('desiredstock') ?GETPOST('desiredstock') : 0; $object->canvas = GETPOST('canvas'); @@ -723,6 +725,7 @@ if (empty($reshook)) { $object->status_batch = GETPOST('status_batch', 'aZ09'); $object->batch_mask = GETPOST('batch_mask', 'alpha'); $object->fk_default_warehouse = GETPOST('fk_default_warehouse'); + $object->fk_default_workstation = GETPOST('fk_default_workstation'); // removed from update view so GETPOST always empty /* $object->seuil_stock_alerte = GETPOST('seuil_stock_alerte'); @@ -1441,7 +1444,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Description (used in invoice, propal...) print ''; + } + // Duration if ($type == 1) { print ''; */ } + + if ($object->isService() && $conf->workstation->enabled) { + // Default workstation + print ''; + } + /* else { @@ -2505,6 +2524,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } + if ($object->isService() && $conf->workstation->enabled) { + $workstation = new Workstation($db); + $res = $workstation->fetch($object->fk_default_workstation); + + print ''; + } + // Parent product. if (!empty($conf->variants->enabled) && ($object->isProduct() || $object->isService())) { $combination = new ProductCombination($db); diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index 4ede9e1e297..a21ff6348e6 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -42,6 +42,7 @@ class FormProduct // Cache arrays public $cache_warehouses = array(); public $cache_lot = array(); + public $cache_workstations = array(); /** @@ -172,6 +173,63 @@ class FormProduct } } + /** + * Load in cache array list of workstations + * If fk_product is not 0, we do not use cache + * + * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. + * @param array $exclude warehouses ids to exclude + * @param string $orderBy [='e.ref'] Order by + * @return int Nb of loaded lines, 0 if already loaded, <0 if KO + * @throws Exception + */ + public function loadWorkstations($fk_product = 0, $exclude = array(), $orderBy = 'w.ref') + { + global $conf, $langs; + + if (empty($fk_product) && count($this->cache_workstations)) { + return 0; // Cache already loaded and we do not want a list with information specific to a product + } + + $sql = "SELECT w.rowid, w.ref as ref, w.label as label, w.type, w.nb_operators_required,w.thm_operator_estimated,w.thm_machine_estimated"; + $sql .= " FROM ".$this->db->prefix()."workstation_workstation as w"; + $sql .= " WHERE 1 = 1"; + if (!empty($fk_product) && $fk_product > 0) { + $sql .= " AND w.fk_product = ".((int) $fk_product); + } + $sql .= " AND w.entity IN (".getEntity('workstation').")"; + + if (is_array($exclude) && !empty($exclude)) { + $sql .= ' AND w.rowid NOT IN('.$this->db->sanitize(implode(',', $exclude)).')'; + } + + $sql .= " ORDER BY ".$orderBy; + + dol_syslog(get_class($this).'::loadWorkstations', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $this->db->fetch_object($resql); + + $this->cache_workstations[$obj->rowid]['id'] = $obj->rowid; + $this->cache_workstations[$obj->rowid]['ref'] = $obj->ref; + $this->cache_workstations[$obj->rowid]['label'] = $obj->label; + $this->cache_workstations[$obj->rowid]['type'] = $obj->type; + $this->cache_workstations[$obj->rowid]['nb_operators_required'] = $obj->nb_operators_required; + $this->cache_workstations[$obj->rowid]['thm_operator_estimated'] = $obj->thm_operator_estimated; + $this->cache_workstations[$obj->rowid]['thm_machine_estimated'] = $obj->thm_machine_estimated; + $i++; + } + + return $num; + } else { + dol_print_error($this->db); + return -1; + } + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return full path to current warehouse in $tab (recursive function) @@ -320,6 +378,104 @@ class FormProduct return $out; } + /** + * Return list of workstations + * + * @param string|int $selected Id of preselected warehouse ('' or '-1' for no value, 'ifone' and 'ifonenodefault' = select value if one value otherwise no value, '-2' to use the default value from setup) + * @param string $htmlname Name of html select html + * @param int $empty 1=Can be empty, 0 if not + * @param int $disabled 1=Select is disabled + * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. + * @param string $empty_label Empty label if needed (only if $empty=1) + * @param int $forcecombo 1=Force combo iso ajax select2 + * @param array $events Events to add to select2 + * @param string $morecss Add more css classes to HTML select + * @param array $exclude Warehouses ids to exclude + * @param int $showfullpath 1=Show full path of name (parent ref into label), 0=Show only ref of current warehouse + * @param string $orderBy [='e.ref'] Order by + * @return string HTML select + * + * @throws Exception + */ + public function selectWorkstations($selected = '', $htmlname = 'idworkstations', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label = '', $forcecombo = 0, $events = array(), $morecss = 'minwidth200', $exclude = array(), $showfullpath = 1, $orderBy = 'e.ref') + { + global $conf, $langs, $user, $hookmanager; + + dol_syslog(get_class($this)."::selectWorkstations $selected, $htmlname, $empty, $disabled, $fk_product, $empty_label, $forcecombo, $morecss", LOG_DEBUG); + + $out = ''; + if (!empty($fk_product) && $fk_product > 0) { + $this->cache_workstations = array(); + } + + $this->loadWorkstations($fk_product); + $nbofworkstations = count($this->cache_workstations); + + if ($conf->use_javascript_ajax && !$forcecombo) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + $comboenhancement = ajax_combobox($htmlname, $events); + $out .= $comboenhancement; + } + + if (strpos($htmlname, 'search_') !== 0) { + if (empty($user->fk_workstation) || $user->fk_workstation == -1) { + if (($selected == '-2' || $selected == 'ifone') && !empty($conf->global->MAIN_DEFAULT_WORKSTATION)) { + $selected = $conf->global->MAIN_DEFAULT_WORKSTATION; + } + } else { + if (($selected == '-2' || $selected == 'ifone') && !empty($conf->global->MAIN_DEFAULT_WORKSTATION)) { + $selected = $user->fk_workstation; + } + } + } + + $out .= ''; // Price - print ''; // Price minimum - print ''; // Price by quantity diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index d0f27eb46f4..a71098fc2bf 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -57,6 +57,19 @@ class StockTransfer extends CommonObject */ public $isextrafieldmanaged = 1; + /** + * @var string Customer ref + * @deprecated + * @see $ref_customer + */ + public $ref_client; + + /** + * @var string Customer ref + */ + public $ref_customer; + + /** * @var string String with name of icon for stocktransfer. Must be the part after the 'object_' into object_stocktransfer.png */ @@ -140,6 +153,7 @@ class StockTransfer extends CommonObject public $note_private; public $date_creation; public $tms; + public $lead_time_for_warning; public $fk_user_creat; public $fk_user_modif; public $import_key; diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index a5d49dcc3a7..14febad09d4 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -232,7 +232,6 @@ class StockTransferLine extends CommonObjectLine // Reset some properties unset($object->id); - unset($object->fk_user_creat); unset($object->import_key); diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php index 0a1ebc0600e..051506d54ac 100644 --- a/htdocs/public/members/new.php +++ b/htdocs/public/members/new.php @@ -770,10 +770,14 @@ if (!empty($conf->global->MEMBER_SKIP_TABLE) || !empty($conf->global->MEMBER_NEW foreach ($measuringUnits->records as $lines) $units[$lines->short_label] = $langs->trans(ucfirst($lines->label)); - $sql = "SELECT d.rowid, d.libelle as label, d.subscription, d.amount, d.caneditamount, d.vote, d.note, d.duration, d.statut as status, d.morphy"; + $publiccounters = $conf->global->MEMBER_COUNTERS_ARE_PUBLIC; + + $sql = "SELECT d.rowid, d.libelle as label, d.subscription, d.amount, d.caneditamount, d.vote, d.note, d.duration, d.statut as status, d.morphy, COUNT(a.rowid) AS membercount"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent as a"; + $sql .= " ON d.rowid = a.fk_adherent_type AND a.statut>0"; $sql .= " WHERE d.entity IN (".getEntity('member_type').")"; - $sql .= " AND d.statut=1"; + $sql .= " AND d.statut=1 GROUP BY d.rowid"; $result = $db->query($sql); if ($result) { @@ -789,6 +793,7 @@ if (!empty($conf->global->MEMBER_SKIP_TABLE) || !empty($conf->global->MEMBER_NEW print ''; print ''; print ''; + if ($publiccounters) print ''; print ''; print "\n"; @@ -828,6 +833,8 @@ if (!empty($conf->global->MEMBER_SKIP_TABLE) || !empty($conf->global->MEMBER_NEW } print ''; print ''; + $membercount = $objp->membercount>0? $objp->membercount: "–"; + if ($publiccounters) print ''; print ''; print ""; $i++; diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 2e5033b5a55..f1ce166cf81 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -396,7 +396,7 @@ if (empty($reshook)) { } include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', 'tic'.$object->id, '', 'ticket'); - if ($mailfile->error || $mailfile->errors) { + if ($mailfile->error || !empty($mailfile->errors)) { setEventMessages($mailfile->error, $mailfile->errors, 'errors'); } else { $result = $mailfile->sendfile(); diff --git a/htdocs/societe/canvas/company/tpl/card_view.tpl.php b/htdocs/societe/canvas/company/tpl/card_view.tpl.php index d1ba18f82fd..fb9a38ed442 100644 --- a/htdocs/societe/canvas/company/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_view.tpl.php @@ -263,7 +263,7 @@ for ($i = 1; $i <= 4; $i++) { ">trans("Modify"); ?> -rights->societe->supprimer) { ?> +hasRight('societe', 'supprimer')) { ?> use_javascript_ajax) { ?> trans('Delete'); ?> @@ -283,7 +283,7 @@ for ($i = 1; $i <= 4; $i++) { */ $filedir = $conf->societe->multidir_output[$this->control->tpl['entity']].'/'.$socid; $urlsource = $_SERVER["PHP_SELF"]."?socid=".$socid; -$genallowed = $user->rights->societe->lire; +$genallowed = $user->hasRight('societe', 'lire'); $delallowed = $user->rights->societe->creer; print $formfile->showdocuments('company', $socid, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $objcanvas->control->object->default_lang); diff --git a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php index 98979c917d4..369ef413fc1 100644 --- a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php @@ -190,7 +190,7 @@ if ($this->control->tpl['action_delete']) { ">trans("Modify"); ?> -rights->societe->supprimer) { ?> +hasRight('societe', 'supprimer')) { ?> use_javascript_ajax) { ?> trans('Delete'); ?> @@ -209,7 +209,7 @@ if ($this->control->tpl['action_delete']) { */ $filedir = $conf->societe->multidir_output[$this->control->tpl['entity']].'/'.$socid; $urlsource = $_SERVER["PHP_SELF"]."?socid=".$socid; -$genallowed = $user->rights->societe->lire; +$genallowed = $user->hasRight('societe', 'lire'); $delallowed = $user->rights->societe->creer; print $formfile->showdocuments('company', $socid, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $objcanvas->control->object->default_lang); diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index bdc48872c03..4b612df0c00 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -137,9 +137,9 @@ if (!empty($canvas)) { } // Permissions -$permissiontoread = $user->rights->societe->lire; +$permissiontoread = $user->hasRight('societe', 'lire'); $permissiontoadd = $user->rights->societe->creer; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php -$permissiontodelete = $user->rights->societe->supprimer || ($permissiontoadd && isset($object->status) && $object->status == 0); +$permissiontodelete = $user->hasRight('societe', 'supprimer') || ($permissiontoadd && isset($object->status) && $object->status == 0); $permissionnote = $user->rights->societe->creer; // Used by the include of actions_setnotes.inc.php $permissiondellink = $user->rights->societe->creer; // Used by the include of actions_dellink.inc.php $upload_dir = $conf->societe->multidir_output[isset($object->entity) ? $object->entity : 1]; @@ -914,7 +914,7 @@ if (empty($reshook)) { } // Delete third party - if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->societe->supprimer) { + if ($action == 'confirm_delete' && $confirm == 'yes' && $user->hasRight('societe', 'supprimer')) { $object->fetch($socid); $object->oldcopy = clone $object; $result = $object->delete($socid, $user); @@ -3247,7 +3247,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print dolGetButtonAction($langs->trans('MergeThirdparties'), $langs->trans('Merge'), 'danger', $_SERVER["PHP_SELF"].'?socid='.$object->id.'&action=merge&token='.newToken(), '', $permissiontodelete); - if ($user->rights->societe->supprimer) { + if ($user->hasRight('societe', 'supprimer')) { $deleteUrl = $_SERVER["PHP_SELF"].'?socid='.$object->id.'&action=delete&token='.newToken(); $buttonId = 'action-delete-no-ajax'; if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile)) { // We can't use preloaded confirm form with jmobile @@ -3277,7 +3277,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { */ $filedir = $conf->societe->multidir_output[$object->entity].'/'.$object->id; $urlsource = $_SERVER["PHP_SELF"]."?socid=".$object->id; - $genallowed = $user->rights->societe->lire; + $genallowed = $user->hasRight('societe', 'lire'); $delallowed = $user->rights->societe->creer; print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index f197a1b7024..7fe72779c6c 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -132,7 +132,7 @@ class Thirdparties extends DolibarrApi { $obj_ret = array(); - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } @@ -527,7 +527,7 @@ class Thirdparties extends DolibarrApi */ public function delete($id) { - if (!DolibarrApiAccess::$user->rights->societe->supprimer) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'supprimer')) { throw new RestException(401); } $result = $this->company->fetch($id); @@ -848,7 +848,7 @@ class Thirdparties extends DolibarrApi */ public function getOutStandingProposals($id, $mode = 'customer') { - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } @@ -890,7 +890,7 @@ class Thirdparties extends DolibarrApi */ public function getOutStandingOrder($id, $mode = 'customer') { - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } @@ -931,7 +931,7 @@ class Thirdparties extends DolibarrApi */ public function getOutStandingInvoices($id, $mode = 'customer') { - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } @@ -972,7 +972,7 @@ class Thirdparties extends DolibarrApi */ public function getSalesRepresentatives($id, $mode = 0) { - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } @@ -1015,7 +1015,7 @@ class Thirdparties extends DolibarrApi { $obj_ret = array(); - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } @@ -1439,7 +1439,7 @@ class Thirdparties extends DolibarrApi */ public function getSocieteAccounts($id, $site = null) { - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } @@ -1870,7 +1870,7 @@ class Thirdparties extends DolibarrApi { global $conf; - if (!DolibarrApiAccess::$user->rights->societe->lire) { + if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on thirdparties.'); } diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php index 1d0bdfe39a1..e161cd8668c 100644 --- a/htdocs/societe/index.php +++ b/htdocs/societe/index.php @@ -124,10 +124,10 @@ $result = $db->query($sql); if ($result) { while ($objp = $db->fetch_object($result)) { $found = 0; - if (isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS) && ($objp->client == 2 || $objp->client == 3)) { + if (isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS) && ($objp->client == 2 || $objp->client == 3)) { $found = 1; $third['prospect']++; } - if (isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS) && ($objp->client == 1 || $objp->client == 3)) { + if (isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS) && ($objp->client == 1 || $objp->client == 3)) { $found = 1; $third['customer']++; } if (((isModEnabled('fournisseur') && $user->rights->fournisseur->facture->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || (isModEnabled('supplier_order') && $user->rights->supplier_order->lire) || (isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS) && $objp->fournisseur) { @@ -150,10 +150,10 @@ $thirdpartygraph .= ''."\n"; } else { - if (isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS)) { + if (isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS)) { $statstring = ""; $statstring .= ''; $statstring .= ""; } - if (isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS)) { + if (isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS)) { $statstring .= ""; $statstring .= ''; $statstring .= ""; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index ff6de888284..680ab8aff82 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -383,8 +383,8 @@ if (empty($reshook)) { // Mass actions $objectclass = 'Societe'; $objectlabel = 'ThirdParty'; - $permissiontoread = $user->rights->societe->lire; - $permissiontodelete = $user->rights->societe->supprimer; + $permissiontoread = $user->hasRight('societe', 'lire'); + $permissiontodelete = $user->hasRight('societe', 'supprimer'); $permissiontoadd = $user->rights->societe->creer; $uploaddir = $conf->societe->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; @@ -898,7 +898,7 @@ if ($user->rights->societe->creer) { if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete', 'preaffecttag', 'preenable', 'preclose'))) { $arrayofmassactions = array(); } -if ($user->rights->societe->supprimer) { +if ($user->hasRight('societe', 'supprimer')) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 30b19e59d8b..fe5654a0d06 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -79,7 +79,7 @@ $extrafields->fetch_name_optionals_label($object->table_element); $hookmanager->initHooks(array('thirdpartybancard', 'globalcard')); // Permissions -$permissiontoread = $user->rights->societe->lire; +$permissiontoread = $user->hasRight('societe', 'lire'); $permissiontoadd = $user->rights->societe->creer; // Used by the include of actions_addupdatedelete.inc.php and actions_builddoc.inc.php $permissiontoaddupdatepaymentinformation = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $permissiontoadd) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->societe->thirdparty_paymentinformation_advance->write))); diff --git a/htdocs/societe/website.php b/htdocs/societe/website.php index 8de63dfeffc..9ca58ab0bf4 100644 --- a/htdocs/societe/website.php +++ b/htdocs/societe/website.php @@ -161,8 +161,8 @@ if (empty($reshook)) { // Mass actions $objectclass = 'WebsiteAccount'; $objectlabel = 'WebsiteAccount'; - $permissiontoread = $user->rights->societe->lire; - $permissiontodelete = $user->rights->societe->supprimer; + $permissiontoread = $user->hasRight('societe', 'lire'); + $permissiontodelete = $user->hasRight('societe', 'supprimer'); $uploaddir = $conf->societe->multidir_output[$object->entity]; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -250,7 +250,7 @@ print dol_get_fiche_end(); $newcardbutton = ''; if (isModEnabled('website')) { - if (!empty($user->rights->societe->lire)) { + if ($user->hasRight('societe', 'lire')) { $newcardbutton .= dolGetButtonTitle($langs->trans("AddWebsiteAccount"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/website/websiteaccount_card.php?action=create&fk_soc='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id)); } else { $newcardbutton .= dolGetButtonTitle($langs->trans("AddAction"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/website/websiteaccount_card.php?action=create&fk_soc='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', 0); diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 680516d80dd..44c93873103 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -1656,7 +1656,7 @@ class Ticket extends CommonObject $sendtocc = ''; $deliveryreceipt = 0; $mailfile = new CMailFile($subject, $info_sendto['email'], $from, $tmpmessage, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, 0); - if ($mailfile->error || $mailfile->errors) { + if ($mailfile->error || !empty($mailfile->errors)) { setEventMessages($mailfile->error, $mailfile->errors, 'errors'); } else { $result = $mailfile->sendfile(); diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 80656681015..0551532b00f 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -491,7 +491,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); -if ($socid && !$projectid && !$project_ref && $user->rights->societe->lire) { +if ($socid && !$projectid && !$project_ref && $user->hasRight('societe', 'lire')) { $socstat = new Societe($db); $res = $socstat->fetch($socid); if ($res > 0) {
'.$langs->trans('Qty').''; - print ''; - print $langs->trans('Unit'); - print ''; + print ''; + print $langs->trans('Unit'); + print '' . $form->textwithpicto($langs->trans('QtyFrozen'), $langs->trans("QuantityConsumedInvariable")) . '' . $form->textwithpicto($langs->trans('DisableStockChange'), $langs->trans('DisableStockChangeHelp')) . '' . $form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('ValueOfMeansLoss')) . '' . $form->textwithpicto($langs->trans('Unit'), '').'' . $form->textwithpicto($langs->trans('Workstation'), '') . '' . $form->textwithpicto($langs->trans('TotalCost'), '') . ''.$form->textwithpicto($langs->trans('QtyFrozen'), $langs->trans("QuantityConsumedInvariable")).''.$form->textwithpicto($langs->trans('DisableStockChange'), $langs->trans('DisableStockChangeHelp')).''.$form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('ValueOfMeansLoss')).'  
'; // Predefined product/service if (isModEnabled("product") || isModEnabled("service")) { - if (!empty($conf->global->BOM_SUB_BOM)) { + if ($filtertype == 1) { + print $langs->trans("Service"); + } elseif (!empty($conf->global->BOM_SUB_BOM)) { print $langs->trans("Product"); } echo ''; - $filtertype = 0; - if (!empty($object->element) && $object->element == 'contrat' && empty($conf->global->STOCK_SUPPORT_SERVICES)) { - $filtertype = -1; - } $statustoshow = -1; if (!empty($conf->global->ENTREPOT_EXTRA_STATUS)) { // hide products in closed warehouse, but show products for internal transfer - $form->select_produits(GETPOST('idprod', 'int'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array')); + $form->select_produits(GETPOST('idprod', 'int'), (($filtertype == 1) ? 'idprodservice' : 'idprod'), $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array')); } else { - $form->select_produits(GETPOST('idprod', 'int'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array')); + $form->select_produits(GETPOST('idprod', 'int'), (($filtertype == 1) ? 'idprodservice' : 'idprod'), $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array')); } echo ''; } -if (!empty($conf->global->BOM_SUB_BOM)) { +if (!empty($conf->global->BOM_SUB_BOM) && $filtertype!=1) { print '
'.$langs->trans("or").'
'.$langs->trans("BOM"); // TODO Add component to select a BOM $form->select_bom(); @@ -118,35 +133,57 @@ $coldisplay++; print '
'; print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ' '; + print ''; + print $formproduct->selectMeasuringUnits("fk_unit", "time", $fk_unit_default, 0, 0); + print ''; + print ' '; + print ''; + print ' '; print ''; -print ''; + print ''; + print '
'; -print ''; -print ''; -print ''; -print ' '; -print ''; -print ''; -print '
'; + print ''; + print 'qty_frozen ? ' checked="checked"' : '')) . '>'; + print 'disable_stock_change ? ' checked="checked"' : '')) . '">'; + print ''; + print ''; + print ''; + print $formproduct->selectMeasuringUnits("fk_unit", "time", ($line->fk_unit) ? $line->fk_unit : '', 0, 0); + print ''; + print ''; print 'qty_frozen ? ' checked="checked"' : '')).'>'; -print 'disable_stock_change ? ' checked="checked"' : '')).'">'; -print ''; -print ''; -print ''; $coldisplay += $colspan; diff --git a/htdocs/bom/tpl/objectline_title.tpl.php b/htdocs/bom/tpl/objectline_title.tpl.php index dff3a38ccd2..f93fb59fe0d 100644 --- a/htdocs/bom/tpl/objectline_title.tpl.php +++ b/htdocs/bom/tpl/objectline_title.tpl.php @@ -38,6 +38,10 @@ if (empty($object) || !is_object($object)) { print "Error, template page can't be called as URL"; exit; } + +global $filtertype; +if (empty($filtertype)) $filtertype = 0; + print "\n"; @@ -53,30 +57,42 @@ if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { // Product or sub-bom print ''.$langs->trans('Description'); -if (!empty($conf->global->BOM_SUB_BOM)) { +if (!empty($conf->global->BOM_SUB_BOM) && $filtertype != 1) { print '   '.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'  '; print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").' '; } print ''.$form->textwithpicto($langs->trans('Qty'), $langs->trans("QtyRequiredIfNoLoss")).''.$form->textwithpicto($langs->trans('Qty'), ($filtertype != 1) ? $langs->trans("QtyRequiredIfNoLoss") : '').''.$langs->trans('Unit').'' . $langs->trans('Unit') . '' . $form->textwithpicto($langs->trans('QtyFrozen'), $langs->trans("QuantityConsumedInvariable")) . '' . $form->textwithpicto($langs->trans('DisableStockChange'), $langs->trans('DisableStockChangeHelp')) . '' . $form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('ValueOfMeansLoss')) . ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).'' . $form->textwithpicto($langs->trans('Unit'), '').'' . $form->textwithpicto($langs->trans('DefaultWorkstation'), '') . ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCostService")).''.$form->textwithpicto($langs->trans('QtyFrozen'), $langs->trans("QuantityConsumedInvariable")).''.$form->textwithpicto($langs->trans('DisableStockChange'), $langs->trans('DisableStockChangeHelp')).''.$form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('ValueOfMeansLoss')).''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''; - $label = $tmpproduct->getLabelOfUnit('long'); - if ($label !== '') { - print $langs->trans($label); +if ($filtertype != 1) { + if (!empty($conf->global->PRODUCT_USE_UNITS)) { + print ''; + $label = $tmpproduct->getLabelOfUnit('long'); + if ($label !== '') { + print $langs->trans($label); + } + print ''; + $coldisplay++; + echo $line->qty_frozen ? yn($line->qty_frozen) : ''; print ''; + $coldisplay++; + echo $line->disable_stock_change ? yn($line->disable_stock_change) : ''; // Yes, it is a quantity, not a price, but we just want the formating role of function price + print ''; + $coldisplay++; + echo $line->efficiency; + print ''; + $coldisplay++; + + if (!empty($line->fk_unit)) { + require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php'; + $unit = new CUnits($this->db); + $unit->fetch($line->fk_unit); + print (isset($unit->label) ? " ".$langs->trans(ucwords($unit->label))." " : ''); + } + + print ''; + $coldisplay++; + if ($res > 0) echo $workstation->getNomUrl(); + print ''; -$coldisplay++; -echo $line->qty_frozen ? yn($line->qty_frozen) : ''; -print ''; -$coldisplay++; -echo $line->disable_stock_change ? yn($line->disable_stock_change) : ''; // Yes, it is a quantity, not a price, but we just want the formating role of function price -print ''; -$coldisplay++; -echo $line->efficiency; -print ''; $coldisplay++; diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index 76381c0d53d..e59ff070aec 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -315,7 +315,7 @@ class Categories extends DolibarrApi throw new RestException(401); } elseif ($type == Categorie::TYPE_CONTACT && !DolibarrApiAccess::$user->rights->contact->lire) { throw new RestException(401); - } elseif ($type == Categorie::TYPE_CUSTOMER && !DolibarrApiAccess::$user->rights->societe->lire) { + } elseif ($type == Categorie::TYPE_CUSTOMER && !DolibarrApiAccess::$user->hasRight('societe', 'lire')) { throw new RestException(401); } elseif ($type == Categorie::TYPE_SUPPLIER && !DolibarrApiAccess::$user->rights->fournisseur->lire) { throw new RestException(401); diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 67df6af0298..1eca4555e91 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -131,7 +131,7 @@ if ($id > 0 && empty($object->id)) { } } if ($object->id > 0) { - if (!($object->client > 0) || empty($user->rights->societe->lire)) { + if (!($object->client > 0) || !$user->hasRight('societe', 'lire')) { accessforbidden(); } } diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index ed6184e0cd4..01f3bba9eff 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -594,7 +594,7 @@ print '
'; /* * Last modified customers or prospects */ -if (isModEnabled("societe") && $user->rights->societe->lire) { +if (isModEnabled("societe") && $user->hasRight('societe', 'lire')) { $sql = "SELECT s.rowid as socid, s.nom as name, s.name_alias"; $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur"; @@ -700,7 +700,7 @@ if (isModEnabled("societe") && $user->rights->societe->lire) { /* * Last suppliers */ -if (((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $user->rights->societe->lire) { +if (((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $user->hasRight('societe', 'lire')) { $sql = "SELECT s.rowid as socid, s.nom as name, s.name_alias"; $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur"; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 301bbe761be..8b0967c64b6 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3662,7 +3662,10 @@ class Commande extends CommonOrder } elseif ($status == self::STATUS_SHIPMENTONPROCESS) { $labelStatus = $langs->transnoentitiesnoconv('StatusOrderSent').$billedtext; $labelStatusShort = $langs->transnoentitiesnoconv('StatusOrderSentShort').$billedtext; - $labelTooltip = $langs->transnoentitiesnoconv("StatusOrderSent").' - '.$langs->transnoentitiesnoconv("DateDeliveryPlanned").dol_print_date($this->date_livraison).$billedtext; + $labelTooltip = $langs->transnoentitiesnoconv("StatusOrderSent"); + if (!empty($this->delivery_date)) { + $labelTooltip .= ' - '.$langs->transnoentitiesnoconv("DateDeliveryPlanned").dol_print_date($this->delivery_date, 'day').$billedtext; + } $statusType = 'status4'; } elseif ($status == self::STATUS_CLOSED && (!$billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) { $labelStatus = $langs->transnoentitiesnoconv('StatusOrderToBill'); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index eea44ab7387..1bcffd9e5f9 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -312,8 +312,8 @@ if (empty($reshook)) { // Mass actions $objectclass = 'Contact'; $objectlabel = 'Contact'; - $permissiontoread = $user->rights->societe->lire; - $permissiontodelete = $user->rights->societe->supprimer; + $permissiontoread = $user->hasRight('societe', 'lire'); + $permissiontodelete = $user->hasRight('societe', 'supprimer'); $permissiontoadd = $user->rights->societe->creer; $uploaddir = $conf->societe->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; @@ -690,7 +690,7 @@ $arrayofmassactions = array( // 'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), ); //if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); -if ($user->rights->societe->supprimer) { +if ($user->hasRight('societe', 'supprimer')) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } if ($user->rights->societe->creer) { diff --git a/htdocs/core/ajax/objectonoff.php b/htdocs/core/ajax/objectonoff.php index c66a49557d0..77cd3234cd8 100644 --- a/htdocs/core/ajax/objectonoff.php +++ b/htdocs/core/ajax/objectonoff.php @@ -67,7 +67,7 @@ if (!empty($user->socid)) { $socid = $user->socid; } -//$user->rights->societe->lire = 0;$user->rights->fournisseur->lire = 0; +//$user->hasRight('societe', 'lire') = 0;$user->rights->fournisseur->lire = 0; //restrictedArea($user, 'societe', $id); if (in_array($field, array('status'))) { diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php index 364b79932ef..cb934debef3 100644 --- a/htdocs/core/boxes/box_clients.php +++ b/htdocs/core/boxes/box_clients.php @@ -86,7 +86,7 @@ class box_clients extends ModeleBoxes $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedCustomers", $max)); - if ($user->rights->societe->lire) { + if ($user->hasRight('societe', 'lire')) { $sql = "SELECT s.rowid as socid, s.nom as name, s.name_alias"; $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.logo, s.email, s.entity"; diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index f257d7db18d..f051fe5ade3 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -85,7 +85,7 @@ class box_contacts extends ModeleBoxes $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedContacts", $max)); - if ($user->rights->societe->lire && $user->rights->societe->contact->lire) { + if ($user->hasRight('societe', 'lire') && $user->rights->societe->contact->lire) { $sql = "SELECT sp.rowid as id, sp.lastname, sp.firstname, sp.civility as civility_id, sp.datec, sp.tms, sp.fk_soc, sp.statut as status"; $sql .= ", sp.address, sp.zip, sp.town, sp.phone, sp.phone_perso, sp.phone_mobile, sp.email as spemail"; diff --git a/htdocs/core/boxes/box_customers_outstanding_bill_reached.php b/htdocs/core/boxes/box_customers_outstanding_bill_reached.php index 2bf5a2c0693..ec82f1a57e4 100644 --- a/htdocs/core/boxes/box_customers_outstanding_bill_reached.php +++ b/htdocs/core/boxes/box_customers_outstanding_bill_reached.php @@ -86,7 +86,7 @@ class box_customers_outstanding_bill_reached extends ModeleBoxes $this->info_box_head = array('text' => $langs->trans("BoxTitleLastOutstandingBillReached", $max)); - if ($user->rights->societe->lire) { + if ($user->hasRight('societe', 'lire')) { $sql = "SELECT s.rowid as socid, s.nom as name, s.name_alias"; $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.logo, s.email, s.entity"; diff --git a/htdocs/core/boxes/box_dolibarr_state_board.php b/htdocs/core/boxes/box_dolibarr_state_board.php index a60d5c20a93..0f63582370c 100644 --- a/htdocs/core/boxes/box_dolibarr_state_board.php +++ b/htdocs/core/boxes/box_dolibarr_state_board.php @@ -114,8 +114,8 @@ class box_dolibarr_state_board extends ModeleBoxes $conditions = array( 'users' => $user->hasRight('user', 'user', 'lire'), 'members' => isModEnabled('adherent') && $user->rights->adherent->lire, - 'customers' => isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS), - 'prospects' => isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS), + 'customers' => isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS), + 'prospects' => isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS), 'suppliers' => ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->lire) || (isModEnabled("supplier_order") && $user->rights->supplier_order->lire) || (isModEnabled("supplier_invoice") && $user->rights->supplier_invoice->lire) diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php index 59280aeec62..1c14ac0be4f 100644 --- a/htdocs/core/boxes/box_fournisseurs.php +++ b/htdocs/core/boxes/box_fournisseurs.php @@ -81,7 +81,7 @@ class box_fournisseurs extends ModeleBoxes $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedSuppliers", $max)); - if ($user->rights->societe->lire) { + if ($user->hasRight('societe', 'lire')) { $sql = "SELECT s.rowid as socid, s.nom as name, s.name_alias"; $sql .= ", s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur"; $sql .= ", s.logo, s.email, s.entity"; diff --git a/htdocs/core/boxes/box_goodcustomers.php b/htdocs/core/boxes/box_goodcustomers.php index 3341e08107d..90ffc82a5d8 100644 --- a/htdocs/core/boxes/box_goodcustomers.php +++ b/htdocs/core/boxes/box_goodcustomers.php @@ -69,7 +69,7 @@ class box_goodcustomers extends ModeleBoxes $this->enabled = 0; // not enabled by default. Very slow on large database } - $this->hidden = empty($user->rights->societe->lire); + $this->hidden = !$user->hasRight('societe', 'lire'); } /** @@ -90,7 +90,7 @@ class box_goodcustomers extends ModeleBoxes $this->info_box_head = array('text' => $langs->trans("BoxTitleGoodCustomers", $max)); - if ($user->rights->societe->lire) { + if ($user->hasRight('societe', 'lire')) { $sql = "SELECT s.rowid, s.nom as name, s.logo, s.code_client, s.code_fournisseur, s.client, s.fournisseur, s.tms as datem, s.status as status,"; $sql .= " count(*) as nbfact, sum(".$this->db->ifsql('f.paye=1', '1', '0').") as nbfactpaye"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as f"; diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php index 205cf09419c..69e8432a879 100644 --- a/htdocs/core/boxes/box_prospect.php +++ b/htdocs/core/boxes/box_prospect.php @@ -86,7 +86,7 @@ class box_prospect extends ModeleBoxes $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedProspects", $max)); - if ($user->rights->societe->lire) { + if ($user->hasRight('societe', 'lire')) { $sql = "SELECT s.rowid as socid, s.nom as name, s.name_alias"; $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.logo, s.email, s.entity"; diff --git a/htdocs/core/class/cunits.class.php b/htdocs/core/class/cunits.class.php index dfc22fd37ec..102bbbda652 100644 --- a/htdocs/core/class/cunits.class.php +++ b/htdocs/core/class/cunits.class.php @@ -420,15 +420,16 @@ class CUnits // extends CommonObject * Get unit from code * @param string $code code of unit * @param string $mode 0= id , short_label=Use short label as value, code=use code + * @param string $unit_type weight,size,surface,volume,qty,time... * @return int <0 if KO, Id of code if OK */ - public function getUnitFromCode($code, $mode = 'code') + public function getUnitFromCode($code, $mode = 'code', $unit_type = '') { if ($mode == 'short_label') { - return dol_getIdFromCode($this->db, $code, 'c_units', 'short_label', 'rowid'); + return dol_getIdFromCode($this->db, $code, 'c_units', 'short_label', 'rowid', 0, ' AND unit_type = "'.$this->db->escape($unit_type).'"'); } elseif ($mode == 'code') { - return dol_getIdFromCode($this->db, $code, 'c_units', 'code', 'rowid'); + return dol_getIdFromCode($this->db, $code, 'c_units', 'code', 'rowid', 0, ' AND unit_type = "'. $this->db->escape($unit_type) .'"'); } return $code; diff --git a/htdocs/core/class/html.formcontract.class.php b/htdocs/core/class/html.formcontract.class.php index 6267c6ff390..c763bc1a04e 100644 --- a/htdocs/core/class/html.formcontract.class.php +++ b/htdocs/core/class/html.formcontract.class.php @@ -104,7 +104,7 @@ class FormContract while ($i < $num) { $obj = $this->db->fetch_object($resql); // If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project. - if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && empty($user->rights->societe->lire)) { + if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && !$user->hasRight('societe', 'lire')) { // Do nothing } else { $labeltoshow = dol_trunc($obj->ref, 18); diff --git a/htdocs/core/class/html.formintervention.class.php b/htdocs/core/class/html.formintervention.class.php index 107e9ba378a..751e77eafe1 100644 --- a/htdocs/core/class/html.formintervention.class.php +++ b/htdocs/core/class/html.formintervention.class.php @@ -99,7 +99,7 @@ class FormIntervention while ($i < $num) { $obj = $this->db->fetch_object($resql); // If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project. - if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && empty($user->rights->societe->lire)) { + if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && !$user->hasRight('societe', 'lire')) { // Do nothing } else { $labeltoshow = dol_trunc($obj->ref, 18); diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 4d34211ed17..d4c3b1aa21f 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -206,7 +206,7 @@ class FormProjets while ($i < $num) { $obj = $this->db->fetch_object($resql); // If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project. - if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && empty($user->rights->societe->lire)) { + if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && !$user->hasRight('societe', 'lire')) { // Do nothing } else { if ($discard_closed == 1 && $obj->fk_statut == 2 && $obj->rowid != $selected) { // We discard closed except if selected diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 96bd34143c7..cb5a7f41f8f 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -104,7 +104,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh } } - if (isModEnabled('societe') && !empty($user->rights->societe->lire)) { + if (isModEnabled('societe') && $user->hasRight('societe', 'lire')) { print '
'; print img_picto($langs->trans("ThirdParty"), 'company', 'class="pictofixedwidth inline-block"'); print $form->select_company($socid, 'search_socid', '', ' ', 0, 0, null, 0, 'minwidth100 maxwidth500'); diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 9cadb431ec5..b4ae935677b 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -242,7 +242,7 @@ function societe_prepare_head(Societe $object) $h++; } - if (isModEnabled('website') && (!empty($conf->global->WEBSITE_USE_WEBSITE_ACCOUNTS)) && (!empty($user->rights->societe->lire))) { + if (isModEnabled('website') && (!empty($conf->global->WEBSITE_USE_WEBSITE_ACCOUNTS)) && ($user->hasRight('societe', 'lire'))) { $head[$h][0] = DOL_URL_ROOT.'/societe/website.php?id='.urlencode($object->id); $head[$h][1] = $langs->trans("WebSiteAccounts"); $nbNote = 0; diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index f8d11b4bc82..d2383a14dfc 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -319,6 +319,27 @@ function convertSecondToTime($iSecond, $format = 'all', $lengthOfDay = 86400, $l } +/** Convert duration to hour + * + * @param int $duration_value Duration value + * @param int $duration_unit Duration unit + * @return int $result + */ +function convertDurationtoHour($duration_value, $duration_unit) +{ + $result = 0; + + if ($duration_unit == 's') $result = $duration_value / 3600; + if ($duration_unit == 'i') $result = $duration_value / 60; + if ($duration_unit == 'h') $result = $duration_value; + if ($duration_unit == 'd') $result = $duration_value * 24; + if ($duration_unit == 'w') $result = $duration_value * 24 * 7; + if ($duration_unit == 'm') $result = $duration_value * 730.484; + if ($duration_unit == 'y') $result = $duration_value * 365 * 24; + + return $result; +} + /** * Generate a SQL string to make a filter into a range (for second of date until last second of date). * This method allows to maje SQL request that will deal correctly the timezone of server. diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7b3aa47af17..a3c538954dc 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8543,10 +8543,11 @@ function dol_osencode($str) * @param string $fieldkey Field to search the key into * @param string $fieldid Field to get * @param int $entityfilter Filter by entity + * @param string $filters Filter on other fields * @return int <0 if KO, Id of code if OK * @see $langs->getLabelFromKey */ -function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = 'id', $entityfilter = 0) +function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = 'id', $entityfilter = 0, $filters = '') { global $cache_codes; @@ -8568,6 +8569,9 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = if (!empty($entityfilter)) { $sql .= " AND entity IN (".getEntity($tablename).")"; } + if ($filters) { + $sql .= $filters; + } $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index ce6f9b38320..1c0d7d1aab1 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -421,7 +421,7 @@ function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = ' } if ($feature == 'societe') { - if (empty($user->rights->societe->lire) && empty($user->rights->fournisseur->lire)) { + if (!$user->hasRight('societe', 'lire') && empty($user->rights->fournisseur->lire)) { $readok = 0; $nbko++; } @@ -831,7 +831,7 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl if ($user->socid != $objectid) { return false; } - } elseif (isModEnabled("societe") && ($user->rights->societe->lire && empty($user->rights->societe->client->voir))) { + } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && empty($user->rights->societe->client->voir))) { // If internal user: Check permission for internal users that are restricted on their objects $sql = "SELECT COUNT(sc.fk_soc) as nb"; $sql .= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -857,7 +857,7 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")"; $sql .= " AND dbt.fk_soc = ".((int) $user->socid); - } elseif (isModEnabled("societe") && ($user->rights->societe->lire && empty($user->rights->societe->client->voir))) { + } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && empty($user->rights->societe->client->voir))) { // If internal user: Check permission for internal users that are restricted on their objects $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 6d7c5bf82fd..6b2c02de197 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -876,11 +876,12 @@ class ImportXlsx extends ModeleImports if (!empty($updatekeys)) { // We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields) + $where = array(); + if (empty($lastinsertid)) { // No insert done yet for a parent table $sqlSelect = "SELECT ".$fname." FROM " . $tablename; $data = array_combine($listfields, $listvalues); - $where = array(); $filters = array(); foreach ($updatekeys as $key) { $col = $objimport->array_import_updatekeys[0][$key]; @@ -929,6 +930,7 @@ class ImportXlsx extends ModeleImports // Note: For extrafield tablename, we have in importfieldshidden_array an enty 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object' $sqlSelect = "SELECT rowid FROM " . $tablename; + if (empty($keyfield)) { $keyfield = 'rowid'; } diff --git a/htdocs/core/modules/modWebServicesClient.class.php b/htdocs/core/modules/modWebServicesClient.class.php index d44d48ef13a..f2b75119523 100644 --- a/htdocs/core/modules/modWebServicesClient.class.php +++ b/htdocs/core/modules/modWebServicesClient.class.php @@ -46,7 +46,7 @@ class modWebServicesClient extends DolibarrModules $this->name = preg_replace('/^mod/i', '', get_class($this)); $this->description = "Enable the web service client to call external supplier web services"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'experimental'; + $this->version = 'experimental_deprecated'; // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of image file used for this module. diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index 8ca9a36b0f8..b1129bbb1ed 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -140,10 +140,10 @@ class pdf_aurore extends ModelePDFSupplierProposal $this->page_largeur = $formatarray['width']; $this->page_hauteur = $formatarray['height']; $this->format = array($this->page_largeur, $this->page_hauteur); - $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10; - $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10; - $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10; - $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10; + $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10); + $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10); + $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10); + $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10); $this->option_logo = 1; // Display logo $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION @@ -168,24 +168,18 @@ class pdf_aurore extends ModelePDFSupplierProposal $this->postotalht = 174; if (!empty($conf->global->PRODUCT_USE_UNITS)) { - $this->posxtva = 101; - $this->posxup = 118; + $this->posxup = 112; $this->posxqty = 135; $this->posxunit = 151; } else { - $this->posxtva = 102; - $this->posxup = 126; + $this->posxup = 120; $this->posxqty = 145; $this->posxunit = 162; } - if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || !empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) { - $this->posxup = $this->posxtva; - } - $this->posxpicture = $this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images + $this->posxpicture = $this->posxup - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images if ($this->page_largeur < 210) { // To work with US executive format $this->posxpicture -= 20; - $this->posxtva -= 20; $this->posxup -= 20; $this->posxqty -= 20; $this->posxunit -= 20; @@ -276,7 +270,7 @@ class pdf_aurore extends ModelePDFSupplierProposal } } if (count($realpatharray) == 0) { - $this->posxpicture = $this->posxtva; + $this->posxpicture = $this->posxup; } if ($conf->supplier_proposal->dir_output) { @@ -358,7 +352,6 @@ class pdf_aurore extends ModelePDFSupplierProposal if (empty($this->atleastonediscount)) { $delta = ($this->postotalht - $this->posxdiscount); $this->posxpicture += $delta; - $this->posxtva += $delta; $this->posxup += $delta; $this->posxqty += $delta; $this->posxunit += $delta; @@ -460,7 +453,7 @@ class pdf_aurore extends ModelePDFSupplierProposal if (!empty($imglinesize['width']) && !empty($imglinesize['height'])) { $curX = $this->posxpicture - 1; - $pdf->Image($realpatharray[$i], $curX + (($this->posxtva - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $curX + (($this->posxup - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } @@ -472,7 +465,7 @@ class pdf_aurore extends ModelePDFSupplierProposal if ($posYAfterImage > 0) { $descWidth = $this->posxpicture - $curX; } else { - $descWidth = $this->posxtva - $curX; + $descWidth = $this->posxup - $curX; } pdf_writelinedesc($pdf, $object, $i, $outputlangs, $descWidth, 3, $curX, $curY, $hideref, $hidedesc, 1); @@ -528,22 +521,6 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut - // VAT Rate - /* - if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) - { - $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); - $pdf->SetXY($this->posxtva, $curY); - $pdf->MultiCell($this->posxup-$this->posxtva-3, 3, $vat_rate, 0, 'R'); - } - - // Unit price before discount - $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); - $pdf->SetXY($this->posxup, $curY); - if ($up_excl_tax > 0) - $pdf->MultiCell($this->posxqty-$this->posxup-0.8, 3, $up_excl_tax, 0, 'R', 0); - */ - // Quantity $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); @@ -805,7 +782,7 @@ class pdf_aurore extends ModelePDFSupplierProposal $posy = $pdf->GetY() + 1; } - /* PHFAVRE + /* elseif ($object->availability_code || $object->availability) // Show availability conditions { $pdf->SetFont('','B', $default_font_size - 2); @@ -1138,22 +1115,6 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0); - /* - if ($object->close_code == 'discount_vat') - { - $index++; - $pdf->SetFillColor(255,255,255); - - $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1); - - $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1); - - $resteapayer=0; - } - */ - $index++; $pdf->SetTextColor(0, 0, 60); $pdf->SetFillColor(224, 224, 224); @@ -1226,16 +1187,7 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->MultiCell(108, 2, $outputlangs->transnoentities("Designation"), '', 'L'); } - if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) { - $pdf->line($this->posxtva, $tab_top, $this->posxtva, $tab_top + $tab_height); - //$pdf->line($this->posxtva-2, $tab_top, $this->posxtva-2, $tab_top + $tab_height); - if (empty($hidetop)) { - $pdf->SetXY($this->posxtva - 5, $tab_top + 1); - $pdf->MultiCell($this->posxup - $this->posxtva + 3, 2, $outputlangs->transnoentities("VAT"), '', 'C'); - } - } - - $pdf->line($this->posxup - 3, $tab_top, $this->posxup - 3, $tab_top + $tab_height); + $pdf->line($this->posxup + 1, $tab_top, $this->posxup + 1, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxup - 1, $tab_top + 1); $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUHT"), '', 'C'); @@ -1349,12 +1301,6 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefSupplier")." : ".dol_trunc($outputlangs->convToOutputCharset($object->ref_fourn), 65), '', 'R'); } - /* PHFAVRE - $posy+=4; - $pdf->SetXY($posx,$posy); - $pdf->SetTextColor(0,0,60); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("SupplierProposalDate")." : " . dol_print_date($object->delivery_date, "day", false, $outputlangs, true), '', 'R'); - */ if ($object->thirdparty->code_fournisseur) { $posy += 4; diff --git a/htdocs/core/triggers/interface_95_modWebhook_WebhookTriggers.class.php b/htdocs/core/triggers/interface_95_modWebhook_WebhookTriggers.class.php index a8932934bd1..94b4b861e86 100644 --- a/htdocs/core/triggers/interface_95_modWebhook_WebhookTriggers.class.php +++ b/htdocs/core/triggers/interface_95_modWebhook_WebhookTriggers.class.php @@ -104,7 +104,7 @@ class InterfaceWebhookTriggers extends DolibarrTriggers $actionarray = explode(",", $tmpobject->trigger_codes); if (is_array($actionarray) && in_array($action, $actionarray)) { $jsonstr = '{"triggercode":'.json_encode($action).',"object":'.json_encode($object).'}'; - $response = getURLContent($tmpobject->url, 'POST', $jsonstr); + $response = getURLContent($tmpobject->url, 'POST', $jsonstr, 1, array(), array('http', 'https'), 0, -1); if (empty($response['curl_error_no']) && $response['http_code'] >= 200 && $response['http_code'] < 300) { $nbPosts ++; } else { diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 3a0568c8fbe..470525102cc 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -28,22 +28,24 @@ */ /** - * \file htdocs/fourn/commande/card.php - * \ingroup supplier, order - * \brief Card supplier order + * \file htdocs/fourn/commande/card.php + * \ingroup supplier, order + * \brief Card supplier order */ + // Load Dolibarr environment require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + if (isModEnabled('supplier_proposal')) { require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; } @@ -60,29 +62,33 @@ if (!empty($conf->variants->enabled)) { require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php'; } + +// Load translation files required by the page $langs->loadLangs(array('admin', 'orders', 'sendings', 'companies', 'bills', 'propal', 'receptions', 'supplier_proposal', 'deliveries', 'products', 'stocks', 'productbatch')); if (!empty($conf->incoterm->enabled)) { $langs->load('incoterm'); } + +// Get Parameters $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); -$action = GETPOST('action', 'alpha'); -$confirm = GETPOST('confirm', 'alpha'); +$action = GETPOST('action', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'purchaseordercard'; // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); -$socid = GETPOST('socid', 'int'); +$socid = GETPOST('socid', 'int'); $projectid = GETPOST('projectid', 'int'); -$cancel = GETPOST('cancel', 'alpha'); -$lineid = GETPOST('lineid', 'int'); -$origin = GETPOST('origin', 'alpha'); -$originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility -$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; +$cancel = GETPOST('cancel', 'alpha'); +$lineid = GETPOST('lineid', 'int'); +$origin = GETPOST('origin', 'alpha'); +$originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility +$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; -//PDF +// PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php index 5fc4d46072e..dc30d1296f9 100644 --- a/htdocs/fourn/commande/index.php +++ b/htdocs/fourn/commande/index.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Vinicius Nogueira - * Copyright (C) 2019 Nicolas ZABOURI + * Copyright (C) 2019 Nicolas ZABOURI * * 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 @@ -20,16 +20,22 @@ */ /** - * \file htdocs/fourn/commande/index.php - * \ingroup commande fournisseur - * \brief Home page of supplier's orders area + * \file htdocs/fourn/commande/index.php + * \ingroup commande fournisseur + * \brief Home page of supplier's orders area */ + // Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; + + +// Load translation files required by the page +$langs->loadLangs(array("suppliers", "orders")); + // Security check $orderid = GETPOST('orderid'); @@ -43,8 +49,6 @@ $hookmanager = new HookManager($db); // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array $hookmanager->initHooks(array('orderssuppliersindex')); -// Load translation files required by the page -$langs->loadLangs(array("suppliers", "orders")); /* diff --git a/htdocs/fourn/commande/info.php b/htdocs/fourn/commande/info.php index 017818e3e6b..698fead1a43 100644 --- a/htdocs/fourn/commande/info.php +++ b/htdocs/fourn/commande/info.php @@ -19,17 +19,18 @@ */ /** - * \file htdocs/fourn/commande/info.php - * \ingroup commande - * \brief Fiche commande + * \file htdocs/fourn/commande/info.php + * \ingroup commande + * \brief Info page for Purchase Order / Supplier Order */ + // Load Dolibarr environment require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } @@ -37,8 +38,9 @@ if (isModEnabled('project')) { // Load translation files required by the page $langs->loadLangs(array("suppliers", "orders", "companies", "stocks")); -$id = GETPOST('id', 'int'); -$ref = GETPOST('ref', 'alpha'); +// Get Paramters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; @@ -79,6 +81,7 @@ if (empty($user->rights->fournisseur->commande->lire)) { accessforbidden(); } +// Init Hooks $hookmanager->initHooks(array('ordersuppliercardinfo')); diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 4b8c1cffc6d..b08396706d4 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -26,27 +26,30 @@ */ /** - * \file htdocs/fourn/commande/list.php - * \ingroup fournisseur - * \brief List of purchase orders + * \file htdocs/fourn/commande/list.php + * \ingroup fournisseur + * \brief List of purchase orders */ + // Load Dolibarr environment require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +// Load translation files required by the page $langs->loadLangs(array("orders", "sendings", 'deliveries', 'companies', 'compta', 'bills', 'projects', 'suppliers', 'products')); +// Get Parameters $action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); $show_files = GETPOST('show_files', 'int'); @@ -54,6 +57,7 @@ $confirm = GETPOST('confirm', 'alpha'); $toselect = GETPOST('toselect', 'array'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'supplierorderlist'; +// Search Criteria $search_date_order_startday = GETPOST('search_date_order_startday', 'int'); $search_date_order_startmonth = GETPOST('search_date_order_startmonth', 'int'); $search_date_order_startyear = GETPOST('search_date_order_startyear', 'int'); @@ -62,6 +66,7 @@ $search_date_order_endmonth = GETPOST('search_date_order_endmonth', 'int'); $search_date_order_endyear = GETPOST('search_date_order_endyear', 'int'); $search_date_order_start = dol_mktime(0, 0, 0, $search_date_order_startmonth, $search_date_order_startday, $search_date_order_startyear); // Use tzserver $search_date_order_end = dol_mktime(23, 59, 59, $search_date_order_endmonth, $search_date_order_endday, $search_date_order_endyear); + $search_date_delivery_startday = GETPOST('search_date_delivery_startday', 'int'); $search_date_delivery_startmonth = GETPOST('search_date_delivery_startmonth', 'int'); $search_date_delivery_startyear = GETPOST('search_date_delivery_startyear', 'int'); @@ -79,6 +84,7 @@ $search_date_valid_endmonth = GETPOST('search_date_valid_endmonth', 'int'); $search_date_valid_endyear = GETPOST('search_date_valid_endyear', 'int'); $search_date_valid_start = dol_mktime(0, 0, 0, $search_date_valid_startmonth, $search_date_valid_startday, $search_date_valid_startyear); // Use tzserver $search_date_valid_end = dol_mktime(23, 59, 59, $search_date_valid_endmonth, $search_date_valid_endday, $search_date_valid_endyear); + $search_date_approve_startday = GETPOST('search_date_approve_startday', 'int'); $search_date_approve_startmonth = GETPOST('search_date_approve_startmonth', 'int'); $search_date_approve_startyear = GETPOST('search_date_approve_startyear', 'int'); diff --git a/htdocs/fourn/commande/note.php b/htdocs/fourn/commande/note.php index ee5c0335ce9..167c506b651 100644 --- a/htdocs/fourn/commande/note.php +++ b/htdocs/fourn/commande/note.php @@ -20,11 +20,12 @@ */ /** - * \file htdocs/fourn/commande/note.php - * \ingroup commande - * \brief Fiche note commande + * \file htdocs/fourn/commande/note.php + * \ingroup commande + * \brief page for notes on supplier orders */ + // Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; @@ -36,6 +37,7 @@ if (isModEnabled('project')) { // Load translation files required by the page $langs->loadLangs(array("suppliers", "orders", "companies", "stocks")); +// Get Parameters $id = GETPOST('facid', 'int') ?GETPOST('facid', 'int') : GETPOST('id', 'int'); $ref = GETPOST('ref'); $action = GETPOST('action', 'aZ09'); @@ -45,12 +47,14 @@ if ($user->socid) { $socid = $user->socid; } +// Init Objects $hookmanager->initHooks(array('ordersuppliercardnote')); $result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); $object = new CommandeFournisseur($db); $object->fetch($id, $ref); +// Permissions $permissionnote = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer); // Used by the include of actions_setnotes.inc.php @@ -70,6 +74,7 @@ if (empty($reshook)) { /* * View */ + $title = $object->ref." - ".$langs->trans('Notes'); $help_url = 'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores'; llxHeader('', $title, $help_url); diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php index 857d41fc85b..74a459328f4 100644 --- a/htdocs/ftp/index.php +++ b/htdocs/ftp/index.php @@ -709,7 +709,7 @@ print '
'; if (!empty($conn_id)) { $disconnect = dol_ftp_close($conn_id); - if ($disconnect == false) { + if (!$disconnect) { setEventMessages($langs->trans("ErrorFTPNodisconnect"), null, 'errors'); } } diff --git a/htdocs/holiday/month_report.php b/htdocs/holiday/month_report.php index a3b8171cc62..735f8892129 100644 --- a/htdocs/holiday/month_report.php +++ b/htdocs/holiday/month_report.php @@ -335,7 +335,7 @@ print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', print '
'.$langs->trans('None').'
'.$langs->trans('None').'
'.$langs->trans("Description").''; - $doleditor = new DolEditor('desc', GETPOST('desc', 'restricthtml'), '', 160, 'dolibarr_details', '', false, true, getDolGlobalString('FCKEDITOR_ENABLE_PRODUCTDESC'), ROWS_4, '90%'); $doleditor->Create(); @@ -1485,6 +1487,14 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } } + if ($type == 1 && $conf->workstation->enabled) { + // Default workstation + print '
'.$langs->trans("DefaultWorkstation").''; + print img_picto($langs->trans("DefaultWorkstation"), 'workstation', 'class="pictofixedwidth"'); + print $formproduct->selectWorkstations($object->fk_default_workstation, 'fk_default_workstation', 1); + print '
'.$langs->trans("Duration").''; @@ -2024,6 +2034,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print '
'.$langs->trans("DefaultWorkstation").''; + print img_picto($langs->trans("DefaultWorkstation"), 'workstation', 'class="pictofixedwidth"'); + print $formproduct->selectWorkstations($object->fk_default_workstation, 'fk_default_workstation', 1); + print '
'.$langs->trans("DefaultWorkstation").''; + print (!empty($workstation->id) ? $workstation->getNomUrl(1) : ''); + print '
'.$langs->trans("SellingPrice").''; + print '
'.$langs->trans("SellingPrice").''; if ($object->price_base_type == 'TTC') { print price($object->price_ttc).' '.$langs->trans($object->price_base_type); } else { print price($object->price).' '.$langs->trans($object->price_base_type); + if (!empty($conf->global->PRODUCT_DISPLAY_VAT_INCL_PRICES) && !empty($object->price_ttc)) { + print ' - ' . price($object->price_ttc).' '.$langs->trans('TTC') . ''; + } } + print '
'.$langs->trans("MinPrice").''; + print '
'.$langs->trans("MinPrice").''; if ($object->price_base_type == 'TTC') { print price($object->price_min_ttc).' '.$langs->trans($object->price_base_type); } else { print price($object->price_min).' '.$langs->trans($object->price_base_type); + if (!empty($conf->global->PRODUCT_DISPLAY_VAT_INCL_PRICES) && !empty($object->price_min_ttc)) { + print ' - ' . price($object->price_min_ttc).' '.$langs->trans('TTC') . ''; + } } + print '
'.$langs->trans("Amount").''.$langs->trans("MembersNature").''.$langs->trans("VoteAllowed").''.$langs->trans("Members").''.$langs->trans("NewSubscription").'
'.yn($objp->vote).''.$membercount.'
'.$langs->trans("St if (!empty($conf->use_javascript_ajax) && ((round($third['prospect']) ? 1 : 0) + (round($third['customer']) ? 1 : 0) + (round($third['supplier']) ? 1 : 0) + (round($third['other']) ? 1 : 0) >= 2)) { $thirdpartygraph .= '
'; $dataseries = array(); - if (isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS)) { + if (isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS)) { $dataseries[] = array($langs->trans("Prospects"), round($third['prospect'])); } - if (isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS)) { + if (isModEnabled('societe') && $user->hasRight('societe', 'lire') && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS)) { $dataseries[] = array($langs->trans("Customers"), round($third['customer'])); } if (((isModEnabled('fournisseur') && $user->rights->fournisseur->facture->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || (isModEnabled('supplier_order') && $user->rights->supplier_order->lire) || (isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS)) { @@ -173,12 +173,12 @@ if (!empty($conf->use_javascript_ajax) && ((round($third['prospect']) ? 1 : 0) + $thirdpartygraph .= $dolgraph->show(); $thirdpartygraph .= '
'.$langs->trans("Prospects").''.round($third['prospect']).'
'.$langs->trans("Customers").''.round($third['customer']).'