dolibarr  16.0.1
stocktransfer_card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) ---Put here your own copyright and developer email---
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 //if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db
26 //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Do not load object $user
27 //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // Do not load object $mysoc
28 //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Do not load object $langs
29 //if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check injection attack on GET parameters
30 //if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check injection attack on POST parameters
31 //if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on).
32 //if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
33 //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
34 //if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
35 //if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
36 //if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library
37 //if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
38 //if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
39 //if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value
40 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler
41 //if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
42 //if (! defined("FORCECSP")) define('FORCECSP','none'); // Disable all Content Security Policies
43 
44 
45 // Load Dolibarr environment
46 $res = 0;
47 // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
48 if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
49 // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
50 $tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
51 while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; }
52 if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
53 if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
54 // Try main.inc.php using relative path
55 if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php";
56 if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
57 if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php";
58 if (!$res) die("Include of main fails");
59 
60 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
61 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
62 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
63 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
64 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
65 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
66 require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php';
67 require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php';
68 require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php';
69 require_once DOL_DOCUMENT_ROOT.'/core/modules/stocktransfer/modules_stocktransfer.php';
70 
71 // Load translation files required by the page
72 $langs->loadLangs(array("stocks", "other", "productbatch", "companies"));
73  if (!empty($conf->incoterm->enabled)) $langs->load('incoterm');
74 
75 // Get parameters
76 $id = GETPOST('id', 'int');
77 $ref = GETPOST('ref', 'alpha');
78 $action = GETPOST('action', 'aZ09');
79 $confirm = GETPOST('confirm', 'alpha');
80 $cancel = GETPOST('cancel', 'aZ09');
81 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'stocktransfercard'; // To manage different context of search
82 $backtopage = GETPOST('backtopage', 'alpha');
83 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
84 $qty = GETPOST('qty', 'int');
85 $fk_product = GETPOST('fk_product', 'int');
86 $fk_warehouse_source = GETPOST('fk_warehouse_source', 'int');
87 $fk_warehouse_destination = GETPOST('fk_warehouse_destination', 'int');
88 $lineid = GETPOST('lineid', 'int');
89 $label = GETPOST('label', 'alpha');
90 $batch = GETPOST('batch', 'alpha');
91 $code_inv = GETPOST('inventorycode', 'alphanohtml');
92 
93 // Initialize technical objects
94 $object = new StockTransfer($db);
95 $extrafields = new ExtraFields($db);
96 $diroutputmassaction = $conf->stocktransfer->dir_output.'/temp/massgeneration/'.$user->id;
97 $hookmanager->initHooks(array('stocktransfercard', 'globalcard')); // Note that conf->hooks_modules contains array
98 
99 // Fetch optionals attributes and labels
100 $extrafields->fetch_name_optionals_label($object->table_element);
101 
102 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
103 
104 // Initialize array of search criterias
105 $search_all = trim(GETPOST("search_all", 'alpha'));
106 $search = array();
107 foreach ($object->fields as $key => $val) {
108  if (GETPOST('search_'.$key, 'alpha')) $search[$key] = GETPOST('search_'.$key, 'alpha');
109 }
110 
111 if (empty($action) && empty($id) && empty($ref)) $action = 'view';
112 
113 // Load object
114 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
115 
116 
117 $permissiontoread = $user->rights->stocktransfer->stocktransfer->read;
118 $permissiontoadd = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
119 $permissionnote = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_setnotes.inc.php
120 $permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
121 $permissiondellink = $user->rights->stocktransfer->stocktransfer->write; // Used by the include of actions_dellink.inc.php
122 $upload_dir = $conf->stocktransfer->multidir_output[isset($object->entity) ? $object->entity : 1];
123 
124 // Security check - Protection if external user
125 //if ($user->socid > 0) accessforbidden();
126 //if ($user->socid > 0) $socid = $user->socid;
127 //$isdraft = (($object->statut == $object::STATUS_DRAFT) ? 1 : 0);
128 //$result = restrictedArea($user, 'stocktransfer', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
129 
130 if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) accessforbidden();
131 
132 
133 /*
134  * Actions
135  */
136 
137 $form = new Form($db);
138 $formfile = new FormFile($db);
139 $formproject = new FormProjets($db);
140 
141 $parameters = array();
142 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
143 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
144 
145 if (empty($reshook)) {
146  $error = 0;
147 
148  $backurlforlist = dol_buildpath('/product/stock/stocktransfer/stocktransfer_list.php', 1);
149 
150  if (empty($backtopage) || ($cancel && empty($id))) {
151  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
152  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) $backtopage = $backurlforlist;
153  else $backtopage = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.($id > 0 ? $id : '__ID__');
154  }
155  }
156  $triggermodname = 'STOCKTRANSFER_STOCKTRANSFER_MODIFY'; // Name of trigger action code to execute when we modify record
157 
158  // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
159  include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
160 
161  // On remet cette lecture de permission ici car nécessaire d'avoir le nouveau statut de l'objet après toute action exécutée dessus (après incrémentation par exemple, le bouton supprimer doit disparaître)
162  $permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
163 
164  // Actions when linking object each other
165  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
166 
167  // Actions when printing a doc from card
168  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
169 
170  // Action to move up and down lines of object
171  include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
172 
173  // Action to build doc
174  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
175 
176  if ($action == 'set_thirdparty' && $permissiontoadd) {
177  $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'STOCKTRANSFER_MODIFY');
178  }
179  if ($action == 'classin' && $permissiontoadd) {
180  $object->setProject(GETPOST('projectid', 'int'));
181  }
182 
183  if ($action == 'addline' && $permissiontoadd) {
184  if ($qty <= 0) {
185  $error++;
186  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
187  $action = 'view';
188  }
189 
190  if ($fk_warehouse_source <= 0) {
191  $error++;
192  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
193  $action = 'view';
194  }
195 
196  if ($fk_warehouse_destination <= 0) {
197  $error++;
198  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
199  $action = 'view';
200  }
201 
202  $prod = new Product($db);
203  $prod->fetch($fk_product);
204  if ($prod->hasbatch()) {
205  if (empty($batch)) {
206  $error++;
207  $langs->load("errors");
208  setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors');
209  }
210  } else {
211  if (!empty($batch)) {
212  $error++;
213  setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors');
214  }
215  }
216 
217  if (empty($error)) {
218  $line = new StockTransferLine($db);
219  $records = $line->fetchAll('', '', 0, 0, array('customsql'=>' fk_stocktransfer = '.((int) $id).' AND fk_product = '.((int) $fk_product).' AND fk_warehouse_source = '.((int) $fk_warehouse_source).' AND fk_warehouse_destination = '.((int) $fk_warehouse_destination).' AND ('.(empty($batch) ? 'batch = "" or batch IS NULL' : "batch = '".$db->escape($batch)."'" ).')'));
220  if (!empty($records[key($records)])) $line = $records[key($records)];
221  $line->fk_stocktransfer = $id;
222  $line->qty += $qty;
223  $line->fk_warehouse_source = $fk_warehouse_source;
224  $line->fk_warehouse_destination = $fk_warehouse_destination;
225  $line->fk_product = $fk_product;
226  $line->batch = $batch;
227 
228  $line->pmp = $prod->pmp;
229  if ($line->id > 0) $line->update($user);
230  else {
231  $line->rang = count($object->lines) + 1;
232  $line->create($user);
233  }
234  $object->fetchLines();
235  }
236  } elseif ($action === 'updateline' && $permissiontoadd) {
237  if ($qty <= 0) {
238  $error++;
239  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
240  $action = 'editline';
241  }
242 
243  if ($fk_warehouse_source <= 0) {
244  $error++;
245  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
246  $action = 'editline';
247  }
248 
249  if ($fk_warehouse_destination <= 0) {
250  $error++;
251  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
252  $action = 'editline';
253  }
254 
255  $prod = new Product($db);
256  $prod->fetch($fk_product);
257  if ($prod->hasbatch()) {
258  if (empty($batch)) {
259  $error++;
260  $langs->load("errors");
261  setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->getNomUrl()), null, 'errors');
262  $action = 'editline';
263  }
264  } else {
265  if (!empty($batch)) {
266  $error++;
267  setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), '', 'errors');
268  $action = 'editline';
269  }
270  }
271 
272  if (empty($error)) {
273  $line = new StockTransferLine($db);
274  $line->fetch($lineid);
275  $line->qty = $qty;
276  $line->fk_warehouse_source = $fk_warehouse_source;
277  $line->fk_warehouse_destination = $fk_warehouse_destination;
278  $line->fk_product = $fk_product;
279  $line->batch = $batch;
280  $line->pmp = $prod->pmp;
281  $line->update($user);
282  }
283  }
284 
285  if ($permissiontoadd) {
286  // Décrémentation
287  if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED) {
288  $lines = $object->getLinesArray();
289  if (!empty($lines)) {
290  $db->begin();
291  foreach ($lines as $line) {
292  $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source);
293  if ($res <= 0) $error++;
294  }
295  if (empty($error)) $db->commit();
296  else $db->rollback();
297  }
298  if (empty($error)) {
299  $object->setStatut($object::STATUS_TRANSFERED, $id);
300  $object->status = $object::STATUS_TRANSFERED;
301  $object->date_reelle_depart = date('Y-m-d');
302  $object->update($user);
303  setEventMessage('StockStransferDecremented');
304  }
305  }
306 
307  // Annulation décrémentation
308  if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) {
309  $lines = $object->getLinesArray();
310  if (!empty($lines)) {
311  $db->begin();
312  foreach ($lines as $line) {
313  $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source, 0);
314  if ($res <= 0) $error++;
315  }
316  if (empty($error)) $db->commit();
317  else $db->rollback();
318  }
319  if (empty($error)) {
320  $object->setStatut($object::STATUS_VALIDATED, $id);
321  $object->status = $object::STATUS_VALIDATED;
322  $object->date_reelle_depart = null;
323  $object->update($user);
324  setEventMessage('StockStransferDecrementedCancel', 'warnings');
325  }
326  }
327 
328  // Incrémentation
329  if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED) {
330  $lines = $object->getLinesArray();
331  if (!empty($lines)) {
332  $db->begin();
333  foreach ($lines as $line) {
334  $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination, 0);
335  if ($res <= 0) $error++;
336  }
337  if (empty($error)) $db->commit();
338  else $db->rollback();
339  }
340  if (empty($error)) {
341  $object->setStatut($object::STATUS_CLOSED, $id);
342  $object->status = $object::STATUS_CLOSED;
343  $object->date_reelle_arrivee = date('Y-m-d');
344  $object->update($user);
345  setEventMessage('StockStransferIncrementedShort');
346  }
347  }
348 
349  // Annulation incrémentation
350  if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED) {
351  $lines = $object->getLinesArray();
352  if (!empty($lines)) {
353  $db->begin();
354  foreach ($lines as $line) {
355  $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination);
356  if ($res <= 0) $error++;
357  }
358  if (empty($error)) $db->commit();
359  else $db->rollback();
360  }
361  if (empty($error)) {
362  $object->setStatut($object::STATUS_TRANSFERED, $id);
363  $object->status = $object::STATUS_TRANSFERED;
364  $object->date_reelle_arrivee = null;
365  $object->update($user);
366  setEventMessage('StockStransferIncrementedShortCancel', 'warnings');
367  }
368  }
369  }
370 
371  // Set incoterm
372  if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $permissiontoadd) {
373  $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha'));
374  }
375  // Actions to send emails
376  $triggersendname = 'STOCKTRANSFER_SENTBYMAIL';
377  $autocopy = 'MAIN_MAIL_AUTOCOPY_STOCKTRANSFER_TO';
378  $trackid = 'stocktransfer'.$object->id;
379  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
380 }
381 
382 
383 
384 
385 /*
386  * View
387  *
388  * Put here all code to build page
389  */
390 
391 $title = $langs->trans("StockTransfer");
392 $help_url = '';
393 llxHeader('', $title, $help_url);
394 
395 
396 
397 // Example : Adding jquery code
398 print '<script type="text/javascript" language="javascript">
399 jQuery(document).ready(function() {';
400 
401 // Affichage alerte date prévue de départ si transfert concerné
402 $date_prevue_depart = $object->date_prevue_depart;
403 $date_prevue_depart_plus_delai = $date_prevue_depart;
404 if ($object->lead_time_for_warning > 0) $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day');
405 if (!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) {
406  print "$('.valuefield.fieldname_date_prevue_depart').append('";
407  print img_warning($langs->trans('Alert').' - '.$langs->trans('Late'));
408  print "');";
409 }
410 
411 print '});
412 </script>';
413 
414 
415 // Part to create
416 if ($action == 'create') {
417  print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("StockTransfer")), '', 'object_'.$object->picto);
418 
419  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
420  print '<input type="hidden" name="token" value="'.newToken().'">';
421  print '<input type="hidden" name="action" value="add">';
422  if ($backtopage) print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
423  if ($backtopageforcancel) print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
424 
425  print dol_get_fiche_head(array(), '');
426 
427  // Set some default values
428  //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue';
429 
430  print '<table class="border centpercent tableforfieldcreate">'."\n";
431 
432  // Common attributes
433  include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
434 
435  if (!empty($conf->incoterm->enabled)) {
436  print '<tr>';
437  print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $soc->label_incoterms, 1).'</label></td>';
438  print '<td class="maxwidthonsmartphone">';
439  print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : ''), '', 'fk_incoterms');
440  print '</td></tr>';
441  }
442  // Template to use by default
443  print '<tr><td>'.$langs->trans('DefaultModel').'</td>';
444  print '<td>';
445  print img_picto('', 'pdf', 'class="pictofixedwidth"');
446  include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
448  $preselected = $conf->global->STOCKTRANSFER_ADDON_PDF;
449  print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
450  print "</td></tr>";
451 
452  // Other attributes
453  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
454 
455  print '</table>'."\n";
456 
457  print dol_get_fiche_end();
458 
459  print '<div class="center">';
460  print '<input type="submit" class="button" name="add" value="'.dol_escape_htmltag($langs->trans("Create")).'">';
461  print '&nbsp; ';
462  print '<input type="'.($backtopage ? "submit" : "button").'" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'"'.($backtopage ? '' : ' onclick="javascript:history.go(-1)"').'>'; // Cancel for create does not post form if we don't know the backtopage
463  print '</div>';
464 
465  print '</form>';
466 
467  //dol_set_focus('input[name="ref"]');
468 }
469 
470 // Part to edit record
471 if (($id || $ref) && $action == 'edit') {
472  //if($object->status < 3) {
473  print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto);
474 
475  print '<form method="POST" action="' . $_SERVER["PHP_SELF"] . '">';
476  print '<input type="hidden" name="token" value="' . newToken() . '">';
477  print '<input type="hidden" name="action" value="update">';
478  print '<input type="hidden" name="id" value="' . $object->id . '">';
479  if ($backtopage) print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
480  if ($backtopageforcancel) print '<input type="hidden" name="backtopageforcancel" value="' . $backtopageforcancel . '">';
481 
482  print dol_get_fiche_head();
483 
484  print '<table class="border centpercent tableforfieldedit">' . "\n";
485 
486  // Common attributes
487  include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php';
488 
489  // Other attributes
490  include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php';
491 
492  print '</table>';
493 
494  print dol_get_fiche_end();
495 
496  print '<div class="center"><input type="submit" class="button" name="save" value="' . $langs->trans("Save") . '">';
497  print ' &nbsp; <input type="submit" class="button" name="cancel" value="' . $langs->trans("Cancel") . '">';
498  print '</div>';
499 
500  print '</form>';
501  //} else $action = 'view';
502 }
503 
504 // Part to show record
505 if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
506  $res = $object->fetch_optionals();
507 
508  $head = stocktransferPrepareHead($object);
509  print dol_get_fiche_head($head, 'card', $langs->trans("StockTransfer"), -1, $object->picto);
510 
511  $formconfirm = '';
512 
513  // Confirmation to delete
514  if ($action == 'delete') {
515  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Delete'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1);
516  }
517  // Confirmation to delete line
518  if ($action == 'deleteline') {
519  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
520  }
521  // Clone confirmation
522  if ($action == 'clone') {
523  // Create an array for form
524  $formquestion = array();
525  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
526  } elseif ($action == 'destock') { // Destock confirmation
527  // Create an array for form
528  $formquestion = array( 'text' => '',
529  array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'size'=>40),
530  array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25)
531  );
532  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1);
533  } elseif ($action == 'destockcancel') { // Destock confirmation cancel
534  // Create an array for form
535  $formquestion = array( 'text' => '',
536  array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'size'=>40),
537  array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25)
538  );
539  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1);
540  } elseif ($action == 'addstock') { // Addstock confirmation
541  // Create an array for form
542  $formquestion = array( 'text' => '',
543  array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").'&nbsp;:', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'size'=>40),
544  array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25)
545  );
546  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1);
547  } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel
548  // Create an array for form
549  $formquestion = array( 'text' => '',
550  array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").'&nbsp;:', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'size'=>40),
551  array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'size'=>25)
552  );
553  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProductCancel'), '', 'confirm_addstockcancel', $formquestion, 'yes', 1);
554  }
555 
556  // Confirmation of action xxxx
557  if ($action == 'xxx') {
558  $formquestion = array();
559  /*
560  $forcecombo=0;
561  if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
562  $formquestion = array(
563  // 'text' => $langs->trans("ConfirmClone"),
564  // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
565  // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
566  // array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
567  );
568  */
569  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220);
570  }
571 
572 
573  if ($action == 'valid' && $permissiontoadd) {
574  $nextref=$object->getNextNumRef();
575  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->transnoentities('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2);
576  }
577 
578  // Call Hook formConfirm
579  $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
580  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
581  if (empty($reshook)) $formconfirm .= $hookmanager->resPrint;
582  elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint;
583 
584  // Print form confirm
585  print $formconfirm;
586 
587 
588  // Object card
589  // ------------------------------------------------------------
590  $linkback = '<a href="'.dol_buildpath('/product/stock/stocktransfer/stocktransfer_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
591 
592  $morehtmlref = '<div class="refidno">';
593 
594  // Thirdparty
595  if (isModEnabled('societe')) {
596  $morehtmlref .= $langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '').'<br>';
597  }
598  // Project
599  if (! empty($conf->project->enabled)) {
600  $langs->load("projects");
601  $morehtmlref.=$langs->trans('Project') . ' ';
602  if ($permissiontoadd) {
603  //if ($action != 'classify') $morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> ';
604  $morehtmlref.=' : ';
605  if ($action == 'classify') {
606  //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
607  $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
608  $morehtmlref.='<input type="hidden" name="action" value="classin">';
609  $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
610  $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
611  $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
612  $morehtmlref.='</form>';
613  } else {
614  $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
615  }
616  } else {
617  if (! empty($object->fk_project)) {
618  $proj = new Project($db);
619  $proj->fetch($object->fk_project);
620  $morehtmlref .= ': '.$proj->getNomUrl();
621  } else {
622  $morehtmlref .= '';
623  }
624  }
625  }
626  $morehtmlref .= '</div>';
627 
628 
629  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
630 
631 
632  print '<div class="fichecenter">';
633  print '<div class="fichehalfleft">';
634  print '<div class="underbanner clearboth"></div>';
635  print '<table class="border centpercent tableforfield">'."\n";
636 
637  // Common attributes
638  //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field
639  //unset($object->fields['fk_project']); // Hide field already shown in banner
640  //unset($object->fields['fk_soc']); // Hide field already shown in banner
641 
642  $object->fields['fk_soc']['visible']=0; // Already available in banner
643  $object->fields['fk_project']['visible']=0; // Already available in banner
644  include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
645 
646  // Incoterms
647  if (!empty($conf->incoterm->enabled)) {
648  print '<tr><td>';
649  print '<table width="100%" class="nobordernopadding"><tr><td>';
650  print $langs->trans('IncotermLabel');
651  print '<td><td class="right">';
652  if ($permissiontoadd && $action != 'editincoterm') print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=editincoterm">'.img_edit().'</a>';
653  else print '&nbsp;';
654  print '</td></tr></table>';
655  print '</td>';
656  print '<td>';
657  if ($action != 'editincoterm') {
658  print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
659  } else {
660  print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
661  }
662  print '</td></tr>';
663  }
664 
665  echo '<tr>';
666  echo '<td>'.$langs->trans('EnhancedValue').'&nbsp;'.strtolower($langs->trans('TotalWoman'));
667  echo '<td>'.price($object->getValorisationTotale(), 0, '', 1, -1, -1, $conf->currency).'</td>';
668  echo '</tr>';
669  // Other attributes. Fields from hook formObjectOptions and Extrafields.
670  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
671 
672  print '</table>';
673  print '</div>';
674  print '</div>';
675 
676  print '<div class="clearboth"></div>';
677 
678  print dol_get_fiche_end();
679 
680 
681  /*
682  * Lines
683  */
684 
685  if (!empty($object->table_element_line)) {
686  // Show object lines
687  /*$result = $object->getLinesArray();
688 
689  print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#addline' : '#line_'.GETPOST('lineid', 'int')).'" method="POST">
690  <input type="hidden" name="token" value="' . newToken().'">
691  <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
692  <input type="hidden" name="mode" value="">
693  <input type="hidden" name="id" value="' . $object->id.'">
694  ';*/
695 
696  if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
697  include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
698  }
699 
700  /*print '<div class="div-table-responsive-no-min">';
701  if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline'))
702  {
703  print '<table id="tablelines" class="noborder noshadow" width="100%">';
704  }
705 
706  if (!empty($object->lines))
707  {
708  $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1);
709  }
710 
711  // Form to add new line
712  if ($object->status == 0 && $permissiontoadd && $action != 'selectlines')
713  {
714  if ($action != 'editline')
715  {
716  // Add products/services form
717  $object->formAddObjectLine(1, $mysoc, $soc);
718 
719  $parameters = array();
720  $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
721  }
722  }
723 
724  if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline'))
725  {
726  print '</table>';
727  }
728  print '</div>';
729 
730  print "</form>\n";*/
731  }
732 
733 
734  $formproduct = new FormProduct($db);
735  print '<div class="div-table-responsive-no-min">';
736  print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#addline' : '#line_'.GETPOST('lineid', 'int')).'" method="POST">
737  <input type="hidden" name="token" value="' . newToken().'">
738  <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
739  <input type="hidden" name="mode" value="">
740  <input type="hidden" name="id" value="' . $object->id.'">
741  ';
742  if ($lineid > 0) print '<input type="hidden" name="lineid" value="'.$lineid.'" />';
743  print '<table id="tablelines" class="liste centpercent">';
744  //print '<div class="tagtable centpercent">';
745 
746  $param = '';
747 
748  $conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE=true; // Full display needed to see all column title details
749 
750  print '<tr class="liste_titre">';
751  print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
752  if (isModEnabled('productbatch')) {
753  print getTitleFieldOfList($langs->trans('Batch'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
754  }
755  print getTitleFieldOfList($langs->trans('WarehouseSource'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
756  print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
757  print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
758  if ($conf->global->PRODUCT_USE_UNITS) {
759  print getTitleFieldOfList($langs->trans('Unit'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
760  }
761  print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
762  print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
763  if (empty($object->status) && $permissiontoadd) {
764  print getTitleFieldOfList('', 0);
765  print getTitleFieldOfList('', 0);
766  print getTitleFieldOfList('', 0);
767  }
768 
769  print '</tr>';
770 
771  $listofdata = $object->getLinesArray();
772  $productstatic = new Product($db);
773  $warehousestatics = new Entrepot($db);
774  $warehousestatict = new Entrepot($db);
775 
776  foreach ($listofdata as $key => $line) {
777  $productstatic->fetch($line->fk_product);
778  $warehousestatics->fetch($line->fk_warehouse_source);
779  $warehousestatict->fetch($line->fk_warehouse_destination);
780 
781  // add html5 elements
782  $domData = ' data-element="'.$line->element.'"';
783  $domData .= ' data-id="'.$line->id.'"';
784  $domData .= ' data-qty="'.$line->qty.'"';
785  //$domData .= ' data-product_type="'.$line->product_type.'"';
786 
787  print '<tr id="row-'.$line->id.'" class="drag drop oddeven" '.$domData.'>';
788  print '<td class="titlefield">';
789  if ($action === 'editline' && $line->id == $lineid) $form->select_produits($line->fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1);
790  else print $productstatic->getNomUrl(1).' - '.$productstatic->label;
791  print '</td>';
792  if (isModEnabled('productbatch')) {
793  print '<td>';
794  if ($action === 'editline' && $line->id == $lineid) print '<input type="text" value="'.$line->batch.'" name="batch" class="flat maxwidth50"/>';
795  else {
796  $productlot = new Productlot($db);
797  if ($productlot->fetch(0, $line->fk_product, $line->batch) > 0) {
798  print $productlot->getNomUrl(1);
799  } elseif (!empty($line->batch)) print $line->batch.'&nbsp;'.img_warning($langs->trans('BatchNotFound'));;
800  }
801  print '</td>';
802  }
803 
804  print '<td>';
805 
806  if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource);
807  else print $warehousestatics->getNomUrl(1);
808  print '</td>';
809  print '<td>';
810  if ($action === 'editline' && $line->id == $lineid) print $formproduct->selectWarehouses($line->fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination);
811  else print $warehousestatict->getNomUrl(1);
812  print '</td>';
813  if ($action === 'editline' && $line->id == $lineid) print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" value="'.$line->qty.'"></td>';
814  else print '<td class="center">'.$line->qty.'</td>';
815 
816  if ($conf->global->PRODUCT_USE_UNITS) {
817  print '<td class="linecoluseunit nowrap left">';
818  $label = $productstatic->getLabelOfUnit('short');
819  if ($label !== '') {
820  print $langs->trans($label);
821  }
822  print '</td>';
823  }
824 
825  print '<td class="center">';
826  print price($line->pmp, 0, '', 1, -1, -1, $conf->currency);
827  print '</td>';
828  print '<td class="center">';
829  print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency);
830  print '</td>';
831  if (empty($object->status) && $permissiontoadd) {
832  if ($action === 'editline' && $line->id == $lineid) {
833  //print '<td class="right" colspan="2"><input type="submit" class="button" name="addline" value="' . dol_escape_htmltag($langs->trans('Save')) . '"></td>';
834  print '<td class="center valignmiddle" colspan="2"><input type="submit" class="button buttongen marginbottomonly" id="savelinebutton marginbottomonly" name="save" value="'.$langs->trans("Save").'"><br>';
835  print '<input type="submit" class="button buttongen marginbottomonly" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'"></td>';
836  } else {
837  print '<td class="right">';
838  print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=editline&amp;lineid=' . $line->id . '#line_' . $line->id . '">';
839  print img_edit() . '</a>';
840  print '</td>';
841  print '<td class="right">';
842  print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $id . '&action=deleteline&lineid=' . $line->id . '">' . img_delete($langs->trans("Remove")) . '</a>';
843  print '</td>';
844  }
845 
846  $num = count($object->lines);
847 
848  if ($num > 1 && $conf->browser->layout != 'phone' && empty($disablemove)) {
849  print '<td class="linecolmove tdlineupdown center">';
850  $coldisplay++;
851  if ($i > 0) { ?>
852  <a class="lineupdown" href="<?php print $_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=up&amp;rowid='.$line->id; ?>">
853  <?php print img_up('default', 0, 'imgupforline'); ?>
854  </a>
855  <?php }
856  if ($i < $num - 1) { ?>
857  <a class="lineupdown" href="<?php print $_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=down&amp;rowid='.$line->id; ?>">
858  <?php print img_down('default', 0, 'imgdownforline'); ?>
859  </a>
860  <?php }
861  print '</td>';
862  } else {
863  print '<td '.(($conf->browser->layout != 'phone' && empty($disablemove)) ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'></td>';
864  $coldisplay++;
865  }
866  }
867 
868  print '</tr>';
869  }
870 
871  if (empty($object->status) && $action !== 'editline' && $permissiontoadd) {
872  print '<tr class="oddeven">';
873  // Product
874  print '<td class="titlefield">';
875  $filtertype = 0;
876  if (!empty($conf->global->STOCK_SUPPORTS_SERVICES)) $filtertype = '';
877  if ($conf->global->PRODUIT_LIMIT_SIZE <= 0) {
878  $limit = '';
879  } else {
880  $limit = $conf->global->PRODUIT_LIMIT_SIZE;
881  }
882 
883  $form->select_produits($fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1);
884  print '</td>';
885  // Batch number
886  if (isModEnabled('productbatch')) {
887  print '<td>';
888  print '<input type="text" name="batch" class="flat maxwidth50" '.(!empty($error) ? 'value="'.$batch.'"' : '').'>';
889  print '</td>';
890  }
891 
892  $formproduct->loadWarehouses(); // Pour charger la totalité des entrepôts
893 
894  // On stock ceux qui ne doivent pas être proposés dans la liste
895  $TExcludedWarehouseSource=array();
896  if (!empty($object->fk_warehouse_source)) {
897  $source_ent = new Entrepot($db);
898  $source_ent->fetch($object->fk_warehouse_source);
899  foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) {
900  if (strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id'];
901  }
902  }
903 
904  // On stock ceux qui ne doivent pas être proposés dans la liste
905  $TExcludedWarehouseDestination=array();
906  if (!empty($object->fk_warehouse_destination)) {
907  $dest_ent = new Entrepot($db);
908  $dest_ent->fetch($object->fk_warehouse_destination);
909  foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) {
910  if (strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id'];
911  }
912  }
913 
914  // On vide le tableau pour qu'il se charge tout seul lors de l'appel à la fonction select_warehouses
915  $formproduct->cache_warehouses=array();
916  // In warehouse
917  print '<td>';
918  print $formproduct->selectWarehouses(empty($fk_warehouse_source) ? $object->fk_warehouse_source : $fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseSource);
919  print '</td>';
920 
921  // On vide le tableau pour qu'il se charge tout seul lors de l'appel à la fonction select_warehouses
922  $formproduct->cache_warehouses=array();
923  // Out warehouse
924  print '<td>';
925  print $formproduct->selectWarehouses(empty($fk_warehouse_destination) ? $object->fk_warehouse_destination : $fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200', $TExcludedWarehouseDestination);
926  print '</td>';
927 
928  // Qty
929  print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" '.(!empty($error) ? 'value="'.$qty.'"' : '').'></td>';
930  // PMP
931  print '<td></td>';
932  if ($conf->global->PRODUCT_USE_UNITS) {
933  // Unité
934  print '<td></td>';
935  }
936  // PMP * Qty
937  print '<td></td>';
938  // Button to add line
939  print '<td class="right" colspan="2"><input type="submit" class="button" name="addline" value="' . dol_escape_htmltag($langs->trans('Add')) . '"></td>';
940  // Grad and drop lines
941  print '<td></td>';
942  print '</tr>';
943  }
944 
945  print '</table>';
946  print '</form>';
947  print '</div>';
948 
949  // Buttons for actions
950 
951  if ($action != 'presend' && $action != 'editline') {
952  print '<div class="tabsAction">'."\n";
953  $parameters = array();
954  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
955  if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
956 
957  if (empty($reshook)) {
958  // Send
959  if (empty($user->socid)) {
960  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendMail').'</a>'."\n";
961  }
962 
963  // Back to draft
964  if ($object->status == $object::STATUS_VALIDATED) {
965  if ($permissiontoadd) {
966  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes">'.$langs->trans("SetToDraft").'</a>';
967  }
968  }
969 
970  // Modify
971  if ($permissiontoadd) {
972  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit">'.$langs->trans("Modify").'</a>'."\n";
973  }
974  /*else
975  {
976  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Modify').'</a>'."\n";
977  }*/
978 
979  // Validate
980  if ($object->status == $object::STATUS_DRAFT) {
981  if ($permissiontoadd) {
982  if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
983  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=valid">'.$langs->trans("Validate").'</a>';
984  } else {
985  $langs->load("errors");
986  print '<a class="butActionRefused" href="" title="'.$langs->trans("ErrorAddAtLeastOneLineFirst").'">'.$langs->trans("Validate").'</a>';
987  }
988  }
989  } elseif ($object->status == $object::STATUS_VALIDATED && $permissiontoadd) {
990  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=destock">'.$langs->trans("StockTransferDecrementation").'</a>';
991  } elseif ($object->status == $object::STATUS_TRANSFERED && $permissiontoadd) {
992  print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=destockcancel">'.$langs->trans("StockTransferDecrementationCancel").'</a>';
993  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=addstock">'.$langs->trans("StockTransferIncrementation").'</a>';
994  } elseif ($object->status == $object::STATUS_CLOSED && $permissiontoadd) {
995  print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=addstockcancel">'.$langs->trans("StockTransferIncrementationCancel").'</a>';
996  }
997 
998  // Clone
999  if ($permissiontoadd) {
1000  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&object=stocktransfer">'.$langs->trans("ToClone").'</a>'."\n";
1001  }
1002 
1003  /*
1004  if ($permissiontoadd)
1005  {
1006  if ($object->status == $object::STATUS_ENABLED)
1007  {
1008  print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=disable">'.$langs->trans("Disable").'</a>'."\n";
1009  }
1010  else
1011  {
1012  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=enable">'.$langs->trans("Enable").'</a>'."\n";
1013  }
1014  }
1015  if ($permissiontoadd)
1016  {
1017  if ($object->status == $object::STATUS_VALIDATED)
1018  {
1019  print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=close">'.$langs->trans("Cancel").'</a>'."\n";
1020  }
1021  else
1022  {
1023  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen">'.$langs->trans("Re-Open").'</a>'."\n";
1024  }
1025  }
1026  */
1027 
1028  // Delete (need delete permission, or if draft, just need create/modify permission)
1029  if ($object->status < $object::STATUS_TRANSFERED && $permissiontodelete) {
1030  print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'">'.$langs->trans('Delete').'</a>'."\n";
1031  }
1032  /*else
1033  {
1034  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Delete').'</a>'."\n";
1035  }*/
1036  }
1037  print '</div>'."\n";
1038  }
1039 
1040 
1041  // Select mail models is same action as presend
1042  if (GETPOST('modelselected')) {
1043  $action = 'presend';
1044  }
1045 
1046  if ($action != 'presend') {
1047  print '<div class="fichecenter"><div class="fichehalfleft">';
1048  print '<a name="builddoc"></a>'; // ancre
1049 
1050  $includedocgeneration = 1;
1051 
1052  // Documents
1053  if ($includedocgeneration) {
1054  $objref = dol_sanitizeFileName($object->ref);
1055  $relativepath = $objref . '/' . $objref . '.pdf';
1056  $filedir = $conf->stocktransfer->dir_output.'/'.$object->element.'/'.$objref;
1057  $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id;
1058  $genallowed = $user->rights->stocktransfer->stocktransfer->read; // If you can read, you can build the PDF to read content
1059  $delallowed = $user->rights->stocktransfer->stocktransfer->write; // If you can create/edit, you can remove a file on card
1060  print $formfile->showdocuments('stocktransfer:StockTransfer', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
1061  }
1062 
1063  // Show links to link elements
1064  $linktoelem = $form->showLinkToObjectBlock($object, null, array('stocktransfer'));
1065  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1066 
1067 
1068  print '</div><div class="fichehalfright"><div class="ficheaddleft">';
1069 
1070  $MAXEVENT = 10;
1071 
1072  $morehtmlright = '<a href="'.dol_buildpath('/product/stock/stocktransfer/stocktransfer_agenda.php', 1).'?id='.$object->id.'">';
1073  $morehtmlright .= $langs->trans("SeeAll");
1074  $morehtmlright .= '</a>';
1075 
1076  // List of actions on element
1077  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1078  $formactions = new FormActions($db);
1079  $somethingshown = $formactions->showactions($object, 'stocktransfer', 0, 1, '', $MAXEVENT, '', $morehtmlright);
1080 
1081  print '</div></div></div>';
1082  }
1083 
1084  //Select mail models is same action as presend
1085  if (GETPOST('modelselected')) $action = 'presend';
1086 
1087  // Presend form
1088  $modelmail = 'stocktransfer';
1089  $defaulttopic = 'InformationMessage';
1090  $diroutput = $conf->stocktransfer->dir_output;
1091  $trackid = 'stocktransfer'.$object->id;
1092 
1093  include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1094 }
1095 
1096 // End of page
1097 llxFooter();
1098 $db->close();
Class for StockTransfer.
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class for StockTransferLine.
img_edit($titlealt= 'default', $float=0, $other= '')
Show logo editer/modifier fiche.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action== 'set') elseif($action== 'specimen') elseif($action== 'setmodel') elseif($action== 'del') elseif($action== 'setdoc') $formactions
View.
Class with list of lots and properties.
if($cancel &&!$id) if($action== 'add'&&!$cancel) if($action== 'delete') if($id) $form
Actions.
Definition: card.php:142
Class to manage building of HTML components.
Class to manage products or services.
dol_now($mode= 'auto')
Return date for now.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOCSRFCHECK')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:59
stocktransferPrepareHead($object)
Prepare array of tabs for StockTransfer.
setEventMessage($mesgs, $style= 'mesgs')
Set event message in dol_events session object.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:122
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save"&&empty($cancel)) $help_url
View.
Definition: agenda.php:116
img_warning($titlealt= 'default', $moreatt= '', $morecss= 'pictowarning')
Show warning logo.
price($amount, $form=0, $outlangs= '', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code= '')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
Class with static methods for building HTML components related to products Only components common to ...
Class to manage standard extra fields.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
img_down($titlealt= 'default', $selected=0, $moreclass= '')
Show down arrow logo.
Class to manage projects.
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
img_up($titlealt= 'default', $selected=0, $moreclass= '')
Show top arrow logo.
Class to manage building of HTML components.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
if(!GETPOST('transkey', 'alphanohtml')&&!GETPOST('transphrase', 'alphanohtml')) else
View.
Definition: notice.php:53
accessforbidden($message= '', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
Class to offer components to list and upload files.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name &#39;newtoken&#39;.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
isModEnabled($module)
Is Dolibarr module enabled.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip= '', $forcenowrapcolumntitle=0)
Get title line of an array.
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.
llxFooter()
Empty footer.
Definition: wrapper.php:73
img_delete($titlealt= 'default', $other= 'class="pictodelete"', $morecss= '')
Show delete logo.
$formconfirm
if ($action == &#39;delbookkeepingyear&#39;) {
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
Class to manage warehouses.