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;