From 73dab143a3c6bac5fdf7546bcf8ee8fde0576c73 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Thu, 19 Nov 2020 14:14:24 +0100 Subject: [PATCH 1/7] NEW Add an option to hide by default icon shippable order in command list --- htdocs/commande/list.php | 181 +++++++++++++++-------------- htdocs/langs/en_US/deliveries.lang | 1 + htdocs/langs/fr_FR/deliveries.lang | 1 + 3 files changed, 94 insertions(+), 89 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 3e7a8d416cf..ff784a73a99 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -114,6 +114,8 @@ $pagenext = $page + 1; if (!$sortfield) $sortfield = 'c.ref'; if (!$sortorder) $sortorder = 'DESC'; +$show_shippable_command = GETPOST('show_shippable_command', 'aZ09'); + // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new Commande($db); $hookmanager->initHooks(array('orderlist')); @@ -569,6 +571,11 @@ if ($resql) $moreforfilter = ''; + $moreforfilter .= '
'; + $moreforfilter .= $langs->trans('ShowShippableCommand').': '; + $moreforfilter .= ''; + $moreforfilter.='
'; + // If the user can view prospects other than his' if ($user->rights->societe->client->voir || $socid) { @@ -950,108 +957,104 @@ if ($resql) if (!empty($arrayfields['c.ref']['checked'])) { print ''; - - $generic_commande->getLinesArray(); // This set ->lines + if(!empty($show_shippable_command)) { + $generic_commande->getLinesArray(); // This set ->lines + } print $generic_commande->getNomUrl(1, ($search_status != 2 ? 0 : $obj->fk_statut), 0, 0, 0, 1, 1); - // Show shippable Icon (create subloop, so may be slow) - if ($conf->stock->enabled) - { - if (($obj->fk_statut > 0) && ($obj->fk_statut < 3)) - { - $numlines = count($generic_commande->lines); // Loop on each line of order - for ($lig = 0; $lig < $numlines; $lig++) - { - if ($generic_commande->lines[$lig]->product_type == 0 && $generic_commande->lines[$lig]->fk_product > 0) // If line is a product and not a service - { - $nbprod++; // order contains real products - $generic_product->id = $generic_commande->lines[$lig]->fk_product; - - // Get local and virtual stock and store it into cache - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) { - $generic_product->load_stock('nobatch'); - //$generic_product->load_virtual_stock(); Already included into load_stock - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel; - $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; - } else { - $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; - $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; - } - - if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code. Default is when this option is not set, setting it create strange result + if(!empty($show_shippable_command)) { + // Show shippable Icon (create subloop, so may be slow) + if ($conf->stock->enabled) { + if (($obj->fk_statut > 0) && ($obj->fk_statut < 3)) { + $numlines = count($generic_commande->lines); // Loop on each line of order + for ($lig = 0; $lig < $numlines; $lig++) { + if ($generic_commande->lines[$lig]->product_type == 0 && $generic_commande->lines[$lig]->fk_product > 0) // If line is a product and not a service { - $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->product_ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); - $text_info .= ' - '.$langs->trans("Stock").': '.$generic_product->stock_reel.''; - $text_info .= ' - '.$langs->trans("VirtualStock").': '.$generic_product->stock_theorique.''; - $text_info .= '
'; + $nbprod++; // order contains real products + $generic_product->id = $generic_commande->lines[$lig]->fk_product; - if ($generic_commande->lines[$lig]->qty > $generic_product->stock_reel) - { - $notshippable++; - } - } else { // Detailed virtual stock, looks bugged, uncomplete and need heavy load. - // stock order and stock order_supplier - $stock_order = 0; - $stock_order_supplier = 0; - if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) // What about other options ? - { - if (!empty($conf->commande->enabled)) - { - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'])) { - $generic_product->load_stats_commande(0, '1,2'); - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'] = $generic_product->stats_commande['qty']; - } else { - $generic_product->stats_commande['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer']; - } - $stock_order = $generic_product->stats_commande['qty']; - } - if (!empty($conf->fournisseur->enabled)) - { - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'])) { - $generic_product->load_stats_commande_fournisseur(0, '3'); - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'] = $generic_product->stats_commande_fournisseur['qty']; - } else { - $generic_product->stats_commande_fournisseur['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier']; - } - $stock_order_supplier = $generic_product->stats_commande_fournisseur['qty']; - } - } - $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); - $text_stock_reel = $generic_product->stock_reel.'/'.$stock_order; - if ($stock_order > $generic_product->stock_reel && !($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { - $warning++; - $text_warning .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; - } - if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { - $notshippable++; - $text_info .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; + // Get local and virtual stock and store it into cache + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) { + $generic_product->load_stock('nobatch'); + //$generic_product->load_virtual_stock(); Already included into load_stock + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel; + $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } else { - $text_info .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; + $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; + $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } - if (!empty($conf->fournisseur->enabled)) { - $text_info .= ' '.$langs->trans('SupplierOrder').' : '.$stock_order_supplier.'
'; - } else { + + if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code. Default is when this option is not set, setting it create strange result + { + $text_info .= $generic_commande->lines[$lig]->qty . ' X ' . $generic_commande->lines[$lig]->product_ref . ' ' . dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_info .= ' - ' . $langs->trans("Stock") . ': ' . $generic_product->stock_reel . ''; + $text_info .= ' - ' . $langs->trans("VirtualStock") . ': ' . $generic_product->stock_theorique . ''; $text_info .= '
'; + + if ($generic_commande->lines[$lig]->qty > $generic_product->stock_reel) { + $notshippable++; + } + } else { // Detailed virtual stock, looks bugged, uncomplete and need heavy load. + // stock order and stock order_supplier + $stock_order = 0; + $stock_order_supplier = 0; + if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) // What about other options ? + { + if (!empty($conf->commande->enabled)) { + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'])) { + $generic_product->load_stats_commande(0, '1,2'); + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'] = $generic_product->stats_commande['qty']; + } else { + $generic_product->stats_commande['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer']; + } + $stock_order = $generic_product->stats_commande['qty']; + } + if (!empty($conf->fournisseur->enabled)) { + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'])) { + $generic_product->load_stats_commande_fournisseur(0, '3'); + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'] = $generic_product->stats_commande_fournisseur['qty']; + } else { + $generic_product->stats_commande_fournisseur['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier']; + } + $stock_order_supplier = $generic_product->stats_commande_fournisseur['qty']; + } + } + $text_info .= $generic_commande->lines[$lig]->qty . ' X ' . $generic_commande->lines[$lig]->ref . ' ' . dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_stock_reel = $generic_product->stock_reel . '/' . $stock_order; + if ($stock_order > $generic_product->stock_reel && !($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { + $warning++; + $text_warning .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; + } + if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { + $notshippable++; + $text_info .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; + } else { + $text_info .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; + } + if (!empty($conf->fournisseur->enabled)) { + $text_info .= ' ' . $langs->trans('SupplierOrder') . ' : ' . $stock_order_supplier . '
'; + } else { + $text_info .= '
'; + } } } } + if ($notshippable == 0) { + $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'green paddingleft'); + $text_info = $langs->trans('Shippable') . '
' . $text_info; + } else { + $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'error paddingleft'); + $text_info = $langs->trans('NonShippable') . '
' . $text_info; + } } - if ($notshippable == 0) { - $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'green paddingleft'); - $text_info = $langs->trans('Shippable').'
'.$text_info; - } else { - $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'error paddingleft'); - $text_info = $langs->trans('NonShippable').'
'.$text_info; - } - } - if ($nbprod) - { - print $form->textwithtooltip('', $text_info, 2, 1, $text_icon, '', 2); - } - if ($warning) { // Always false in default mode - print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders').'
'.$text_warning, 2, 1, img_picto('', 'error'), '', 2); + if ($nbprod) { + print $form->textwithtooltip('', $text_info, 2, 1, $text_icon, '', 2); + } + if ($warning) { // Always false in default mode + print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders') . '
' . $text_warning, 2, 1, img_picto('', 'error'), '', 2); + } } } diff --git a/htdocs/langs/en_US/deliveries.lang b/htdocs/langs/en_US/deliveries.lang index 1f48c01de75..0713ebd9f2d 100644 --- a/htdocs/langs/en_US/deliveries.lang +++ b/htdocs/langs/en_US/deliveries.lang @@ -27,5 +27,6 @@ Recipient=Recipient ErrorStockIsNotEnough=There's not enough stock Shippable=Shippable NonShippable=Not Shippable +ShowShippableCommand=Show shippable command ShowReceiving=Show delivery receipt NonExistentOrder=Nonexistent order diff --git a/htdocs/langs/fr_FR/deliveries.lang b/htdocs/langs/fr_FR/deliveries.lang index ff244a08917..29cbd5736cf 100644 --- a/htdocs/langs/fr_FR/deliveries.lang +++ b/htdocs/langs/fr_FR/deliveries.lang @@ -27,5 +27,6 @@ Recipient=Destinataire ErrorStockIsNotEnough=Le stock est insuffisant Shippable=Expédiable NonShippable=Non expédiable +ShowShippableCommand=Afficher statut expédiabilité ShowReceiving=Afficher le bon de réception NonExistentOrder=Commande inexistante From 7e207e80ae42343380ea4389d2a898787068e822 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Thu, 19 Nov 2020 14:29:37 +0100 Subject: [PATCH 2/7] FIX spaces before IF --- htdocs/commande/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index ff784a73a99..3d8e152c870 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -957,13 +957,13 @@ if ($resql) if (!empty($arrayfields['c.ref']['checked'])) { print ''; - if(!empty($show_shippable_command)) { + if (!empty($show_shippable_command)) { $generic_commande->getLinesArray(); // This set ->lines } print $generic_commande->getNomUrl(1, ($search_status != 2 ? 0 : $obj->fk_statut), 0, 0, 0, 1, 1); - if(!empty($show_shippable_command)) { + if (!empty($show_shippable_command)) { // Show shippable Icon (create subloop, so may be slow) if ($conf->stock->enabled) { if (($obj->fk_statut > 0) && ($obj->fk_statut < 3)) { From f29ed4b045bf1bf5185284645c48bd566511dafd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 19 Nov 2020 17:49:23 +0100 Subject: [PATCH 3/7] Fix limit to send emails --- scripts/emailings/mailing-send.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php index d4c915c3b72..b4354e086b5 100755 --- a/scripts/emailings/mailing-send.php +++ b/scripts/emailings/mailing-send.php @@ -39,14 +39,20 @@ if (substr($sapi_type, 0, 3) == 'cgi') { } if (!isset($argv[1]) || !$argv[1]) { - print "Usage: ".$script_file." (ID_MAILING|all)\n"; + print "Usage: ".$script_file." (ID_MAILING|all) [userloginforsignature] [maxnbofemails]\n"; exit(-1); } + $id = $argv[1]; -if (isset($argv[2]) || !empty($argv[2])) - $login = $argv[2]; + +if (isset($argv[2]) || !empty($argv[2])) $login = $argv[2]; else $login = ''; +$max = 0; + +if (isset($argv[3]) || !empty($argv[3])) $max = $argv[3]; + + require_once $path."../../htdocs/master.inc.php"; require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php"; require_once DOL_DOCUMENT_ROOT."/comm/mailing/class/mailing.class.php"; @@ -113,9 +119,13 @@ if ($resql) { // ou envoyes en erreur (statut=-1) $sql2 = "SELECT mc.rowid, mc.fk_mailing, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag"; $sql2 .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; - $sql2 .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".$id; - if ($conf->global->MAILING_LIMIT_SENDBYCLI > 0) { + $sql2 .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".((int) $id); + if ($conf->global->MAILING_LIMIT_SENDBYCLI > 0 && empty($max)) { $sql2 .= " LIMIT ".$conf->global->MAILING_LIMIT_SENDBYCLI; + } elseif ($conf->global->MAILING_LIMIT_SENDBYCLI > 0 && $max > 0) { + $sql2 .= " LIMIT ".min($conf->global->MAILING_LIMIT_SENDBYCLI, $max); + } elseif ($max > 0) { + $sql2 .= " LIMIT ".$max; } $resql2 = $db->query($sql2); @@ -128,7 +138,7 @@ if ($resql) { $now = dol_now(); // Positionne date debut envoi - $sqlstartdate = "UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi='".$db->idate($now)."' WHERE rowid=".$id; + $sqlstartdate = "UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi='".$db->idate($now)."' WHERE rowid=".((int) $id); $resqlstartdate = $db->query($sqlstartdate); if (!$resqlstartdate) { dol_print_error($db); From 8b2ec747d446db39c5223c996e1af819e0c504d2 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 19 Nov 2020 17:59:03 +0100 Subject: [PATCH 4/7] fix warning --- htdocs/main.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index b5eb35dd2d9..561966881c8 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -988,7 +988,7 @@ if (!defined('NOLOGIN')) $user->getrights(); } -dol_syslog("--- Access to ".$_SERVER["REQUEST_METHOD"].' '.$_SERVER["PHP_SELF"].' - action='.GETPOST('action', 'aZ09').', massaction='.GETPOST('massaction', 'aZ09').' NOTOKENRENEWAL='.constant('NOTOKENRENEWAL')); +dol_syslog("--- Access to ".$_SERVER["REQUEST_METHOD"].' '.$_SERVER["PHP_SELF"].' - action='.GETPOST('action', 'aZ09').', massaction='.GETPOST('massaction', 'aZ09').' NOTOKENRENEWAL='.(defined('NOTOKENRENEWAL')?constant('NOTOKENRENEWAL'):'')); //Another call for easy debugg //dol_syslog("Access to ".$_SERVER["PHP_SELF"].' GET='.join(',',array_keys($_GET)).'->'.join(',',$_GET).' POST:'.join(',',array_keys($_POST)).'->'.join(',',$_POST)); From aa7383f3d401116494dd6630fddf2701f04b3a36 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 19 Nov 2020 18:15:40 +0100 Subject: [PATCH 5/7] Fix warning --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 5845547a027..74f77c28558 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6475,7 +6475,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__AMOUNT_FORMATED__'] = is_object($object) ? ($object->total_ttc ? price($object->total_ttc, 0, $outputlangs, 0, 0, -1, $conf->currency) : null) : ''; $substitutionarray['__AMOUNT_EXCL_TAX_FORMATED__'] = is_object($object) ? ($object->total_ht ? price($object->total_ht, 0, $outputlangs, 0, 0, -1, $conf->currency) : null) : ''; - $substitutionarray['__AMOUNT_VAT_FORMATED__'] = is_object($object) ? ($object->total_vat ? price($object->total_vat, 0, $outputlangs, 0, 0, -1, $conf->currency) : ($object->total_tva ? price($object->total_tva, 0, $outputlangs, 0, 0, -1, $conf->currency) : null)) : ''; + $substitutionarray['__AMOUNT_VAT_FORMATED__'] = is_object($object) ? (isset($object->total_vat) ? price($object->total_vat, 0, $outputlangs, 0, 0, -1, $conf->currency) : ($object->total_tva ? price($object->total_tva, 0, $outputlangs, 0, 0, -1, $conf->currency) : null)) : ''; if ($onlykey != 2 || $mysoc->useLocalTax(1)) $substitutionarray['__AMOUNT_TAX2_FORMATED__'] = is_object($object) ? ($object->total_localtax1 ? price($object->total_localtax1, 0, $outputlangs, 0, 0, -1, $conf->currency) : null) : ''; if ($onlykey != 2 || $mysoc->useLocalTax(2)) $substitutionarray['__AMOUNT_TAX3_FORMATED__'] = is_object($object) ? ($object->total_localtax2 ? price($object->total_localtax2, 0, $outputlangs, 0, 0, -1, $conf->currency) : null) : ''; From 06545e005b8718e8e96cf0d0fdeb56c3630de19f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 19 Nov 2020 18:55:37 +0100 Subject: [PATCH 6/7] Use status constant --- htdocs/commande/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 3d8e152c870..9186f8c39c0 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -965,8 +965,8 @@ if ($resql) if (!empty($show_shippable_command)) { // Show shippable Icon (create subloop, so may be slow) - if ($conf->stock->enabled) { - if (($obj->fk_statut > 0) && ($obj->fk_statut < 3)) { + if (! empty($conf->stock->enabled)) { + if (($obj->fk_statut > $generic_commande::STATUS_DRAFT) && ($obj->fk_statut < $generic_commande::STATUS_CLOSED)) { $numlines = count($generic_commande->lines); // Loop on each line of order for ($lig = 0; $lig < $numlines; $lig++) { if ($generic_commande->lines[$lig]->product_type == 0 && $generic_commande->lines[$lig]->fk_product > 0) // If line is a product and not a service From 772d401a649ddcf60a00ef3beedf539a88314951 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 19 Nov 2020 19:56:00 +0100 Subject: [PATCH 7/7] FIX Restore a more common behavior. Add a hidden constant to switch to a mode when we must enabled load of shippable status. --- htdocs/commande/list.php | 232 ++++++++++++++----------- htdocs/langs/en_US/deliveries.lang | 2 +- htdocs/product/class/product.class.php | 2 +- 3 files changed, 129 insertions(+), 107 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 9186f8c39c0..71ff0ef147a 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -94,6 +94,8 @@ $search_btn = GETPOST('button_search', 'alpha'); $search_remove_btn = GETPOST('button_removefilter', 'alpha'); $search_project_ref = GETPOST('search_project_ref', 'alpha'); $search_project = GETPOST('search_project', 'alpha'); +$search_shippable = GETPOST('search_shippable', 'aZ09'); + // Security check $id = (GETPOST('orderid') ?GETPOST('orderid', 'int') : GETPOST('id', 'int')); @@ -167,7 +169,8 @@ $arrayfields = array( 'c.note_public'=>array('label'=>'NotePublic', 'checked'=>0, 'position'=>510, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PUBLIC_NOTES))), 'c.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'position'=>511, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PRIVATE_NOTES))), 'c.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), - 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'position'=>1000, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) + 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'position'=>1000, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))), + 'shippable'=>array('label'=>"Shippable", 'checked'=>1, 'position'=>1000, 'enabled'=>(!empty($conf->expedition->enabled))) ); // Extra fields include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -571,11 +574,6 @@ if ($resql) $moreforfilter = ''; - $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('ShowShippableCommand').': '; - $moreforfilter .= ''; - $moreforfilter.='
'; - // If the user can view prospects other than his' if ($user->rights->societe->client->voir || $socid) { @@ -848,6 +846,19 @@ if ($resql) print $form->selectarray('search_status', $liststatus, $search_status, -4, 0, 0, '', 0, 0, 0, '', 'maxwidth100', 1); print ''; } + // Shippable + if (!empty($arrayfields['shippable']['checked'])) + { + print ''; + //print $form->selectyesno('search_shippable', $search_shippable, 1, 0, 1, 1); + if (! empty($conf->global->ORDER_SHIPABLE_STATUS_DISABLED_BY_DEFAULT)) { + print ''; + print $langs->trans('ShowShippableStatus'); + } else { + $show_shippable_command = 1; + } + print ''; + } // Status billed if (!empty($arrayfields['c.facture']['checked'])) { @@ -899,6 +910,7 @@ if ($resql) if (!empty($arrayfields['c.note_public']['checked'])) print_liste_field_titre($arrayfields['c.note_public']['label'], $_SERVER["PHP_SELF"], "c.note_public", "", $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['c.note_private']['checked'])) print_liste_field_titre($arrayfields['c.note_private']['label'], $_SERVER["PHP_SELF"], "c.note_private", "", $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['c.fk_statut']['checked'])) print_liste_field_titre($arrayfields['c.fk_statut']['label'], $_SERVER["PHP_SELF"], "c.fk_statut", "", $param, '', $sortfield, $sortorder, 'right '); + if (!empty($arrayfields['shippable']['checked'])) print_liste_field_titre($arrayfields['shippable']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center '); if (!empty($arrayfields['c.facture']['checked'])) print_liste_field_titre($arrayfields['c.facture']['label'], $_SERVER["PHP_SELF"], 'c.facture', '', $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'maxwidthsearch center '); print ''."\n"; @@ -957,107 +969,8 @@ if ($resql) if (!empty($arrayfields['c.ref']['checked'])) { print ''; - if (!empty($show_shippable_command)) { - $generic_commande->getLinesArray(); // This set ->lines - } - print $generic_commande->getNomUrl(1, ($search_status != 2 ? 0 : $obj->fk_statut), 0, 0, 0, 1, 1); - if (!empty($show_shippable_command)) { - // Show shippable Icon (create subloop, so may be slow) - if (! empty($conf->stock->enabled)) { - if (($obj->fk_statut > $generic_commande::STATUS_DRAFT) && ($obj->fk_statut < $generic_commande::STATUS_CLOSED)) { - $numlines = count($generic_commande->lines); // Loop on each line of order - for ($lig = 0; $lig < $numlines; $lig++) { - if ($generic_commande->lines[$lig]->product_type == 0 && $generic_commande->lines[$lig]->fk_product > 0) // If line is a product and not a service - { - $nbprod++; // order contains real products - $generic_product->id = $generic_commande->lines[$lig]->fk_product; - - // Get local and virtual stock and store it into cache - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) { - $generic_product->load_stock('nobatch'); - //$generic_product->load_virtual_stock(); Already included into load_stock - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel; - $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; - } else { - $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; - $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; - } - - if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code. Default is when this option is not set, setting it create strange result - { - $text_info .= $generic_commande->lines[$lig]->qty . ' X ' . $generic_commande->lines[$lig]->product_ref . ' ' . dol_trunc($generic_commande->lines[$lig]->product_label, 25); - $text_info .= ' - ' . $langs->trans("Stock") . ': ' . $generic_product->stock_reel . ''; - $text_info .= ' - ' . $langs->trans("VirtualStock") . ': ' . $generic_product->stock_theorique . ''; - $text_info .= '
'; - - if ($generic_commande->lines[$lig]->qty > $generic_product->stock_reel) { - $notshippable++; - } - } else { // Detailed virtual stock, looks bugged, uncomplete and need heavy load. - // stock order and stock order_supplier - $stock_order = 0; - $stock_order_supplier = 0; - if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) // What about other options ? - { - if (!empty($conf->commande->enabled)) { - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'])) { - $generic_product->load_stats_commande(0, '1,2'); - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'] = $generic_product->stats_commande['qty']; - } else { - $generic_product->stats_commande['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer']; - } - $stock_order = $generic_product->stats_commande['qty']; - } - if (!empty($conf->fournisseur->enabled)) { - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'])) { - $generic_product->load_stats_commande_fournisseur(0, '3'); - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'] = $generic_product->stats_commande_fournisseur['qty']; - } else { - $generic_product->stats_commande_fournisseur['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier']; - } - $stock_order_supplier = $generic_product->stats_commande_fournisseur['qty']; - } - } - $text_info .= $generic_commande->lines[$lig]->qty . ' X ' . $generic_commande->lines[$lig]->ref . ' ' . dol_trunc($generic_commande->lines[$lig]->product_label, 25); - $text_stock_reel = $generic_product->stock_reel . '/' . $stock_order; - if ($stock_order > $generic_product->stock_reel && !($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { - $warning++; - $text_warning .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; - } - if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { - $notshippable++; - $text_info .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; - } else { - $text_info .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; - } - if (!empty($conf->fournisseur->enabled)) { - $text_info .= ' ' . $langs->trans('SupplierOrder') . ' : ' . $stock_order_supplier . '
'; - } else { - $text_info .= '
'; - } - } - } - } - if ($notshippable == 0) { - $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'green paddingleft'); - $text_info = $langs->trans('Shippable') . '
' . $text_info; - } else { - $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'error paddingleft'); - $text_info = $langs->trans('NonShippable') . '
' . $text_info; - } - } - - if ($nbprod) { - print $form->textwithtooltip('', $text_info, 2, 1, $text_icon, '', 2); - } - if ($warning) { // Always false in default mode - print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders') . '
' . $text_warning, 2, 1, img_picto('', 'error'), '', 2); - } - } - } - // Warning late icon and note if ($generic_commande->hasDelay()) { print img_picto($langs->trans("Late").' : '.$generic_commande->showDelay(), "warning"); @@ -1259,6 +1172,7 @@ if ($resql) $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; + // Date creation if (!empty($arrayfields['c.datec']['checked'])) { @@ -1267,6 +1181,7 @@ if ($resql) print ''; if (!$i) $totalarray['nbfield']++; } + // Date modification if (!empty($arrayfields['c.tms']['checked'])) { @@ -1275,6 +1190,7 @@ if ($resql) print ''; if (!$i) $totalarray['nbfield']++; } + // Date cloture if (!empty($arrayfields['c.date_cloture']['checked'])) { @@ -1283,6 +1199,7 @@ if ($resql) print ''; if (!$i) $totalarray['nbfield']++; } + // Note public if (!empty($arrayfields['c.note_public']['checked'])) { @@ -1291,6 +1208,7 @@ if ($resql) print ''; if (!$i) $totalarray['nbfield']++; } + // Note private if (!empty($arrayfields['c.note_private']['checked'])) { @@ -1299,12 +1217,116 @@ if ($resql) print ''; if (!$i) $totalarray['nbfield']++; } + // Status if (!empty($arrayfields['c.fk_statut']['checked'])) { print ''.$generic_commande->LibStatut($obj->fk_statut, $obj->billed, 5, 1).''; if (!$i) $totalarray['nbfield']++; } + + // Show shippable Icon (this creates subloops, so may be slow) + if (!empty($arrayfields['shippable']['checked'])) + { + print ''; + if (!empty($show_shippable_command) && !empty($conf->stock->enabled)) { + if (($obj->fk_statut > $generic_commande::STATUS_DRAFT) && ($obj->fk_statut < $generic_commande::STATUS_CLOSED)) { + $generic_commande->getLinesArray(); // This set ->lines + + $numlines = count($generic_commande->lines); // Loop on each line of order + for ($lig = 0; $lig < $numlines; $lig++) { + if ($generic_commande->lines[$lig]->product_type == 0 && $generic_commande->lines[$lig]->fk_product > 0) // If line is a product and not a service + { + $nbprod++; // order contains real products + $generic_product->id = $generic_commande->lines[$lig]->fk_product; + + // Get local and virtual stock and store it into cache + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) { + $generic_product->load_stock('nobatch'); // ->load_virtual_stock() is already included into load_stock() + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel; + $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; + } else { + $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; + $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; + } + + if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code. Default should be this case. + { + $text_info .= $generic_commande->lines[$lig]->qty . ' X ' . $generic_commande->lines[$lig]->product_ref . ' ' . dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_info .= ' - ' . $langs->trans("Stock") . ': ' . $generic_product->stock_reel . ''; + $text_info .= ' - ' . $langs->trans("VirtualStock") . ': ' . $generic_product->stock_theorique . ''; + $text_info .= '
'; + + if ($generic_commande->lines[$lig]->qty > $generic_product->stock_reel) { + $notshippable++; + } + } else { // BUGGED CODE. + // DOES NOT TAKE INTO ACCOUNT MANUFACTURING. THIS CODE SHOULD BE USELESS. PREVIOUS CODE SEEMS COMPLETE. + // COUNT STOCK WHEN WE SHOULD ALREADY HAVE VALUE + // Detailed virtual stock, looks bugged, uncomplete and need heavy load. + // stock order and stock order_supplier + $stock_order = 0; + $stock_order_supplier = 0; + if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) // What about other options ? + { + if (!empty($conf->commande->enabled)) { + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'])) { + $generic_product->load_stats_commande(0, '1,2'); + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'] = $generic_product->stats_commande['qty']; + } else { + $generic_product->stats_commande['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer']; + } + $stock_order = $generic_product->stats_commande['qty']; + } + if (!empty($conf->fournisseur->enabled)) { + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'])) { + $generic_product->load_stats_commande_fournisseur(0, '3'); + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'] = $generic_product->stats_commande_fournisseur['qty']; + } else { + $generic_product->stats_commande_fournisseur['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier']; + } + $stock_order_supplier = $generic_product->stats_commande_fournisseur['qty']; + } + } + $text_info .= $generic_commande->lines[$lig]->qty . ' X ' . $generic_commande->lines[$lig]->ref . ' ' . dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_stock_reel = $generic_product->stock_reel . '/' . $stock_order; + if ($stock_order > $generic_product->stock_reel && !($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { + $warning++; + $text_warning .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; + } + if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { + $notshippable++; + $text_info .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; + } else { + $text_info .= '' . $langs->trans('Available') . ' : ' . $text_stock_reel . ''; + } + if (!empty($conf->fournisseur->enabled)) { + $text_info .= ' ' . $langs->trans('SupplierOrder') . ' : ' . $stock_order_supplier . '
'; + } else { + $text_info .= '
'; + } + } + } + } + if ($notshippable == 0) { + $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'green paddingleft'); + $text_info = $langs->trans('Shippable') . '
' . $text_info; + } else { + $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'error paddingleft'); + $text_info = $langs->trans('NonShippable') . '
' . $text_info; + } + } + + if ($nbprod) { + print $form->textwithtooltip('', $text_info, 2, 1, $text_icon, '', 2); + } + if ($warning) { // Always false in default mode + print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders') . '
' . $text_warning, 2, 1, img_picto('', 'error'), '', 2); + } + } + print ''; + } + // Billed if (!empty($arrayfields['c.facture']['checked'])) { diff --git a/htdocs/langs/en_US/deliveries.lang b/htdocs/langs/en_US/deliveries.lang index 0713ebd9f2d..fdfd6404a8a 100644 --- a/htdocs/langs/en_US/deliveries.lang +++ b/htdocs/langs/en_US/deliveries.lang @@ -27,6 +27,6 @@ Recipient=Recipient ErrorStockIsNotEnough=There's not enough stock Shippable=Shippable NonShippable=Not Shippable -ShowShippableCommand=Show shippable command +ShowShippableStatus=Show shippable status ShowReceiving=Show delivery receipt NonExistentOrder=Nonexistent order diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 292690020b9..fc732802eda 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4898,7 +4898,7 @@ class Product extends CommonObject $this->db->free($result); if (!preg_match('/novirtual/', $option)) { - $this->load_virtual_stock($includedraftpoforvirtual); // This also load stats_commande_fournisseur, ... + $this->load_virtual_stock($includedraftpoforvirtual); // This also load all arrays stats_xxx... } return 1;