dolibarr  9.0.0
dispatch.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
5  * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
6  * Copyright (C) 2010 Juanjo Menent <jmenent@2byte.es>
7  * Copyright (C) 2014 Cedric Gross <c.gross@kreiz-it.fr>
8  * Copyright (C) 2016 Florian Henry <florian.henry@atm-consulting.fr>
9  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
10  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program. If not, see <http://www.gnu.org/licenses/>.
24  * or see http://www.gnu.org/
25  */
26 
33 require '../../main.inc.php';
34 require_once DOL_DOCUMENT_ROOT . '/core/modules/supplier_order/modules_commandefournisseur.php';
35 require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
36 require_once DOL_DOCUMENT_ROOT . '/core/lib/fourn.lib.php';
37 require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.class.php';
38 require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.dispatch.class.php';
39 require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
40 if (! empty($conf->projet->enabled))
41  require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
42 
43 // Load translation files required by the page
44 $langs->loadLangs(array("bills", "orders", "sendings", "companies", "deliveries", "products", "stocks"));
45 
46 if (! empty($conf->productbatch->enabled))
47  $langs->load('productbatch');
48 
49  // Security check
50 $id = GETPOST("id", 'int');
51 $ref = GETPOST('ref');
52 $lineid = GETPOST('lineid', 'int');
53 $action = GETPOST('action','aZ09');
54 if ($user->societe_id)
55  $socid = $user->societe_id;
56 $result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande');
57 
58 if (empty($conf->stock->enabled)) {
60 }
61 
62 $hookmanager->initHooks(array('ordersupplierdispatch'));
63 
64 // Recuperation de l'id de projet
65 $projectid = 0;
66 if ($_GET["projectid"])
67  $projectid = GETPOST("projectid", 'int');
68 
69 $object = new CommandeFournisseur($db);
70 
71 if ($id > 0 || ! empty($ref)) {
72  $result = $object->fetch($id, $ref);
73  if ($result < 0) {
74  setEventMessages($object->error, $object->errors, 'errors');
75  }
76  $result = $object->fetch_thirdparty();
77  if ($result < 0) {
78  setEventMessages($object->error, $object->errors, 'errors');
79  }
80 }
81 
82 
83 /*
84  * Actions
85  */
86 
87 $parameters=array();
88 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
89 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
90 
91 if ($action == 'checkdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check))))
92 {
93  $error=0;
94  $supplierorderdispatch = new CommandeFournisseurDispatch($db);
95 
96  $db->begin();
97 
98  $result = $supplierorderdispatch->fetch($lineid);
99  if (! $result)
100  {
101  $error++;
102  setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
103  $action = '';
104  }
105 
106  if (! $error)
107  {
108  $result = $supplierorderdispatch->setStatut(1);
109  if ($result < 0) {
110  setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
111  $error++;
112  $action = '';
113  }
114  }
115 
116  if (! $error)
117  {
118  $result = $object->calcAndSetStatusDispatch($user);
119  if ($result < 0) {
120  setEventMessages($object->error, $object->errors, 'errors');
121  $error ++;
122  $action = '';
123  }
124  }
125  if (! $error)
126  {
127  $db->commit();
128  }
129  else
130  {
131  $db->rollback();
132  }
133 }
134 
135 if ($action == 'uncheckdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check))))
136 {
137  $error=0;
138  $supplierorderdispatch = new CommandeFournisseurDispatch($db);
139 
140  $db->begin();
141 
142  $result = $supplierorderdispatch->fetch($lineid);
143  if (! $result)
144  {
145  $error++;
146  setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
147  $action = '';
148  }
149 
150  if (! $error)
151  {
152  $result = $supplierorderdispatch->setStatut(0);
153  if ($result < 0) {
154  setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
155  $error ++;
156  $action = '';
157  }
158  }
159  if (! $error)
160  {
161  $result = $object->calcAndSetStatusDispatch($user);
162  if ($result < 0) {
163  setEventMessages($object->error, $object->errors, 'errors');
164  $error ++;
165  $action = '';
166  }
167  }
168  if (! $error)
169  {
170  $db->commit();
171  }
172  else
173  {
174  $db->rollback();
175  }
176 }
177 
178 if ($action == 'denydispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check))))
179 {
180  $error=0;
181  $supplierorderdispatch = new CommandeFournisseurDispatch($db);
182 
183  $db->begin();
184 
185  $result = $supplierorderdispatch->fetch($lineid);
186  if (! $result)
187  {
188  $error++;
189  setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
190  $action = '';
191  }
192 
193  if (! $error)
194  {
195  $result = $supplierorderdispatch->setStatut(2);
196  if ($result < 0) {
197  setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
198  $error ++;
199  $action = '';
200  }
201  }
202  if (! $error)
203  {
204  $result = $object->calcAndSetStatusDispatch($user);
205  if ($result < 0) {
206  setEventMessages($object->error, $object->errors, 'errors');
207  $error ++;
208  $action = '';
209  }
210  }
211  if (! $error)
212  {
213  $db->commit();
214  }
215  else
216  {
217  $db->rollback();
218  }
219 }
220 
221 if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) {
222  $error = 0;
223 
224  $db->begin();
225 
226  $pos = 0;
227  foreach ($_POST as $key => $value)
228  {
229  // without batch module enabled
230  if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg))
231  {
232  $pos ++;
233 
234  // $numline=$reg[2] + 1; // line of product
235  $numline = $pos;
236  $prod = "product_" . $reg[1] . '_' . $reg[2];
237  $qty = "qty_" . $reg[1] . '_' . $reg[2];
238  $ent = "entrepot_" . $reg[1] . '_' . $reg[2];
239  $pu = "pu_" . $reg[1] . '_' . $reg[2]; // This is unit price including discount
240  $fk_commandefourndet = "fk_commandefourndet_" . $reg[1] . '_' . $reg[2];
241 
242  // We ask to move a qty
243  if (GETPOST($qty) != 0) {
244  if (! (GETPOST($ent, 'int') > 0)) {
245  dol_syslog('No dispatch for line ' . $key . ' as no warehouse choosed');
246  $text = $langs->transnoentities('Warehouse') . ', ' . $langs->transnoentities('Line') . ' ' . ($numline);
247  setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
248  $error ++;
249  }
250 
251  if (! $error) {
252  $result = $object->dispatchProduct($user, GETPOST($prod, 'int'), GETPOST($qty), GETPOST($ent, 'int'), GETPOST($pu), GETPOST('comment'), '', '', '', GETPOST($fk_commandefourndet, 'int'), $notrigger);
253  if ($result < 0) {
254  setEventMessages($object->error, $object->errors, 'errors');
255  $error ++;
256  }
257  }
258  }
259  }
260  // with batch module enabled
261  if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg))
262  {
263  $pos ++;
264 
265  // eat-by date dispatch
266  // $numline=$reg[2] + 1; // line of product
267  $numline = $pos;
268  $prod = 'product_batch_' . $reg[1] . '_' . $reg[2];
269  $qty = 'qty_' . $reg[1] . '_' . $reg[2];
270  $ent = 'entrepot_' . $reg[1] . '_' . $reg[2];
271  $pu = 'pu_' . $reg[1] . '_' . $reg[2];
272  $fk_commandefourndet = 'fk_commandefourndet_' . $reg[1] . '_' . $reg[2];
273  $lot = 'lot_number_' . $reg[1] . '_' . $reg[2];
274  $dDLUO = dol_mktime(12, 0, 0, $_POST['dluo_' . $reg[1] . '_' . $reg[2] . 'month'], $_POST['dluo_' . $reg[1] . '_' . $reg[2] . 'day'], $_POST['dluo_' . $reg[1] . '_' . $reg[2] . 'year']);
275  $dDLC = dol_mktime(12, 0, 0, $_POST['dlc_' . $reg[1] . '_' . $reg[2] . 'month'], $_POST['dlc_' . $reg[1] . '_' . $reg[2] . 'day'], $_POST['dlc_' . $reg[1] . '_' . $reg[2] . 'year']);
276 
277  $fk_commandefourndet = 'fk_commandefourndet_' . $reg[1] . '_' . $reg[2];
278 
279  // We ask to move a qty
280  if (GETPOST($qty) > 0) {
281  if (! (GETPOST($ent, 'int') > 0)) {
282  dol_syslog('No dispatch for line ' . $key . ' as no warehouse choosed');
283  $text = $langs->transnoentities('Warehouse') . ', ' . $langs->transnoentities('Line') . ' ' . ($numline) . '-' . ($reg[1] + 1);
284  setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
285  $error ++;
286  }
287 
288  if (! (GETPOST($lot, 'alpha') || $dDLUO || $dDLC)) {
289  dol_syslog('No dispatch for line ' . $key . ' as serial/eat-by/sellby date are not set');
290  $text = $langs->transnoentities('atleast1batchfield') . ', ' . $langs->transnoentities('Line') . ' ' . ($numline) . '-' . ($reg[1] + 1);
291  setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
292  $error ++;
293  }
294 
295  if (! $error) {
296  $result = $object->dispatchProduct($user, GETPOST($prod, 'int'), GETPOST($qty), GETPOST($ent, 'int'), GETPOST($pu), GETPOST('comment'), $dDLC, $dDLUO, GETPOST($lot, 'alpha'), GETPOST($fk_commandefourndet, 'int'), $notrigger);
297  if ($result < 0) {
298  setEventMessages($object->error, $object->errors, 'errors');
299  $error ++;
300  }
301  }
302  }
303  }
304  }
305 
306  if (! $error) {
307  $result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder')?1:0, GETPOST('comment'));
308  if ($result < 0) {
309  setEventMessages($object->error, $object->errors, 'errors');
310  $error ++;
311  }
312  }
313 
314  if (! $notrigger && ! $error) {
315  global $conf, $langs, $user;
316  // Call trigger
317 
318  $result = $object->call_trigger('ORDER_SUPPLIER_DISPATCH', $user);
319  // End call triggers
320 
321  if ($result < 0) {
322  setEventMessages($object->error, $object->errors, 'errors');
323  $error ++;
324  }
325  }
326 
327  if ($result >= 0 && ! $error) {
328  $db->commit();
329 
330  header("Location: dispatch.php?id=" . $id);
331  exit();
332  } else {
333  $db->rollback();
334  }
335 }
336 
337 
338 /*
339  * View
340  */
341 
342 $now = dol_now();
343 
344 $form = new Form($db);
345 $formproduct = new FormProduct($db);
346 $warehouse_static = new Entrepot($db);
347 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
348 
349 $help_url='EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores';
350 llxHeader('', $langs->trans("Order"), $help_url, '', 0, 0, array('/fourn/js/lib_dispatch.js'));
351 
352 if ($id > 0 || ! empty($ref)) {
353  $soc = new Societe($db);
354  $soc->fetch($object->socid);
355 
356  $author = new User($db);
357  $author->fetch($object->user_author_id);
358 
359  $head = ordersupplier_prepare_head($object);
360 
361  $title = $langs->trans("SupplierOrder");
362  dol_fiche_head($head, 'dispatch', $title, -1, 'order');
363 
364 
365  // Supplier order card
366 
367  $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
368 
369  $morehtmlref='<div class="refidno">';
370  // Ref supplier
371  $morehtmlref.=$form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', 0, 1);
372  $morehtmlref.=$form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', null, null, '', 1);
373  // Thirdparty
374  $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
375  // Project
376  if (! empty($conf->projet->enabled))
377  {
378  $langs->load("projects");
379  $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
380  if ($user->rights->fournisseur->commande->creer)
381  {
382  if ($action != 'classify')
383  //$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
384  $morehtmlref.=' : ';
385  if ($action == 'classify') {
386  //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
387  $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
388  $morehtmlref.='<input type="hidden" name="action" value="classin">';
389  $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
390  $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
391  $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
392  $morehtmlref.='</form>';
393  } else {
394  $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
395  }
396  } else {
397  if (! empty($object->fk_project)) {
398  $proj = new Project($db);
399  $proj->fetch($object->fk_project);
400  $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
401  $morehtmlref.=$proj->ref;
402  $morehtmlref.='</a>';
403  } else {
404  $morehtmlref.='';
405  }
406  }
407  }
408  $morehtmlref.='</div>';
409 
410 
411  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
412 
413 
414  print '<div class="fichecenter">';
415  print '<div class="underbanner clearboth"></div>';
416 
417  print '<table class="border" width="100%">';
418 
419  // Date
420  if ($object->methode_commande_id > 0) {
421  print '<tr><td class="titlefield">' . $langs->trans("Date") . '</td><td>';
422  if ($object->date_commande) {
423  print dol_print_date($object->date_commande, "dayhourtext") . "\n";
424  }
425  print "</td></tr>";
426 
427  if ($object->methode_commande) {
428  print '<tr><td>' . $langs->trans("Method") . '</td><td>' . $object->getInputMethod() . '</td></tr>';
429  }
430  }
431 
432  // Author
433  print '<tr><td class="titlefield">' . $langs->trans("AuthorRequest") . '</td>';
434  print '<td>' . $author->getNomUrl(1, '', 0, 0, 0) . '</td>';
435  print '</tr>';
436 
437  $parameters=array();
438  $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
439 
440  print "</table>";
441 
442  print '</div>';
443 
444  // if ($mesg) print $mesg;
445  print '<br>';
446 
447  $disabled = 1;
448  if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
449  $disabled = 0;
450 
451  // Line of orders
452  if ($object->statut <= CommandeFournisseur::STATUS_ACCEPTED || $object->statut >= CommandeFournisseur::STATUS_CANCELED) {
453  print '<span class="opacitymedium">'.$langs->trans("OrderStatusNotReadyToDispatch").'</span>';
454  }
455 
456  if ($object->statut == CommandeFournisseur::STATUS_ORDERSENT
458  || $object->statut == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) {
459  $entrepot = new Entrepot($db);
460  $listwarehouses = $entrepot->list_array(1);
461 
462  print '<form method="POST" action="dispatch.php?id=' . $object->id . '">';
463  print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
464  print '<input type="hidden" name="action" value="dispatch">';
465 
466  print '<div class="div-table-responsive-no-min">';
467  print '<table class="noborder" width="100%">';
468 
469  // Set $products_dispatched with qty dispatched for each product id
470  $products_dispatched = array();
471  $sql = "SELECT l.rowid, cfd.fk_product, sum(cfd.qty) as qty";
472  $sql .= " FROM " . MAIN_DB_PREFIX . "commande_fournisseur_dispatch as cfd";
473  $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "commande_fournisseurdet as l on l.rowid = cfd.fk_commandefourndet";
474  $sql .= " WHERE cfd.fk_commande = " . $object->id;
475  $sql .= " GROUP BY l.rowid, cfd.fk_product";
476 
477  $resql = $db->query($sql);
478  if ($resql) {
479  $num = $db->num_rows($resql);
480  $i = 0;
481 
482  if ($num) {
483  while ( $i < $num ) {
484  $objd = $db->fetch_object($resql);
485  $products_dispatched[$objd->rowid] = price2num($objd->qty, 5);
486  $i++;
487  }
488  }
489  $db->free($resql);
490  }
491 
492  $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,";
493  $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse";
494  $sql .= " FROM " . MAIN_DB_PREFIX . "commande_fournisseurdet as l";
495  $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON l.fk_product=p.rowid";
496  $sql .= " WHERE l.fk_commande = " . $object->id;
497  if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
498  $sql .= " AND l.product_type = 0";
499  $sql .= " GROUP BY p.ref, p.label, p.tobatch, l.rowid, l.fk_product, l.subprice, l.remise_percent"; // Calculation of amount dispatched is done per fk_product so we must group by fk_product
500  $sql .= " ORDER BY p.ref, p.label";
501 
502  $resql = $db->query($sql);
503  if ($resql) {
504  $num = $db->num_rows($resql);
505  $i = 0;
506 
507  if ($num) {
508  print '<tr class="liste_titre">';
509 
510  print '<td>' . $langs->trans("Description") . '</td>';
511  if (! empty($conf->productbatch->enabled))
512  {
513  print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
514  print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
515  print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
516  }
517  else
518  {
519  print '<td></td>';
520  print '<td></td>';
521  print '<td></td>';
522  }
523  print '<td align="right">' . $langs->trans("SupplierRef") . '</td>';
524  print '<td align="right">' . $langs->trans("QtyOrdered") . '</td>';
525  print '<td align="right">' . $langs->trans("QtyDispatchedShort") . '</td>';
526  print '<td align="right">' . $langs->trans("QtyToDispatchShort") . '</td>';
527  print '<td width="32"></td>';
528  print '<td align="right">' . $langs->trans("Warehouse") . '</td>';
529  print "</tr>\n";
530  }
531 
532  $nbfreeproduct = 0; // Nb of lins of free products/services
533  $nbproduct = 0; // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default)
534  // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on.
535 
536  while ( $i < $num ) {
537  $objp = $db->fetch_object($resql);
538 
539  // On n'affiche pas les produits libres
540  if (! $objp->fk_product > 0) {
541  $nbfreeproduct++;
542  } else {
543  $remaintodispatch = price2num($objp->qty - (( float ) $products_dispatched[$objp->rowid]), 5); // Calculation of dispatched
544  if ($remaintodispatch < 0)
545  $remaintodispatch = 0;
546 
547  if ($remaintodispatch || empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) {
548  $nbproduct++;
549 
550  // To show detail cref and description value, we must make calculation by cref
551  // print ($objp->cref?' ('.$objp->cref.')':'');
552  // if ($objp->description) print '<br>'.nl2br($objp->description);
553  $suffix = '_0_' . $i;
554 
555  print "\n";
556  print '<!-- Line to dispatch ' . $suffix . ' -->' . "\n";
557  // hidden fields for js function
558  print '<input id="qty_ordered' . $suffix . '" type="hidden" value="' . $objp->qty . '">';
559  print '<input id="qty_dispatched' . $suffix . '" type="hidden" value="' . ( float ) $products_dispatched[$objp->rowid] . '">';
560  print '<tr class="oddeven">';
561 
562  $linktoprod = '<a href="' . DOL_URL_ROOT . '/product/fournisseurs.php?id=' . $objp->fk_product . '">' . img_object($langs->trans("ShowProduct"), 'product') . ' ' . $objp->ref . '</a>';
563  $linktoprod .= ' - ' . $objp->label . "\n";
564 
565  if (! empty($conf->productbatch->enabled)) {
566  if ($objp->tobatch) {
567  print '<td>';
568  print $linktoprod;
569  print "</td>";
570  print '<td class="dispatch_batch_number"></td>';
571  print '<td class="dispatch_dluo"></td>';
572  print '<td class="dispatch_dlc"></td>';
573  } else {
574  print '<td>';
575  print $linktoprod;
576  print "</td>";
577  print '<td class="dispatch_batch_number">';
578  print $langs->trans("ProductDoesNotUseBatchSerial");
579  print '</td>';
580  print '<td class="dispatch_dluo"></td>';
581  print '<td class="dispatch_dlc"></td>';
582  }
583  } else {
584  print '<td colspan="4">';
585  print $linktoprod;
586  print "</td>";
587  }
588 
589  // Define unit price for PMP calculation
590  $up_ht_disc = $objp->subprice;
591  if (! empty($objp->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP))
592  $up_ht_disc = price2num($up_ht_disc * (100 - $objp->remise_percent) / 100, 'MU');
593 
594  // Supplier ref
595  print '<td align="right">'.$objp->sref.'</td>';
596 
597  // Qty ordered
598  print '<td align="right">' . $objp->qty . '</td>';
599 
600  // Already dispatched
601  print '<td align="right">' . $products_dispatched[$objp->rowid] . '</td>';
602 
603  if (! empty($conf->productbatch->enabled) && $objp->tobatch == 1) {
604  $type = 'batch';
605  print '<td align="right">';
606  print '</td>'; // Qty to dispatch
607  print '<td>';
608  //print img_picto($langs->trans('AddDispatchBatchLine'), 'split.png', 'onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
609  print '</td>'; // Dispatch column
610  print '<td></td>'; // Warehouse column
611  print '</tr>';
612 
613  print '<tr class="oddeven" name="' . $type . $suffix . '">';
614  print '<td>';
615  print '<input name="fk_commandefourndet' . $suffix . '" type="hidden" value="' . $objp->rowid . '">';
616  print '<input name="product_batch' . $suffix . '" type="hidden" value="' . $objp->fk_product . '">';
617 
618  print '<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
619  if (! empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) // Not tested !
620  {
621  print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu' . $suffix . '" type="text" value="' . price2num($up_ht_disc, 'MU') . '">';
622  }
623  else
624  {
625  print '<input class="maxwidth75" name="pu' . $suffix . '" type="hidden" value="' . price2num($up_ht_disc, 'MU') . '">';
626  }
627 
628  print '</td>';
629 
630  print '<td>';
631  print '<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number' . $suffix . '" name="lot_number' . $suffix . '" value="' . GETPOST('lot_number' . $suffix) . '">';
632  print '</td>';
633  print '<td class="nowraponall">';
634  $dlcdatesuffix = dol_mktime(0, 0, 0, GETPOST('dlc' . $suffix . 'month'), GETPOST('dlc' . $suffix . 'day'), GETPOST('dlc' . $suffix . 'year'));
635  print $form->selectDate($dlcdatesuffix, 'dlc' . $suffix, '', '', 1, '');
636  print '</td>';
637  print '<td class="nowraponall">';
638  $dluodatesuffix = dol_mktime(0, 0, 0, GETPOST('dluo' . $suffix . 'month'), GETPOST('dluo' . $suffix . 'day'), GETPOST('dluo' . $suffix . 'year'));
639  print $form->selectDate($dluodatesuffix, 'dluo' . $suffix, '', '', 1, '');
640  print '</td>';
641  print '<td colspan="3">&nbsp</td>'; // Supplier ref + Qty ordered + qty already dispatched
642  } else {
643 
644  $type = 'dispatch';
645  print '<td align="right">';
646  print '</td>'; // Qty to dispatch
647  print '<td>';
648  //print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
649  print '</td>'; // Dispatch column
650  print '<td></td>'; // Warehouse column
651  print '</tr>';
652 
653  print '<tr class="oddeven" name="' . $type . $suffix . '">';
654  print '<td colspan="7">';
655  print '<input name="fk_commandefourndet' . $suffix . '" type="hidden" value="' . $objp->rowid . '">';
656  print '<input name="product' . $suffix . '" type="hidden" value="' . $objp->fk_product . '">';
657 
658  print '<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
659  if (! empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) // Not tested !
660  {
661  print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu' . $suffix . '" type="text" value="' . price2num($up_ht_disc, 'MU') . '">';
662  }
663  else
664  {
665  print '<input class="maxwidth75" name="pu' . $suffix . '" type="hidden" value="' . price2num($up_ht_disc, 'MU') . '">';
666  }
667 
668  print '</td>';
669  }
670 
671  // Qty to dispatch
672  print '<td align="right">';
673  print '<input id="qty' . $suffix . '" name="qty' . $suffix . '" type="text" class="width50 right" value="' . (GETPOST('qty' . $suffix) != '' ? GETPOST('qty' . $suffix) : $remaintodispatch) . '">';
674  print '</td>';
675 
676  print '<td>';
677  if (! empty($conf->productbatch->enabled) && $objp->tobatch == 1) {
678  $type = 'batch';
679  //print img_picto($langs->trans('AddDispatchBatchLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
680  print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
681  }
682  else
683  {
684  $type = 'dispatch';
685  print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
686  }
687 
688  print '</td>';
689 
690  // Warehouse
691  print '<td align="right">';
692  if (count($listwarehouses) > 1) {
693  print $formproduct->selectWarehouses(GETPOST("entrepot" . $suffix)?GETPOST("entrepot" . $suffix):($objp->fk_default_warehouse?$objp->fk_default_warehouse:''), "entrepot" . $suffix, '', 1, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix);
694  } elseif (count($listwarehouses) == 1) {
695  print $formproduct->selectWarehouses(GETPOST("entrepot" . $suffix)?GETPOST("entrepot" . $suffix):($objp->fk_default_warehouse?$objp->fk_default_warehouse:''), "entrepot" . $suffix, '', 0, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix);
696  } else {
697  $langs->load("errors");
698  print $langs->trans("ErrorNoWarehouseDefined");
699  }
700  print "</td>\n";
701 
702  print "</tr>\n";
703  }
704  }
705  $i++;
706  }
707  $db->free($resql);
708  } else {
709  dol_print_error($db);
710  }
711 
712  print "</table>\n";
713  print '</div>';
714  print "<br>\n";
715 
716  if ($nbproduct)
717  {
718  $checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv('StatusOrderReceivedAll'));
719 
720  print '<br><div class="center">';
721  $parameters = array();
722  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
723  // modified by hook
724  if (empty($reshook))
725  {
726  print $langs->trans("Comment").' : ';
727  print '<input type="text" class="minwidth400" maxlength="128" name="comment" value="';
728  print $_POST["comment"] ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
729  // print ' / '.$object->ref_supplier; // Not yet available
730  print '" class="flat"><br>';
731 
732  print '<input type="checkbox" checked="checked" name="closeopenorder"> '.$checkboxlabel;
733 
734  print '<br><input type="submit" class="button" value="'.$langs->trans("DispatchVerb").'"';
735  if (count($listwarehouses) <= 0)
736  print ' disabled';
737  print '>';
738  }
739  print '</div>';
740  }
741 
742  // Message if nothing to dispatch
743  if (! $nbproduct) {
744  if (empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED))
745  print '<div class="opacitymedium">'.$langs->trans("NoPredefinedProductToDispatch").'</div>'; // No predefined line at all
746  else
747  print '<div class="opacitymedium">'.$langs->trans("NoMorePredefinedProductToDispatch").'</div>'; // No predefined line that remain to be dispatched.
748  }
749 
750  print '</form>';
751  }
752 
753  dol_fiche_end();
754 
755 
756  // List of lines already dispatched
757  $sql = "SELECT p.ref, p.label,";
758  $sql .= " e.rowid as warehouse_id, e.ref as entrepot,";
759  $sql .= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status, cfd.datec";
760  $sql .= " FROM " . MAIN_DB_PREFIX . "product as p,";
761  $sql .= " " . MAIN_DB_PREFIX . "commande_fournisseur_dispatch as cfd";
762  $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entrepot as e ON cfd.fk_entrepot = e.rowid";
763  $sql .= " WHERE cfd.fk_commande = " . $object->id;
764  $sql .= " AND cfd.fk_product = p.rowid";
765  $sql .= " ORDER BY cfd.rowid ASC";
766 
767  $resql = $db->query($sql);
768  if ($resql) {
769  $num = $db->num_rows($resql);
770  $i = 0;
771 
772  if ($num > 0) {
773  print "<br>\n";
774 
775  print load_fiche_titre($langs->trans("ReceivingForSameOrder"));
776 
777  print '<div class="div-table-responsive">';
778  print '<table id="dispatch_received_products" class="noborder" width="100%">';
779 
780  print '<tr class="liste_titre">';
781  print '<td>' . $langs->trans("Product") . '</td>';
782  if (! empty($conf->productbatch->enabled)) {
783  print '<td class="dispatch_batch_number_title">' . $langs->trans("batch_number") . '</td>';
784  print '<td class="dispatch_dluo_title">' . $langs->trans("EatByDate") . '</td>';
785  print '<td class="dispatch_dlc_title">' . $langs->trans("SellByDate") . '</td>';
786  }
787  print '<td align="right">' . $langs->trans("QtyDispatched") . '</td>';
788  print '<td></td>';
789  print '<td>' . $langs->trans("Warehouse") . '</td>';
790  print '<td>' . $langs->trans("Comment") . '</td>';
791  if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS))
792  print '<td align="center" colspan="2">' . $langs->trans("Status") . '</td>';
793  print '<td>' . $langs->trans("Date") . '</td>';
794  print "</tr>\n";
795 
796  while ( $i < $num ) {
797  $objp = $db->fetch_object($resql);
798 
799  print "<tr " . $bc[$var] . ">";
800  print '<td>';
801  print '<a href="' . DOL_URL_ROOT . '/product/fournisseurs.php?id=' . $objp->fk_product . '">' . img_object($langs->trans("ShowProduct"), 'product') . ' ' . $objp->ref . '</a>';
802  print ' - ' . $objp->label;
803  print "</td>\n";
804 
805  if (! empty($conf->productbatch->enabled)) {
806  print '<td class="dispatch_batch_number">' . $objp->batch . '</td>';
807  print '<td class="dispatch_dluo">' . dol_print_date($db->jdate($objp->eatby), 'day') . '</td>';
808  print '<td class="dispatch_dlc">' . dol_print_date($db->jdate($objp->sellby), 'day') . '</td>';
809  }
810 
811  // Qty
812  print '<td align="right">' . $objp->qty . '</td>';
813  print '<td>&nbsp;</td>';
814 
815  // Warehouse
816  print '<td>';
817  $warehouse_static->id = $objp->warehouse_id;
818  $warehouse_static->libelle = $objp->entrepot;
819  print $warehouse_static->getNomUrl(1);
820  print '</td>';
821 
822  // Comment
823  print '<td class="tdoverflowmax300">' . $objp->comment . '</td>';
824 
825  // Status
826  if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) {
827  print '<td align="right">';
828  $supplierorderdispatch->status = (empty($objp->status) ? 0 : $objp->status);
829  // print $supplierorderdispatch->status;
830  print $supplierorderdispatch->getLibStatut(5);
831  print '</td>';
832 
833  // Add button to check/uncheck disaptching
834  print '<td align="center">';
835  if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))
836  {
837  if (empty($objp->status)) {
838  print '<a class="button buttonRefused" href="#">' . $langs->trans("Approve") . '</a>';
839  print '<a class="button buttonRefused" href="#">' . $langs->trans("Deny") . '</a>';
840  } else {
841  print '<a class="button buttonRefused" href="#">' . $langs->trans("Disapprove") . '</a>';
842  print '<a class="button buttonRefused" href="#">' . $langs->trans("Deny") . '</a>';
843  }
844  } else {
845  $disabled = '';
846  if ($object->statut == 5)
847  $disabled = 1;
848  if (empty($objp->status)) {
849  print '<a class="button' . ($disabled ? ' buttonRefused' : '') . '" href="' . $_SERVER["PHP_SELF"] . "?id=" . $id . "&action=checkdispatchline&lineid=" . $objp->dispatchlineid . '">' . $langs->trans("Approve") . '</a>';
850  print '<a class="button' . ($disabled ? ' buttonRefused' : '') . '" href="' . $_SERVER["PHP_SELF"] . "?id=" . $id . "&action=denydispatchline&lineid=" . $objp->dispatchlineid . '">' . $langs->trans("Deny") . '</a>';
851  }
852  if ($objp->status == 1) {
853  print '<a class="button' . ($disabled ? ' buttonRefused' : '') . '" href="' . $_SERVER["PHP_SELF"] . "?id=" . $id . "&action=uncheckdispatchline&lineid=" . $objp->dispatchlineid . '">' . $langs->trans("Reinit") . '</a>';
854  print '<a class="button' . ($disabled ? ' buttonRefused' : '') . '" href="' . $_SERVER["PHP_SELF"] . "?id=" . $id . "&action=denydispatchline&lineid=" . $objp->dispatchlineid . '">' . $langs->trans("Deny") . '</a>';
855  }
856  if ($objp->status == 2) {
857  print '<a class="button' . ($disabled ? ' buttonRefused' : '') . '" href="' . $_SERVER["PHP_SELF"] . "?id=" . $id . "&action=uncheckdispatchline&lineid=" . $objp->dispatchlineid . '">' . $langs->trans("Reinit") . '</a>';
858  print '<a class="button' . ($disabled ? ' buttonRefused' : '') . '" href="' . $_SERVER["PHP_SELF"] . "?id=" . $id . "&action=checkdispatchline&lineid=" . $objp->dispatchlineid . '">' . $langs->trans("Approve") . '</a>';
859  }
860  }
861  print '</td>';
862  }
863  // date
864  print '<td>' . dol_print_date($objp->datec, "dayhour") . '</td>';
865 
866  print "</tr>\n";
867 
868  $i ++;
869  }
870  $db->free($resql);
871 
872  print "</table>\n";
873  print '</div>';
874  }
875  } else {
876  dol_print_error($db);
877  }
878 }
879 
880 // End of page
881 llxFooter();
882 $db->close();
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
print
Draft customers invoices.
Definition: index.php:91
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
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:1053
ordersupplier_prepare_head($object)
Prepare array with list of tabs.
Definition: fourn.lib.php:102
const STATUS_RECEIVED_COMPLETELY
Received completely.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm=false, $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
Class to manage table commandefournisseurdispatch.
Class to manage products or services.
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
Class to manage Dolibarr users.
Definition: user.class.php:41
Class with static methods for building HTML components related to products Only components common to ...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Class to manage generation of HTML components Only common components must be here.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage projects.
const STATUS_RECEIVED_PARTIALLY
Received partially.
llxHeader()
Empty header.
Definition: wrapper.php:44
if(GETPOST('cancel', 'alpha')) if(! GETPOST( 'confirmmassaction', 'alpha') &&$massaction !='presend' &&$massaction !='confirm_presend')
Draft customers invoices.
Definition: list.php:156
dol_now($mode='gmt')
Return date for now.
Class to manage predefined suppliers products.
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Class to manage comment.
const STATUS_ORDERSENT
Order sent, shipment on process.
restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
const STATUS_CANCELED
Order canceled.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it&#39;s its name (generic function)
price2num($amount, $rounding='', $alreadysqlnb=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
div float
Buy price without taxes.
Definition: style.css.php:564
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='')
Show tab header of a card.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
Class to manage warehouses.