dolibarr  7.0.0-beta
replenish.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2013 C├ędric Salvador <csalvador@gpcsolutions.fr>
3  * Copyright (C) 2013-2016 Laurent Destaileur <ely@users.sourceforge.net>
4  * Copyright (C) 2014 Regis Houssin <regis.houssin@capnetworks.com>
5  * Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2016 ATM Consulting <support@atm-consulting.fr>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
28 require '../../main.inc.php';
29 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
34 require_once './lib/replenishment.lib.php';
35 
36 $langs->load("products");
37 $langs->load("stocks");
38 $langs->load("orders");
39 
40 // Security check
41 if ($user->societe_id) {
42  $socid = $user->societe_id;
43 }
44 $result=restrictedArea($user,'produit|service');
45 
46 //checks if a product has been ordered
47 
48 $action = GETPOST('action','alpha');
49 $sref = GETPOST('sref', 'alpha');
50 $snom = GETPOST('snom', 'alpha');
51 $sall = trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml'));
52 $type = GETPOST('type','int');
53 $tobuy = GETPOST('tobuy', 'int');
54 $salert = GETPOST('salert', 'alpha');
55 $mode = GETPOST('mode','alpha');
56 $draftorder = GETPOST('draftorder','alpha');
57 
58 
59 $fourn_id = GETPOST('fourn_id','int');
60 $fk_supplier = GETPOST('fk_supplier','int');
61 $fk_entrepot = GETPOST('fk_entrepot','int');
62 $texte = '';
63 
64 $sortfield = GETPOST('sortfield','alpha');
65 $sortorder = GETPOST('sortorder','alpha');
66 $page = GETPOST('page','int');
67 if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
68 $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
69 $offset = $limit * $page ;
70 
71 if (!$sortfield) {
72  $sortfield = 'p.ref';
73 }
74 
75 if (!$sortorder) {
76  $sortorder = 'ASC';
77 }
78 
79 // Define virtualdiffersfromphysical
80 $virtualdiffersfromphysical=0;
81 if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)
82 || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)
83 || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE))
84 {
85  $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs.
86 }
87 $usevirtualstock=0;
88 if ($mode == 'virtual') $usevirtualstock=1;
89 
90 
91 /*
92  * Actions
93  */
94 
95 if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha') || isset($_POST['valid'])) // Both test are required to be compatible with all browsers
96 {
97  $sref = '';
98  $snom = '';
99  $sal = '';
100  $salert = '';
101  $draftorder='';
102 }
103 if($draftorder == 'on') $draftchecked = "checked";
104 
105 // Create orders
106 if ($action == 'order' && isset($_POST['valid']))
107 {
108  $linecount = GETPOST('linecount', 'int');
109  $box = 0;
110  unset($_POST['linecount']);
111  if ($linecount > 0)
112  {
113  $db->begin();
114 
115  $suppliers = array();
116  for ($i = 0; $i < $linecount; $i++)
117  {
118  if (GETPOST('choose' . $i, 'alpha') === 'on' && GETPOST('fourn' . $i, 'int') > 0)
119  {
120  //one line
121  $box = $i;
122  $supplierpriceid = GETPOST('fourn'.$i, 'int');
123  //get all the parameters needed to create a line
124  $qty = GETPOST('tobuy'.$i, 'int');
125  //$desc = GETPOST('desc'.$i, 'alpha');
126  $sql = 'SELECT fk_product, fk_soc, ref_fourn';
127  $sql .= ', tva_tx, unitprice, remise_percent FROM ';
128  $sql .= MAIN_DB_PREFIX . 'product_fournisseur_price';
129  $sql .= ' WHERE rowid = ' . $supplierpriceid;
130  $resql = $db->query($sql);
131  if ($resql && $db->num_rows($resql) > 0)
132  {
133  if ($qty)
134  {
135  //might need some value checks
136  $obj = $db->fetch_object($resql);
137  $line = new CommandeFournisseurLigne($db);
138  $line->qty = $qty;
139  $line->fk_product = $obj->fk_product;
140 
141  $product = new Product($db);
142  $product->fetch($obj->fk_product);
143  if (! empty($conf->global->MAIN_MULTILANGS))
144  {
145  $product->getMultiLangs();
146  }
147  $line->desc = $product->description;
148  if (! empty($conf->global->MAIN_MULTILANGS))
149  {
150  // TODO Get desc in language of thirdparty
151  }
152 
153  $line->tva_tx = $obj->tva_tx;
154  $line->subprice = $obj->unitprice;
155  $line->total_ht = $obj->unitprice * $qty;
156  $tva = $line->tva_tx / 100;
157  $line->total_tva = $line->total_ht * $tva;
158  $line->total_ttc = $line->total_ht + $line->total_tva;
159  $line->remise_percent = $obj->remise_percent;
160  $line->ref_fourn = $obj->ref_fourn;
161  $suppliers[$obj->fk_soc]['lines'][] = $line;
162  }
163  }
164  else
165  {
166  $error=$db->lasterror();
167  dol_print_error($db);
168  }
169  $db->free($resql);
170  unset($_POST['fourn' . $i]);
171  }
172  unset($_POST[$i]);
173  }
174 
175  //we now know how many orders we need and what lines they have
176  $i = 0;
177  $orders = array();
178  $suppliersid = array_keys($suppliers);
179  foreach ($suppliers as $supplier)
180  {
181  $order = new CommandeFournisseur($db);
182  // Check if an order for the supplier exists
183  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."commande_fournisseur";
184  $sql.= " WHERE fk_soc = ".$suppliersid[$i];
185  $sql.= " AND source = 42 AND fk_statut = 0";
186  $sql.= " ORDER BY date_creation DESC";
187  $resql = $db->query($sql);
188  if($resql && $db->num_rows($resql) > 0) {
189  $obj = $db->fetch_object($resql);
190  $order->fetch($obj->rowid);
191  foreach ($supplier['lines'] as $line) {
192  $result = $order->addline(
193  $line->desc,
194  $line->subprice,
195  $line->qty,
196  $line->tva_tx,
197  $line->localtax1_tx,
198  $line->localtax2_tx,
199  $line->fk_product,
200  0,
201  $line->ref_fourn,
202  $line->remise_percent,
203  'HT',
204  0,
205  $line->info_bits
206  );
207  }
208  if ($result < 0) {
209  $fail++;
210  $msg = $langs->trans('OrderFail') . "&nbsp;:&nbsp;";
211  $msg .= $order->error;
212  setEventMessages($msg, null, 'errors');
213  } else {
214  $id = $result;
215  }
216  } else {
217  $order->socid = $suppliersid[$i];
218  $order->fetch_thirdparty();
219  //trick to know which orders have been generated this way
220  $order->source = 42;
221  foreach ($supplier['lines'] as $line) {
222  $order->lines[] = $line;
223  }
224  $order->cond_reglement_id = $order->thirdparty->cond_reglement_supplier_id;
225  $order->mode_reglement_id = $order->thirdparty->mode_reglement_supplier_id;
226  $id = $order->create($user);
227  if ($id < 0) {
228  $fail++;
229  $msg = $langs->trans('OrderFail') . "&nbsp;:&nbsp;";
230  $msg .= $order->error;
231  setEventMessages($msg, null, 'errors');
232  }
233  $i++;
234  }
235  }
236 
237  if (! $fail && $id)
238  {
239  $db->commit();
240 
241  setEventMessages($langs->trans('OrderCreated'), null, 'mesgs');
242  header('Location: replenishorders.php');
243  exit;
244  }
245  else
246  {
247  $db->rollback();
248  }
249  }
250  if ($box == 0)
251  {
252  setEventMessages($langs->trans('SelectProductWithNotNullQty'), null, 'warnings');
253  }
254 }
255 
256 
257 /*
258  * View
259  */
260 
261 $form = new Form($db);
262 $formproduct = new FormProduct($db);
263 $prod = new Product($db);
264 
265 $title = $langs->trans('Status');
266 
267 if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
268  $sqldesiredtock=$db->ifsql("pse.desiredstock IS NULL", "p.desiredstock", "pse.desiredstock");
269  $sqlalertstock=$db->ifsql("pse.seuil_stock_alerte IS NULL", "p.seuil_stock_alerte", "pse.seuil_stock_alerte");
270 } else {
271  $sqldesiredtock='p.desiredstock';
272  $sqlalertstock='p.seuil_stock_alerte';
273 }
274 
275 
276 $sql = 'SELECT p.rowid, p.ref, p.label, p.description, p.price,';
277 $sql.= ' p.price_ttc, p.price_base_type,p.fk_product_type,';
278 $sql.= ' p.tms as datem, p.duration, p.tobuy';
279 $sql.= ' ,p.desiredstock,p.seuil_stock_alerte';
280 if(!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
281  $sql.= ', pse.desiredstock' ;
282  $sql.= ', pse.seuil_stock_alerte' ;
283 }
284 $sql.= ' ,'.$sqldesiredtock.' as desiredstock, '.$sqlalertstock.' as alertstock,';
285 
286 $sql.= ' SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").') as stock_physique';
287 $sql.= ' FROM ' . MAIN_DB_PREFIX . 'product as p';
288 $sql.= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product_stock as s';
289 $sql.= ' ON p.rowid = s.fk_product';
290 if($fk_supplier > 0) {
291  $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price pfp ON (pfp.fk_product = p.rowid AND pfp.fk_soc = '.$fk_supplier.')';
292 }
293 if(!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
294  $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_warehouse_properties AS pse ON (p.rowid = pse.fk_product AND pse.fk_entrepot = '.$fk_entrepot.')';
295 }
296 $sql.= ' WHERE p.entity IN (' . getEntity('product') . ')';
297 if ($sall) $sql .= natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall);
298 // if the type is not 1, we show all products (type = 0,2,3)
299 if (dol_strlen($type)) {
300  if ($type == 1) {
301  $sql .= ' AND p.fk_product_type = 1';
302  } else {
303  $sql .= ' AND p.fk_product_type <> 1';
304  }
305 }
306 if ($sref) $sql.=natural_search('p.ref', $sref);
307 if ($snom) $sql.=natural_search('p.label', $snom);
308 $sql.= ' AND p.tobuy = 1';
309 if (!empty($canvas)) $sql .= ' AND p.canvas = "' . $db->escape($canvas) . '"';
310 $sql.= ' GROUP BY p.rowid, p.ref, p.label, p.description, p.price';
311 $sql.= ', p.price_ttc, p.price_base_type,p.fk_product_type, p.tms';
312 $sql.= ', p.duration, p.tobuy';
313 $sql.= ', p.desiredstock';
314 $sql.= ', p.seuil_stock_alerte';
315 if(!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
316  $sql.= ', pse.desiredstock' ;
317  $sql.= ', pse.seuil_stock_alerte' ;
318 }
319 $sql.= ', s.fk_product';
320 
321 if ($usevirtualstock)
322 {
323  $sqlCommandesCli = "(SELECT ".$db->ifsql("SUM(cd.qty) IS NULL", "0", "SUM(cd.qty)")." as qty";
324  $sqlCommandesCli.= " FROM ".MAIN_DB_PREFIX."commandedet as cd";
325  $sqlCommandesCli.= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON (c.rowid = cd.fk_commande)";
326  $sqlCommandesCli.= " WHERE c.entity IN (".getEntity('commande').")";
327  $sqlCommandesCli.= " AND cd.fk_product = p.rowid";
328  $sqlCommandesCli.= " AND c.fk_statut IN (1,2))";
329 
330  $sqlExpeditionsCli = "(SELECT ".$db->ifsql("SUM(ed.qty) IS NULL", "0", "SUM(ed.qty)")." as qty";
331  $sqlExpeditionsCli.= " FROM ".MAIN_DB_PREFIX."expedition as e";
332  $sqlExpeditionsCli.= " LEFT JOIN ".MAIN_DB_PREFIX."expeditiondet as ed ON (ed.fk_expedition = e.rowid)";
333  $sqlExpeditionsCli.= " LEFT JOIN ".MAIN_DB_PREFIX."commandedet as cd ON (cd.rowid = ed.fk_origin_line)";
334  $sqlExpeditionsCli.= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON (c.rowid = cd.fk_commande)";
335  $sqlExpeditionsCli.= " WHERE e.entity IN (".getEntity('expedition').")";
336  $sqlExpeditionsCli.= " AND cd.fk_product = p.rowid";
337  $sqlExpeditionsCli.= " AND c.fk_statut IN (1,2))";
338 
339  $sqlCommandesFourn = "(SELECT ".$db->ifsql("SUM(cd.qty) IS NULL", "0", "SUM(cd.qty)")." as qty";
340  $sqlCommandesFourn.= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as cd";
341  $sqlCommandesFourn.= ", ".MAIN_DB_PREFIX."commande_fournisseur as c";
342  $sqlCommandesFourn.= " WHERE c.rowid = cd.fk_commande";
343  $sqlCommandesFourn.= " AND c.entity IN (".getEntity('supplier_order').")";
344  $sqlCommandesFourn.= " AND cd.fk_product = p.rowid";
345  $sqlCommandesFourn.= " AND c.fk_statut IN (3,4))";
346 
347  $sqlReceptionFourn = "(SELECT ".$db->ifsql("SUM(fd.qty) IS NULL", "0", "SUM(fd.qty)")." as qty";
348  $sqlReceptionFourn.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf";
349  $sqlReceptionFourn.= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as fd ON (fd.fk_commande = cf.rowid)";
350  $sqlReceptionFourn.= " WHERE cf.entity IN (".getEntity('supplier_order').")";
351  $sqlReceptionFourn.= " AND fd.fk_product = p.rowid";
352  $sqlReceptionFourn.= " AND cf.fk_statut IN (3,4))";
353 
354  $sql.= ' HAVING ((('.$db->ifsql($sqldesiredtock." IS NULL", "0", $sqldesiredtock).' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')';
355  $sql.= ' - ('.$sqlCommandesCli.' - '.$sqlExpeditionsCli.') + ('.$sqlCommandesFourn.' - '.$sqlReceptionFourn.')))';
356  $sql.= ' OR ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')';
357  $sql.= ' - ('.$sqlCommandesCli.' - '.$sqlExpeditionsCli.') + ('.$sqlCommandesFourn.' - '.$sqlReceptionFourn.'))))';
358 
359  if ($salert == 'on') // Option to see when stock is lower than alert
360  {
361  $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')';
362  $sql.= ' - ('.$sqlCommandesCli.' - '.$sqlExpeditionsCli.') + ('.$sqlCommandesFourn.' - '.$sqlReceptionFourn.')))';
363  $alertchecked = 'checked';
364  }
365 } else {
366  $sql.= ' HAVING (('.$sqldesiredtock.' >= 0 AND ('.$sqldesiredtock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))';
367  $sql.= ' OR ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").'))))';
368 
369  if ($salert == 'on') // Option to see when stock is lower than alert
370  {
371  $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))';
372  $alertchecked = 'checked';
373  }
374 }
375 
376 $sql.= $db->order($sortfield,$sortorder);
377 $sql.= $db->plimit($limit + 1, $offset);
378 
379 //print $sql;
380 $resql = $db->query($sql);
381 if (empty($resql))
382 {
383  dol_print_error($db);
384  exit;
385 }
386 //print $sql;
387 
388 $num = $db->num_rows($resql);
389 $i = 0;
390 
391 $helpurl = 'EN:Module_Stocks_En|FR:Module_Stock|';
392 $helpurl .= 'ES:M&oacute;dulo_Stocks';
393 
394 llxHeader('', $title, $helpurl, '');
395 
396 $head = array();
397 $head[0][0] = DOL_URL_ROOT.'/product/stock/replenish.php';
398 $head[0][1] = $title;
399 $head[0][2] = 'replenish';
400 $head[1][0] = DOL_URL_ROOT.'/product/stock/replenishorders.php';
401 $head[1][1] = $langs->trans("ReplenishmentOrders");
402 $head[1][2] = 'replenishorders';
403 
404 
405 print load_fiche_titre($langs->trans('Replenishment'), '', 'title_generic.png');
406 
407 dol_fiche_head($head, 'replenish', '', -1, '');
408 
409 print $langs->trans("ReplenishmentStatusDesc").'<br>'."\n";
410 if ($usevirtualstock == 1)
411 {
412  print $langs->trans("CurentSelectionMode").': ';
413  print $langs->trans("CurentlyUsingVirtualStock").' - ';
414  print '<a href="'.$_SERVER["PHP_SELF"].'?mode=physical&fk_supplier='.$fk_supplier.'&fk_entrepot='.$fk_entrepot.'">'.$langs->trans("UsePhysicalStock").'</a><br>';
415 }
416 if ($usevirtualstock == 0)
417 {
418  print $langs->trans("CurentSelectionMode").': ';
419  print $langs->trans("CurentlyUsingPhysicalStock").' - ';
420  print '<a href="'.$_SERVER["PHP_SELF"].'?mode=virtual&fk_supplier='.$fk_supplier.'&fk_entrepot='.$fk_entrepot.'">'.$langs->trans("UseVirtualStock").'</a><br>';
421 }
422 print '<br>'."\n";
423 
424 print '<form name="formFilterWarehouse" method="GET" action="">';
425 print '<input type="hidden" name="action" value="filter">';
426 print '<input type="hidden" name="sref" value="'.$sref.'">';
427 print '<input type="hidden" name="snom" value="'.$snom.'">';
428 print '<input type="hidden" name="salert" value="'.$salert.'">';
429 print '<input type="hidden" name="draftorder" value="'.$draftorder.'">';
430 print '<input type="hidden" name="mode" value="'.$mode.'">';
431 if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE))
432 {
433  print '<div class="inline-block valignmiddle" style="padding-right: 20px;">';
434  print $langs->trans('Warehouse').' '.$formproduct->selectWarehouses($fk_entrepot, 'fk_entrepot', '', 1);
435  print '</div>';
436 }
437 print '<div class="inline-block valignmiddle" style="padding-right: 20px;">';
438 print $langs->trans('Supplier').' '.$form->select_company($fk_supplier, 'fk_supplier', 'fournisseur=1', 1);
439 print '</div>';
440 print '<div class="inline-block valignmiddle">';
441 print '<input class="button" type="submit" name="valid" value="'.$langs->trans('ToFilter').'">';
442 print '</div>';
443 print '</form>';
444 
445 if ($sref || $snom || $sall || $salert || $draftorder || GETPOST('search', 'alpha')) {
446  $filters = '&sref=' . $sref . '&snom=' . $snom;
447  $filters .= '&sall=' . $sall;
448  $filters .= '&salert=' . $salert;
449  $filters .= '&draftorder=' . $draftorder;
450  $filters .= '&mode=' . $mode;
451  $filters .= '&fk_supplier=' . $fk_supplier;
452  $filters .= '&fk_entrepot=' . $fk_entrepot;
454  $texte,
455  $page,
456  'replenish.php',
457  $filters,
458  $sortfield,
459  $sortorder,
460  '',
461  $num
462  );
463 } else {
464  $filters = '&sref=' . $sref . '&snom=' . $snom;
465  $filters .= '&fourn_id=' . $fourn_id;
466  $filters .= (isset($type)?'&type=' . $type:'');
467  $filters .= '&=' . $salert;
468  $filters .= '&draftorder=' . $draftorder;
469  $filters .= '&mode=' . $mode;
470  $filters .= '&fk_supplier=' . $fk_supplier;
471  $filters .= '&fk_entrepot=' . $fk_entrepot;
473  $texte,
474  $page,
475  'replenish.php',
476  $filters,
477  $sortfield,
478  $sortorder,
479  '',
480  $num
481  );
482 }
483 
484 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
485 print '<table class="liste" width="100%">';
486 
487 $param = (isset($type)? '&type=' . $type : '');
488 $param .= '&fourn_id=' . $fourn_id . '&snom='. $snom . '&salert=' . $salert . '&draftorder='.$draftorder;
489 $param .= '&sref=' . $sref;
490 $param .= '&mode=' . $mode;
491 $param .= '&fk_supplier=' . $fk_supplier;
492 $param .= '&fk_entrepot=' . $fk_entrepot;
493 
494 $stocklabel = $langs->trans('Stock');
495 if ($usevirtualstock == 1) $stocklabel = 'VirtualStock';
496 if ($usevirtualstock == 0) $stocklabel = 'PhysicalStock';
497 
498 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">'.
499  '<input type="hidden" name="token" value="' .$_SESSION['newtoken'] . '">'.
500  '<input type="hidden" name="fk_supplier" value="' . $fk_supplier . '">'.
501  '<input type="hidden" name="fk_entrepot" value="' .$fk_entrepot . '">'.
502  '<input type="hidden" name="sortfield" value="' . $sortfield . '">'.
503  '<input type="hidden" name="sortorder" value="' . $sortorder . '">'.
504  '<input type="hidden" name="type" value="' . $type . '">'.
505  '<input type="hidden" name="linecount" value="' . $num . '">'.
506  '<input type="hidden" name="action" value="order">'.
507  '<input type="hidden" name="mode" value="' . $mode . '">';
508 
509 // Lignes des champs de filtre
510 print '<tr class="liste_titre_filter">';
511 print '<td class="liste_titre">&nbsp;</td>';
512 print '<td class="liste_titre"><input class="flat" type="text" name="sref" size="8" value="'.dol_escape_htmltag($sref).'"></td>';
513 print '<td class="liste_titre"><input class="flat" type="text" name="snom" size="8" value="'.dol_escape_htmltag($snom).'"></td>';
514 if (!empty($conf->service->enabled) && $type == 1) print '<td class="liste_titre">&nbsp;</td>';
515 print '<td class="liste_titre">&nbsp;</td>';
516 print '<td class="liste_titre" align="right">&nbsp;</td>';
517 print '<td class="liste_titre" align="right">' . $langs->trans('AlertOnly') . '&nbsp;<input type="checkbox" id="salert" name="salert" ' . (!empty($alertchecked)?$alertchecked:'') . '></td>';
518 print '<td class="liste_titre" align="right">' . $langs->trans('Draft') . '&nbsp;<input type="checkbox" id="draftorder" name="draftorder" ' . (!empty($draftchecked)?$draftchecked:'') . '></td>';
519 print '<td class="liste_titre">&nbsp;</td>';
520 print '<td class="liste_titre" align="right">';
521 $searchpicto=$form->showFilterAndCheckAddButtons(0);
522 print $searchpicto;
523 print '</td>';
524 print '</tr>';
525 
526 // Lines of title
527 print '<tr class="liste_titre">';
528 print_liste_field_titre('<input type="checkbox" onClick="toggle(this)" />', $_SERVER["PHP_SELF"], '');
529 print_liste_field_titre('Ref', $_SERVER["PHP_SELF"], 'p.ref', $param, '', '', $sortfield, $sortorder);
530 print_liste_field_titre('Label', $_SERVER["PHP_SELF"], 'p.label', $param, '', '', $sortfield, $sortorder);
531 if (!empty($conf->service->enabled) && $type == 1) print_liste_field_titre('Duration', $_SERVER["PHP_SELF"], 'p.duration', $param, '', 'align="center"', $sortfield, $sortorder);
532 print_liste_field_titre('DesiredStock', $_SERVER["PHP_SELF"], 'p.desiredstock', $param, '', 'align="right"', $sortfield, $sortorder);
533 print_liste_field_titre('StockLimitShort', $_SERVER["PHP_SELF"], 'p.seuil_stock_alerte', $param, '', 'align="right"', $sortfield, $sortorder);
534 print_liste_field_titre($stocklabel, $_SERVER["PHP_SELF"], 'stock_physique', $param, '', 'align="right"', $sortfield, $sortorder);
535 print_liste_field_titre('Ordered', $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder);
536 print_liste_field_titre('StockToBuy', $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder);
537 print_liste_field_titre('SupplierRef', $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder);
538 print "</tr>\n";
539 
540 while ($i < ($limit ? min($num, $limit) : $num))
541 {
542  $objp = $db->fetch_object($resql);
543 
544  if (! empty($conf->global->STOCK_SUPPORTS_SERVICES) || $objp->fk_product_type == 0)
545  {
546  $prod->fetch($objp->rowid);
547  $prod->load_stock('warehouseopen, warehouseinternal');
548 
549  // Multilangs
550  if (! empty($conf->global->MAIN_MULTILANGS))
551  {
552  $sql = 'SELECT label,description';
553  $sql .= ' FROM ' . MAIN_DB_PREFIX . 'product_lang';
554  $sql .= ' WHERE fk_product = ' . $objp->rowid;
555  $sql .= ' AND lang = "' . $langs->getDefaultLang() . '"';
556  $sql .= ' LIMIT 1';
557 
558  $resqlm = $db->query($sql);
559  if ($resqlm)
560  {
561  $objtp = $db->fetch_object($resqlm);
562  if (!empty($objtp->description)) $objp->description = $objtp->description;
563  if (!empty($objtp->label)) $objp->label = $objtp->label;
564  }
565  }
566 
567  if ($usevirtualstock)
568  {
569  // If option to increase/decrease is not on an object validation, virtual stock may differs from physical stock.
570  $stock = $prod->stock_theorique;
571  }
572  else
573  {
574  $stock = $prod->stock_reel;
575  }
576 
577  // Force call prod->load_stats_xxx to choose status to count (otherwise it is loaded by load_stock function)
578  if(isset($draftchecked)){
579  $result=$prod->load_stats_commande_fournisseur(0,'0,1,2,3,4');
580  }else {
581  $result=$prod->load_stats_commande_fournisseur(0,'1,2,3,4');
582  }
583 
584  $result=$prod->load_stats_reception(0,'4');
585 
586  //print $prod->stats_commande_fournisseur['qty'].'<br>'."\n";
587  //print $prod->stats_reception['qty'];
588  $ordered = $prod->stats_commande_fournisseur['qty'] - $prod->stats_reception['qty'];
589 
590  $warning='';
591  if ($objp->alertstock && ($stock < $objp->alertstock))
592  {
593  $warning = img_warning($langs->trans('StockTooLow')) . ' ';
594  }
595 
596  //depending on conf, use either physical stock or
597  //virtual stock to compute the stock to buy value
598  $stocktobuy = max(max($objp->desiredstock, $objp->alertstock) - $stock - $ordered, 0);
599  $disabled = '';
600  if ($ordered > 0)
601  {
602  $stockforcompare = $usevirtualstock ? $stock : $stock + $ordered;
603  if ($stockforcompare >= $objp->desiredstock)
604  {
605  $picto = img_picto('', './img/yes', '', 1);
606  $disabled = 'disabled';
607  }
608  else {
609  $picto = img_picto('', './img/no', '', 1);
610  }
611  } else {
612  //$picto = img_help('',$langs->trans("NoPendingReceptionOnSupplierOrder"));
613  $picto = img_picto($langs->trans("NoPendingReceptionOnSupplierOrder"), './img/no', '', 1);
614  }
615 
616  print '<tr class="oddeven">';
617 
618  // Select field
619  //print '<td><input type="checkbox" class="check" name="' . $i . '"' . $disabled . '></td>';
620  print '<td><input type="checkbox" class="check" name="choose'.$i.'"></td>';
621 
622  print '<td class="nowrap">'.$prod->getNomUrl(1, '').'</td>';
623 
624  print '<td>'.$objp->label ;
625  print '<input type="hidden" name="desc' . $i . '" value="' . dol_escape_htmltag($objp->description) . '">'; // TODO Remove this and make a fetch to get description when creating order instead of a GETPOST
626  print '</td>';
627 
628  if (!empty($conf->service->enabled) && $type == 1)
629  {
630  if (preg_match('/([0-9]+)y/i', $objp->duration, $regs)) {
631  $duration = $regs[1] . ' ' . $langs->trans('DurationYear');
632  } elseif (preg_match('/([0-9]+)m/i', $objp->duration, $regs)) {
633  $duration = $regs[1] . ' ' . $langs->trans('DurationMonth');
634  } elseif (preg_match('/([0-9]+)d/i', $objp->duration, $regs)) {
635  $duration = $regs[1] . ' ' . $langs->trans('DurationDay');
636  } else {
637  $duration = $objp->duration;
638  }
639  print '<td align="center">'.$duration.'</td>';
640  }
641 
642  // Desired stock
643  print '<td align="right">' . $objp->desiredstock . '</td>';
644 
645  // Limit stock for alerr
646  print '<td align="right">' . $objp->alertstock . '</td>';
647 
648  // Current stock
649  print '<td align="right">'. $warning . $stock. '</td>';
650 
651  // Already ordered
652  print '<td align="right"><a href="replenishorders.php?sproduct=' . $prod->id . '">'. $ordered . '</a> ' . $picto. '</td>';
653 
654  // To order
655  //print '<td align="right"><input type="text" name="tobuy'.$i.'" value="'.$stocktobuy.'" '.$disabled.'></td>';
656  print '<td align="right"><input type="text" size="4" name="tobuy'.$i.'" value="'.$stocktobuy.'"></td>';
657 
658  // Supplier
659  print '<td align="right">'. $form->select_product_fourn_price($prod->id, 'fourn'.$i, $fk_supplier).'</td>';
660 
661  print '</tr>';
662  }
663  $i++;
664 }
665 print '</table>';
666 print '</div>';
667 
668 $db->free($resql);
669 
670 dol_fiche_end();
671 
672 
673 $value=$langs->trans("CreateOrders");
674 print '<div class="center"><input class="button" type="submit" name="valid" value="'.$value.'"></div>';
675 
676 
677 print '</form>';
678 
679 
680 // TODO Replace this with jquery
681 print '
682 <script type="text/javascript">
683 function toggle(source)
684 {
685  checkboxes = document.getElementsByClassName("check");
686  for (var i=0; i < checkboxes.length;i++) {
687  if (!checkboxes[i].disabled) {
688  checkboxes[i].checked = source.checked;
689  }
690  }
691 }
692 </script>';
693 
694 
695 llxFooter();
696 
697 $db->close();
llxFooter()
Empty footer.
Definition: wrapper.php:58
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it's its name (generic function)
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='')
Show tab header of a card.
Class to manage products or services.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
if(empty($reshook)) $form
View.
Definition: perms.php:103
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NULL, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage generation of HTML components Only common components must be here.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='title_generic.png', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0)
Print a title with navigation controls for pagination.
img_warning($titlealt= 'default', $moreatt= '')
Show warning logo.
if($_POST["cancel"]==$langs->trans("Cancel")&&!$id) if($action== 'setdatev'&&$user->rights->tax->charges->creer) if($action== 'add'&&$_POST["cancel"]<> $langs->trans("Cancel")) if($action== 'delete') $title
Actions.
Definition: card.php:183
dol_fiche_end($notab=0)
Show tab footer of a card.
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id=0, $morecssontable='', $morehtmlcenter='')
Load a title with picto.
llxHeader()
Empty header.
Definition: wrapper.php:46
getEntity($element, $shared=1, $forceentity=null)
Get list of entity id to use.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
Class to manage predefined suppliers products.
print
Draft customers invoices.
Definition: index.php:91
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->societe->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1013
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="")
Show title line of an array.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $objcanvas=null)
Check permissions of a user to show a page and an object.
Class to manage line orders.