dolibarr 24.0.2
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) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
4 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2025-2026 Pierre Ardoin <developpeur@lesmetiersdubatiment.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Load Dolibarr environment
28require '../../../main.inc.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
39require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
40require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
41require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
42require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php';
43require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php';
44require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php';
45require_once DOL_DOCUMENT_ROOT.'/core/modules/stocktransfer/modules_stocktransfer.php';
46
47// Load translation files required by the page
48$langs->loadLangs(array("stocks", "other", "productbatch", "companies"));
49if (isModEnabled('incoterm')) {
50 $langs->load('incoterm');
51}
52
53
54// Get parameters
55$id = GETPOSTINT('id');
56$ref = GETPOST('ref', 'alpha');
57
58$action = GETPOST('action', 'aZ09');
59$confirm = GETPOST('confirm', 'alpha');
60$cancel = GETPOST('cancel');
61$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
62$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
63$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
64$qty = GETPOSTINT('qty');
65$fk_product = GETPOSTINT('fk_product');
66$fk_warehouse_source = GETPOSTINT('fk_warehouse_source');
67$fk_warehouse_destination = GETPOSTINT('fk_warehouse_destination');
68$lineid = GETPOSTINT('lineid');
69$label = GETPOST('label', 'alpha');
70$batch = GETPOST('batch', 'alpha');
71$code_inv = GETPOST('inventorycode', 'alphanohtml');
72$sortfield = GETPOST('sortfield', 'aZ09comma');
73$sortorder = GETPOST('sortorder', 'aZ09comma');
74
75// Initialize a technical objects
77$extrafields = new ExtraFields($db);
78$diroutputmassaction = $conf->stocktransfer->dir_output.'/temp/massgeneration/'.$user->id;
79$hookmanager->initHooks(array($object->element.'card', 'globalcard')); // Note that conf->hooks_modules contains array
80
81// Fetch optionals attributes and labels
82$extrafields->fetch_name_optionals_label($object->table_element);
83
84$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
85
86// Initialize array of search criteria
87$search_all = trim(GETPOST("search_all", 'alpha'));
88$search = array();
89foreach ($object->fields as $key => $val) {
90 if (GETPOST('search_'.$key, 'alpha')) {
91 $search[$key] = GETPOST('search_'.$key, 'alpha');
92 }
93}
94
95if (empty($action) && empty($id) && empty($ref)) {
96 $action = 'view';
97}
98
99// Load object
100include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
101
102
103$permissiontoread = $user->hasRight('stocktransfer', 'stocktransfer', 'read');
104$permissiontoadd = $user->hasRight('stocktransfer', 'stocktransfer', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
105$permissionnote = $user->hasRight('stocktransfer', 'stocktransfer', 'write'); // Used by the include of actions_setnotes.inc.php
106$permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status < $object::STATUS_TRANSFERED);
107$permissiondellink = $user->hasRight('stocktransfer', 'stocktransfer', 'write'); // Used by the include of actions_dellink.inc.php
108$upload_dir = $conf->stocktransfer->multidir_output[isset($object->entity) ? $object->entity : 1];
109
110// Security check - Protection if external user
111restrictedArea($user, 'stocktransfer', $object->id, 'stocktransfer_stocktransfer', 'stocktransfer', 'fk_soc', 'rowid');
112
113if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) {
115}
116
117
118/*
119 * Actions
120 */
121
122$parameters = array();
123$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
124if ($reshook < 0) {
125 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
126}
127
128if (empty($reshook)) {
129 $error = 0;
130
131 $backurlforlist = dolBuildUrl(DOL_URL_ROOT.'/product/stock/stocktransfer/stocktransfer_list.php');
132
133 if (empty($backtopage) || ($cancel && empty($id))) {
134 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
135 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
136 $backtopage = $backurlforlist;
137 } else {
138 $backtopage = dolBuildUrl(DOL_URL_ROOT.'/product/stock/stocktransfer/stocktransfer_card.php', ['id' => ($id > 0 ? $id : '__ID__')]);
139 }
140 }
141 }
142
143 $triggermodname = 'STOCKTRANSFER_MODIFY'; // Name of trigger action code to execute when we modify record
144
145 // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
146 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
147
148 // We put this permission read here because it is necessary to have the new status of the object after any executed action on it (for example, the delete button must disappear after incrementation)
149 $permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
150
151 // Actions when linking object each other
152 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
153
154 // Actions when printing a doc from card
155 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
156
157 // Action to move up and down lines of object
158 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
159
160 // Action to build doc
161 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
162
163 if ($action == 'set_thirdparty' && $permissiontoadd) {
164 $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
165 }
166 if ($action == 'classin' && $permissiontoadd) {
167 $object->setProject(GETPOSTINT('projectid'));
168 }
169
170 if ($action == 'addline' && $permissiontoadd) {
171 if ($qty <= 0) {
172 $error++;
173 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
174 $action = 'view';
175 }
176
177 if ($fk_warehouse_source <= 0) {
178 $error++;
179 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
180 $action = 'view';
181 }
182
183 if ($fk_warehouse_destination <= 0) {
184 $error++;
185 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
186 $action = 'view';
187 }
188
189 $prod = new Product($db);
190 $prod->fetch($fk_product);
191 if ($prod->hasbatch()) {
192 if (empty($batch)) {
193 $error++;
194 $langs->load("errors");
195 setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors');
196 }
197 } else {
198 if (!empty($batch)) {
199 $error++;
200 setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), null, 'errors');
201 }
202 }
203
204 if ($prod->status_batch == 2 && abs($qty) > 1) {
205 $error++;
206 setEventMessages($langs->transnoentities('TooManyQtyForSerialNumber', $prod->ref), null, 'errors');
207 }
208
209 if (empty($error)) {
210 $line = new StockTransferLine($db);
211 $records = $line->fetchAll('', '', 0, 0, '(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)."'").')');
212 if (!empty($records[key($records)])) {
213 $line = $records[key($records)];
214 }
215 $line->fk_stocktransfer = $id;
216 $line->qty += $qty;
217 $line->fk_warehouse_source = $fk_warehouse_source;
218 $line->fk_warehouse_destination = $fk_warehouse_destination;
219 $line->fk_product = $fk_product;
220 $line->batch = $batch;
221
222 $line->pmp = $prod->pmp;
223 if ($line->id > 0) {
224 $line->update($user);
225 } else {
226 $line->rang = (is_array($object->lines) || $object->lines instanceof Countable) ? count($object->lines) + 1 : 1;
227 $line->create($user);
228 }
229 $object->fetchLines();
230 }
231 } elseif ($action === 'updateline' && $permissiontoadd) {
232 if ($qty <= 0) {
233 $error++;
234 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
235 $action = 'editline';
236 }
237
238 if ($fk_warehouse_source <= 0) {
239 $error++;
240 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
241 $action = 'editline';
242 }
243
244 if ($fk_warehouse_destination <= 0) {
245 $error++;
246 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
247 $action = 'editline';
248 }
249
250 $prod = new Product($db);
251 $prod->fetch($fk_product);
252 if ($prod->hasbatch()) {
253 if (empty($batch)) {
254 $error++;
255 $langs->load("errors");
256 setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->getNomUrl()), null, 'errors');
257 $action = 'editline';
258 }
259 } else {
260 if (!empty($batch)) {
261 $error++;
262 setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), null, 'errors');
263 $action = 'editline';
264 }
265 }
266
267 if ($prod->status_batch == 2 && abs($qty) > 1) {
268 $error++;
269 setEventMessages($langs->transnoentities('TooManyQtyForSerialNumber', $prod->ref), null, 'errors');
270 $action = 'editline';
271 }
272
273 if (empty($error)) {
274 $line = new StockTransferLine($db);
275 $line->fetch($lineid);
276 $line->qty = $qty;
277 $line->fk_warehouse_source = $fk_warehouse_source;
278 $line->fk_warehouse_destination = $fk_warehouse_destination;
279 $line->fk_product = $fk_product;
280 $line->batch = $batch;
281 $line->pmp = $prod->pmp;
282 $line->update($user);
283 }
284 }
285
286 // Decrease
287 if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED && $permissiontoadd) {
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) {
294 $error++;
295 setEventMessages($line->error, $line->errors, 'errors');
296 }
297 }
298 if (empty($error)) {
299 $db->commit();
300 } else {
301 $db->rollback();
302 }
303 }
304 if (empty($error)) {
305 $object->setStatut($object::STATUS_TRANSFERED, $id);
306 $object->status = $object::STATUS_TRANSFERED;
307 $object->date_reelle_depart = dol_now();
308 $object->update($user);
309 setEventMessage('StockStransferDecremented');
310 }
311 }
312
313 // Cancel Decrementation
314 if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED && $permissiontoadd) {
315 $lines = $object->getLinesArray();
316 if (!empty($lines)) {
317 $db->begin();
318 foreach ($lines as $line) {
319 $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source, 0);
320 if ($res <= 0) {
321 $error++;
322 setEventMessages($line->error, $line->errors, 'errors');
323 }
324 }
325 if (empty($error)) {
326 $db->commit();
327 } else {
328 $db->rollback();
329 }
330 }
331 if (empty($error)) {
332 $object->setStatut($object::STATUS_VALIDATED, $id);
333 $object->status = $object::STATUS_VALIDATED;
334 $object->date_reelle_depart = null;
335 $object->update($user);
336 setEventMessage('StockStransferDecrementedCancel', 'warnings');
337 }
338 }
339
340 // Incrementing
341 if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED && $permissiontoadd) {
342 $lines = $object->getLinesArray();
343 if (!empty($lines)) {
344 $db->begin();
345 foreach ($lines as $line) {
346 $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination, 0);
347 if ($res <= 0) {
348 $error++;
349 setEventMessages($line->error, $line->errors, 'errors');
350 }
351 }
352 if (empty($error)) {
353 $db->commit();
354 } else {
355 $db->rollback();
356 }
357 }
358 if (empty($error)) {
359 $object->setStatut($object::STATUS_CLOSED, $id);
360 $object->status = $object::STATUS_CLOSED;
361 $object->date_reelle_arrivee = dol_now();
362 $object->update($user);
363 $result = $object->call_trigger('STOCKTRANSFER_CLOSE', $user);
364 if ($result < 0) {
365 $error++;
366 setEventMessages($object->error, $object->errors, 'errors');
367 }
368 setEventMessage('StockStransferIncrementedShort');
369 }
370 }
371
372 // Cancel Incrementing
373 if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED && $permissiontoadd) {
374 $lines = $object->getLinesArray();
375 if (!empty($lines)) {
376 $db->begin();
377 foreach ($lines as $line) {
378 $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination);
379 if ($res <= 0) {
380 $error++;
381 setEventMessages($line->error, $line->errors, 'errors');
382 }
383 }
384 if (empty($error)) {
385 $db->commit();
386 } else {
387 $db->rollback();
388 }
389 }
390 if (empty($error)) {
391 $object->setStatut($object::STATUS_TRANSFERED, $id);
392 $object->status = $object::STATUS_TRANSFERED;
393 $object->date_reelle_arrivee = null;
394 $object->update($user);
395 setEventMessage('StockStransferIncrementedShortCancel', 'warnings');
396 }
397 }
398
399 // Set incoterm
400 if ($action == 'set_incoterms' && isModEnabled('incoterm') && $permissiontoadd) {
401 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
402 }
403 // Actions to send emails
404 $triggersendname = 'STOCKTRANSFER_SENTBYMAIL';
405 $autocopy = 'MAIN_MAIL_AUTOCOPY_STOCKTRANSFER_TO';
406 $trackid = 'stocktransfer'.$object->id;
407 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
408}
409
410
411
412
413/*
414 * View
415 */
416
417$form = new Form($db);
418$formfile = new FormFile($db);
419$formproject = new FormProjets($db);
420
421$title = $langs->trans("StockTransfer");
422$help_url = '';
423
424llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-product page-stock-stocktransfer_stocktransfer_card');
425
426
427// Example: Adding jQuery code
428print '<script type="text/javascript" language="javascript">
429jQuery(document).ready(function() {';
430
431// Show alert for planned departure date if the transfer is related
432$date_prevue_depart = $object->date_prevue_depart;
433$date_prevue_depart_plus_delai = $date_prevue_depart;
434if ($object->lead_time_for_warning > 0) {
435 $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day');
436}
437if (!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) {
438 print "$('.valuefield.fieldname_date_prevue_depart').append('";
439 print img_warning($langs->trans('Alert').' - '.$langs->trans('Late'));
440 print "');";
441}
442
443print '});
444</script>';
445
446
447// Part to create
448if ($action == 'create') {
449 if (empty($permissiontoadd)) {
450 accessforbidden('NotEnoughPermissions', 0, 1);
451 }
452
453 print load_fiche_titre($title, '', 'object_'.$object->picto);
454
455 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
456 print '<input type="hidden" name="token" value="'.newToken().'">';
457 print '<input type="hidden" name="action" value="add">';
458 if ($backtopage) {
459 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
460 }
461 if ($backtopageforcancel) {
462 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
463 }
464
465 print dol_get_fiche_head(array(), '');
466
467
468 print '<table class="border centpercent tableforfieldcreate">'."\n";
469
470 // Common attributes
471 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
472
473 if (isModEnabled('incoterm')) {
474 $soc = new Societe($db);
475 if (!empty($object->fk_soc)) {
476 $soc->fetch($object->fk_soc);
477 }
478 print '<tr>';
479 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $soc->label_incoterms, 1).'</label></td>';
480 print '<td class="maxwidthonsmartphone">';
481 print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : ''), '', 'fk_incoterms');
482 print '</td></tr>';
483 }
484 // Template to use by default
485 print '<tr><td>'.$langs->trans('DefaultModel').'</td>';
486 print '<td>';
487 print img_picto('', 'pdf', 'class="pictofixedwidth"');
488 include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
490 $preselected = getDolGlobalString('STOCKTRANSFER_ADDON_PDF');
491 print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
492 print "</td></tr>";
493
494 // Other attributes
495 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
496
497 print '</table>'."\n";
498
499 print dol_get_fiche_end();
500
501 print $form->buttonsSaveCancel("Create");
502
503 print '</form>';
504
505 //dol_set_focus('input[name="ref"]');
506}
507
508// Part to edit record
509if (($id || $ref) && $action == 'edit') {
510 print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto);
511
512 print '<form method="POST" action="' . $_SERVER["PHP_SELF"] . '">';
513 print '<input type="hidden" name="token" value="' . newToken() . '">';
514 print '<input type="hidden" name="action" value="update">';
515 print '<input type="hidden" name="id" value="' . $object->id . '">';
516 if ($backtopage) {
517 print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
518 }
519 if ($backtopageforcancel) {
520 print '<input type="hidden" name="backtopageforcancel" value="' . $backtopageforcancel . '">';
521 }
522
523 print dol_get_fiche_head();
524
525 print '<table class="border centpercent tableforfieldedit">' . "\n";
526
527 // Common attributes
528 include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php';
529
530 // Other attributes
531 include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php';
532
533 print '</table>';
534
535 print dol_get_fiche_end();
536
537 print $form->buttonsSaveCancel();
538
539 print '</form>';
540}
541
542// Part to show record
543if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
544 $res = $object->fetch_optionals();
545
546 $head = stocktransferPrepareHead($object);
547
548 print dol_get_fiche_head($head, 'card', $langs->trans("StockTransfer"), -1, $object->picto);
549
550 $formconfirm = '';
551
552 // Confirmation to delete (using preloaded confirm popup)
553 if ($action == 'delete' || ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile))) {
554 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMyObject'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 'action-delete');
555 }
556 // Confirmation to delete line
557 if ($action == 'deleteline') {
558 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
559 }
560 $formquestion = array();
561 // Clone confirmation
562 if ($action == 'clone') {
563 // Create an array for form
564 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
565 } elseif ($action == 'destock') { // Destock confirmation
566 // Create an array for form
567 $formquestion = array( 'text' => '',
568 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'morecss' => 'minwidth300'),
569 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
570 );
571 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1);
572 } elseif ($action == 'destockcancel') { // Destock confirmation cancel
573 // Create an array for form
574 $formquestion = array( 'text' => '',
575 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'morecss' => 'minwidth300'),
576 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
577 );
578 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1);
579 } elseif ($action == 'addstock') { // Addstock confirmation
580 // Create an array for form
581 $formquestion = array( 'text' => '',
582 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").'&nbsp;:', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'morecss' => 'minwidth300'),
583 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
584 );
585 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1);
586 } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel
587 // Create an array for form
588 $formquestion = array( 'text' => '',
589 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").'&nbsp;:', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'morecss' => 'minwidth300'),
590 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
591 );
592 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProductCancel'), '', 'confirm_addstockcancel', $formquestion, 'yes', 1);
593 }
594
595 if ($action == 'valid' && $permissiontoadd) {
596 $nextref = $object->getNextNumRef();
597 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->transnoentities('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2);
598 }
599
600 // Call Hook formConfirm
601 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
602 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
603 if (empty($reshook)) {
604 $formconfirm .= $hookmanager->resPrint;
605 } elseif ($reshook > 0) {
606 $formconfirm = $hookmanager->resPrint;
607 }
608
609 // Print form confirm
610 print $formconfirm;
611
612
613 // Object card
614 // ------------------------------------------------------------
615 $linkback = '<a href="'.dol_buildpath('/product/stock/stocktransfer/stocktransfer_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
616
617 $morehtmlref = '<div class="refidno">';
618 // Thirdparty
619 $morehtmlref .= empty($object->thirdparty) ? '' : $object->thirdparty->getNomUrl(1, 'customer');
620 if (!getDolGlobalInt('MAIN_DISABLE_OTHER_LINK') && !empty($object->thirdparty) && $object->thirdparty->id > 0) {
621 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
622 }
623 // Project
624 if (isModEnabled('project')) {
625 $langs->load("projects");
626 $morehtmlref .= (empty($object->thirdparty) ? '' : '<br>');
627 if ($permissiontoadd) {
628 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
629 if ($action != 'classify') {
630 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
631 }
632 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
633 } else {
634 if (!empty($object->fk_project)) {
635 $proj = new Project($db);
636 $proj->fetch($object->fk_project);
637 $morehtmlref .= $proj->getNomUrl(1);
638 if ($proj->title) {
639 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
640 }
641 }
642 }
643 }
644 $morehtmlref .= '</div>';
645
646
647 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
648
649
650 print '<div class="fichecenter">';
651 print '<div class="fichehalfleft">';
652 print '<div class="underbanner clearboth"></div>';
653 print '<table class="border centpercent tableforfield">'."\n";
654
655 // Common attributes
656 //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field
657 //unset($object->fields['fk_project']); // Hide field already shown in banner
658 //unset($object->fields['fk_soc']); // Hide field already shown in banner
659
660 $object->fields['fk_soc']['visible'] = 0; // Already available in banner
661 $object->fields['fk_project']['visible'] = 0; // Already available in banner
662 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
663
664 // Incoterms
665 if (isModEnabled('incoterm')) {
666 print '<tr><td>';
667 print '<table width="100%" class="nobordernopadding"><tr><td>';
668 print $langs->trans('IncotermLabel');
669 print '<td><td class="right">';
670 if ($permissiontoadd && $action != 'editincoterm') {
671 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
672 } else {
673 print '&nbsp;';
674 }
675 print '</td></tr></table>';
676 print '</td>';
677 print '<td>';
678 if ($action != 'editincoterm') {
679 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
680 } else {
681 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
682 }
683 print '</td></tr>';
684 }
685
686 echo '<tr>';
687 echo '<td>'.$langs->trans('EnhancedValue').'&nbsp;'.strtolower($langs->trans('TotalWoman'));
688 echo '<td>'.price($object->getValorisationTotale(), 0, '', 1, -1, -1, $conf->currency).'</td>';
689 echo '</tr>';
690
691 // Other attributes. Fields from hook formObjectOptions and Extrafields.
692 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
693
694 print '</table>';
695 print '</div>';
696 print '</div>';
697
698 print '<div class="clearboth"></div>';
699
700
701
702 /*
703 * Lines
704 */
705
706 if (!empty($object->table_element_line)) {
707 // Show object lines
708 /*
709 $result = $object->getLinesArray();
710
711 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOST('lineid', 'int')).'" method="POST">
712 <input type="hidden" name="token" value="' . newToken().'">
713 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
714 <input type="hidden" name="mode" value="">
715 <input type="hidden" name="page_y" value="">
716 <input type="hidden" name="id" value="' . $object->id.'">
717 ';
718 */
719
720 if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
721 $fk_element = $object->id;
722 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
723 }
724
725 /*
726 print '<div class="div-table-responsive-no-min">';
727 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
728 print '<table id="tablelines" class="noborder noshadow" width="100%">';
729 }
730
731 if (!empty($object->lines)) {
732 $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1);
733 }
734
735 // Form to add new line
736 if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') {
737 if ($action != 'editline') {
738 // Add products/services form
739
740 $parameters = array();
741 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
742 if ($reshook < 0) {
743 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
744 }
745 if (empty($reshook)) {
746 $object->formAddObjectLine(1, $mysoc, $soc);
747 }
748 }
749 }
750
751 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
752 print '</table>';
753 }
754 print '</div>';
755
756 print "</form>\n";
757 */
758 }
759
760
761 $formproduct = new FormProduct($db);
762 print '<div class="div-table-responsive-no-min">';
763 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#addline' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
764 <input type="hidden" name="token" value="' . newToken().'">
765 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
766 <input type="hidden" name="mode" value="">
767 <input type="hidden" name="id" value="' . $object->id.'">
768 ';
769 if ($lineid > 0) {
770 print '<input type="hidden" name="lineid" value="'.$lineid.'" />';
771 }
772 print '<table id="tablelines" class="noborder noshadow centpercent nomarginbottom">';
773 //print '<div class="tagtable centpercent">';
774
775 $param = '';
776
777 print '<tr class="liste_titre">';
778 print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
779 if (isModEnabled('productbatch')) {
780 print getTitleFieldOfList($langs->trans('Batch'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
781 }
782 print getTitleFieldOfList($langs->trans('WarehouseSource'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
783 print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
784 print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
785 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
786 print getTitleFieldOfList($langs->trans('Unit'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
787 }
788 print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
789 print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
790 if (empty($object->status) && $permissiontoadd) {
791 print getTitleFieldOfList('', 0);
792 print getTitleFieldOfList('', 0);
793 print getTitleFieldOfList('', 0);
794 }
795
796 print '</tr>';
797
798 $listofdata = $object->getLinesArray();
799 $productstatic = new Product($db);
800 $warehousestatics = new Entrepot($db);
801 $warehousestatict = new Entrepot($db);
802 $i = 0;
803
804 foreach ($listofdata as $key => $line) {
805 $productstatic->fetch($line->fk_product);
806 $warehousestatics->fetch($line->fk_warehouse_source);
807 $warehousestatict->fetch($line->fk_warehouse_destination);
808
809 // add html5 elements
810 $domData = ' data-element="'.$line->element.'"';
811 $domData .= ' data-id="'.$line->id.'"';
812 $domData .= ' data-qty="'.$line->qty.'"';
813 //$domData .= ' data-product_type="'.$line->product_type.'"';
814
815 print '<tr id="row-'.$line->id.'" class="drag drop oddeven" '.$domData.'>';
816 print '<td class="titlefield">';
817 if ($action === 'editline' && $line->id == $lineid) {
818 $form->select_produits($line->fk_product, 'fk_product', '', 0, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1);
819 } else {
820 print $productstatic->getNomUrl(1).' - '.$productstatic->label;
821 }
822 print '</td>';
823 if (isModEnabled('productbatch')) {
824 print '<td>';
825 if ($action === 'editline' && $line->id == $lineid) {
826 print '<input type="text" value="'.$line->batch.'" name="batch" class="flat maxwidth50"/>';
827 } else {
828 $productlot = new Productlot($db);
829 if ($productlot->fetch(0, $line->fk_product, $line->batch) > 0) {
830 print $productlot->getNomUrl(1);
831 } elseif (!empty($line->batch)) {
832 print $line->batch.'&nbsp;'.img_warning($langs->trans('BatchNotFound'));
833 }
834 }
835 print '</td>';
836 }
837
838 // Warehouse source
839 print '<td class="tdoverflowmax150">';
840 if ($action === 'editline' && $line->id == $lineid) {
841 print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
842 } else {
843 print $warehousestatics->getNomUrl(1);
844 }
845 print '</td>';
846
847 // Warehouse target
848 print '<td class="tdoverflowmax150">';
849 if ($action === 'editline' && $line->id == $lineid) {
850 print $formproduct->selectWarehouses($line->fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
851 } else {
852 print $warehousestatict->getNomUrl(1);
853 }
854 print '</td>';
855
856 if ($action === 'editline' && $line->id == $lineid) {
857 print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" value="'.$line->qty.'"></td>';
858 } else {
859 print '<td class="center">'.$line->qty.'</td>';
860 }
861
862 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
863 print '<td class="linecoluseunit nowrap left">';
864 $label = $productstatic->getLabelOfUnit('short');
865 print $label;
866 print '</td>';
867 }
868
869 print '<td class="center">';
870 print price($line->pmp, 0, '', 1, -1, -1, $conf->currency);
871 print '</td>';
872
873 print '<td class="center">';
874 print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency);
875 print '</td>';
876
877 if (empty($object->status) && $permissiontoadd) {
878 if ($action === 'editline' && $line->id == $lineid) {
879 //print '<td class="right" colspan="2"><input type="submit" class="button" name="addline" value="' . dol_escape_htmltag($langs->trans('Save')) . '"></td>';
880 print '<td class="center valignmiddle" colspan="2"><input type="submit" class="button buttongen marginbottomonly" id="savelinebutton marginbottomonly" name="save" value="'.$langs->trans("Save").'"><br>';
881 print '<input type="submit" class="button buttongen marginbottomonly" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'"></td>';
882 } else {
883 print '<td class="right">';
884 print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=editline&amp;token='.newToken().'&amp;lineid=' . $line->id . '#line_' . $line->id . '">';
885 print img_edit() . '</a>';
886 print '</td>';
887 print '<td class="right">';
888 // Ensure the delete line link embeds a CSRF token.
889 $deleteLineUrl = $_SERVER["PHP_SELF"] . '?id=' . $id . '&action=deleteline&lineid=' . $line->id . '&token=' . newToken();
890 print '<a href="' . $deleteLineUrl . '">' . img_delete($langs->trans("Remove")) . '</a>';
891 print '</td>';
892 }
893
894 $num = count($object->lines);
895
896 if ($num > 1 && $conf->browser->layout != 'phone' && empty($disablemove)) {
897 print '<td class="linecolmove tdlineupdown center">';
898 if ($i > 0) { ?>
899 <a class="lineupdown" href="<?php print $_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=up&amp;token='.newToken().'&amp;rowid='.$line->id; ?>">
900 <?php print img_up('default', 0, 'imgupforline'); ?>
901 </a>
902 <?php }
903 if ($i < $num - 1) { ?>
904 <a class="lineupdown" href="<?php print $_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=down&amp;token='.newToken().'&amp;rowid='.$line->id; ?>">
905 <?php print img_down('default', 0, 'imgdownforline'); ?>
906 </a>
907 <?php }
908 print '</td>';
909 } else {
910 print '<td '.(($conf->browser->layout != 'phone' && empty($disablemove)) ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'></td>';
911 }
912 }
913
914 $i ++;
915 print '</tr>';
916 }
917
918 // Line to add a new line
919 if (empty($object->status) && $action !== 'editline' && $permissiontoadd) {
920 print '<tr class="oddeven">';
921 // Product
922 print '<td class="titlefield">';
923 $filtertype = 0;
924 if (getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
925 $filtertype = '';
926 }
927 if (getDolGlobalInt('PRODUIT_LIMIT_SIZE') <= 0) {
928 $limit = 0;
929 } else {
930 $limit = getDolGlobalInt('PRODUIT_LIMIT_SIZE');
931 }
932
933 $form->select_produits($fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1);
934 print '</td>';
935 // Batch number
936 if (isModEnabled('productbatch')) {
937 print '<td>';
938 print '<input type="text" name="batch" class="flat maxwidth50" '.(!empty($error) ? 'value="'.$batch.'"' : '').'>';
939 print '</td>';
940 }
941
942 $formproduct->loadWarehouses(); // To load all warehouses
943
944 // Define a list of warehouses to exclude from the selection
945 $TExcludedWarehouseSource = array();
946 if (!empty($object->fk_warehouse_source)) {
947 $source_ent = new Entrepot($db);
948 $source_ent->fetch($object->fk_warehouse_source);
949 foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) {
950 if (strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) {
951 $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id'];
952 }
953 }
954 }
955
956 // Define a list of warehouses to exclude from the selection
957 $TExcludedWarehouseDestination = array();
958 if (!empty($object->fk_warehouse_destination)) {
959 $dest_ent = new Entrepot($db);
960 $dest_ent->fetch($object->fk_warehouse_destination);
961 foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) {
962 if (strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) {
963 $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id'];
964 }
965 }
966 }
967
968 // We clean array. It is filled automatically when calling function select_warehouses
969 $formproduct->cache_warehouses = array();
970 // In warehouse
971 print '<td>';
972 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);
973 print '</td>';
974
975 // We clean array. It is filled automatically when calling function select_warehouses
976 $formproduct->cache_warehouses = array();
977 // Out warehouse
978 print '<td>';
979 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);
980 print '</td>';
981
982 // Qty
983 print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" '.(!empty($error) ? 'value="'.(GETPOSTISSET('qty') ? GETPOST('qty') : $qty).'"' : '').'></td>';
984
985 // PMP
986 print '<td></td>';
987 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
988 // Unit
989 print '<td></td>';
990 }
991
992 // PMP * Qty
993 print '<td></td>';
994
995 // Button to add line
996 print '<td class="right" colspan="2"><input type="submit" class="button" name="addline" value="' . dol_escape_htmltag($langs->trans('Add')) . '"></td>';
997
998 // Grad and drop lines
999 print '<td></td>';
1000
1001 print '</tr>';
1002 }
1003
1004 print '</table>';
1005 print '</form>';
1006 print '</div>';
1007
1008 print dol_get_fiche_end();
1009
1010
1011 // Buttons for actions
1012
1013 if ($action != 'presend' && $action != 'editline') {
1014 print '<div class="tabsAction">'."\n";
1015 $parameters = array();
1016 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1017 if ($reshook < 0) {
1018 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1019 }
1020
1021 if (empty($reshook)) {
1022 // Send
1023 if (empty($user->socid)) {
1024 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle');
1025 }
1026
1027 // Back to draft
1028 if ($object->status == $object::STATUS_VALIDATED) {
1029 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken(), '', $permissiontoadd);
1030 }
1031
1032 // Modify
1033 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd);
1034
1035 // Validate
1036 if ($object->status == $object::STATUS_DRAFT) {
1037 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
1038 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_validate&confirm=yes&token='.newToken(), '', $permissiontoadd);
1039 } else {
1040 $langs->load("errors");
1041 print dolGetButtonAction($langs->trans("ErrorAddAtLeastOneLineFirst"), $langs->trans("Validate"), 'default', '#', '', 0);
1042 }
1043 } elseif ($object->status == $object::STATUS_VALIDATED && $permissiontoadd) {
1044 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=destock&token='.newToken().'">'.$langs->trans("StockTransferDecrementation").'</a>';
1045 } elseif ($object->status == $object::STATUS_TRANSFERED && $permissiontoadd) {
1046 print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=destockcancel&token='.newToken().'">'.$langs->trans("StockTransferDecrementationCancel").'</a>';
1047 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=addstock&token='.newToken().'">'.$langs->trans("StockTransferIncrementation").'</a>';
1048 } elseif ($object->status == $object::STATUS_CLOSED && $permissiontoadd) {
1049 print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=addstockcancel&token='.newToken().'">'.$langs->trans("StockTransferIncrementationCancel").'</a>';
1050 }
1051
1052 // Clone
1053 if ($permissiontoadd) {
1054 print dolGetButtonAction('', $langs->trans('ToClone'), 'clone', $_SERVER['PHP_SELF'].'?id='.$object->id.(!empty($object->socid) ? '&socid='.$object->socid : '').'&action=clone&token='.newToken(), '', $permissiontoadd);
1055 }
1056
1057 /*
1058 if ($permissiontoadd) {
1059 if ($object->status == $object::STATUS_ENABLED) {
1060 print dolGetButtonAction('', $langs->trans('Disable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=disable&token='.newToken(), '', $permissiontoadd);
1061 } else {
1062 print dolGetButtonAction('', $langs->trans('Enable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=enable&token='.newToken(), '', $permissiontoadd);
1063 }
1064 }
1065 if ($permissiontoadd) {
1066 if ($object->status == $object::STATUS_VALIDATED) {
1067 print dolGetButtonAction('', $langs->trans('Cancel'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontoadd);
1068 } else {
1069 print dolGetButtonAction('', $langs->trans('Re-Open'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken(), '', $permissiontoadd);
1070 }
1071 }
1072
1073 */
1074
1075 // Delete (with preloaded confirm popup)
1076 $deleteUrl = $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken();
1077 $buttonId = 'action-delete-no-ajax';
1078 if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile)) { // We can use preloaded confirm if not jmobile
1079 $deleteUrl = '';
1080 $buttonId = 'action-delete';
1081 }
1082 $params = array();
1083 print dolGetButtonAction('', $langs->trans("Delete"), 'delete', $deleteUrl, $buttonId, $permissiontodelete, $params);
1084 }
1085 print '</div>'."\n";
1086 }
1087
1088
1089 // Select mail models is same action as presend
1090 if (GETPOST('modelselected')) {
1091 $action = 'presend';
1092 }
1093
1094 if ($action != 'presend') {
1095 print '<div class="fichecenter"><div class="fichehalfleft">';
1096 print '<a name="builddoc"></a>'; // ancre
1097
1098 $includedocgeneration = 1;
1099
1100 // Documents
1101 if ($includedocgeneration) {
1102 $objref = dol_sanitizeFileName($object->ref);
1103 $relativepath = $objref . '/' . $objref . '.pdf';
1104 $filedir = $conf->stocktransfer->dir_output.'/'.$object->element.'/'.$objref;
1105 $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id;
1106 $genallowed = $permissiontoread; // If you can read, you can build the PDF to read content
1107 $delallowed = $permissiontoadd; // If you can create/edit, you can remove a file on card
1108 print $formfile->showdocuments('stocktransfer:StockTransfer', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
1109 }
1110
1111 // Show links to link elements
1112 $tmparray = $form->showLinkToObjectBlock($object, array(), array('stocktransfer'), 1);
1113 $linktoelem = $tmparray['linktoelem'];
1114 $htmltoenteralink = $tmparray['htmltoenteralink'];
1115 print $htmltoenteralink;
1116
1117 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1118
1119
1120 print '</div><div class="fichehalfright">';
1121
1122 $MAXEVENT = 10;
1123
1124 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id);
1125
1126 // List of actions on element
1127 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1128 $formactions = new FormActions($db);
1129 $somethingshown = $formactions->showactions($object, 'stocktransfer', 0, 1, '', $MAXEVENT, '');
1130
1131 print '</div></div>';
1132 }
1133
1134 //Select mail models is same action as presend
1135 if (GETPOST('modelselected')) {
1136 $action = 'presend';
1137 }
1138
1139 // Presend form
1140 $modelmail = 'stocktransfer_send';
1141 $defaulttopic = 'InformationMessage';
1142 $diroutput = $conf->stocktransfer->dir_output.'/'.$object->element;
1143 $trackid = 'stocktransfer'.$object->id;
1144
1145 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1146}
1147
1148// End of page
1149llxFooter();
1150$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage warehouses.
Class to manage standard extra fields.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage building of HTML components.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Class to manage products or services.
Class with list of lots and properties.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class for StockTransfer.
Class for StockTransferLine.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0, $attop=0)
Set event message in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
img_down($titlealt='default', $selected=0, $moreclass='')
Show down arrow 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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
img_up($titlealt='default', $selected=0, $moreclass='')
Show top arrow logo.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
print $langs trans('Date')." left Ref Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as date
Definition receipt.php:492
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
stocktransferPrepareHead($object)
Prepare array of tabs for StockTransfer.