dolibarr 24.0.0-beta
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-2025 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
111//if ($user->socid > 0) accessforbidden();
112//if ($user->socid > 0) $socid = $user->socid;
113//$isdraft = (($object->statut == $object::STATUS_DRAFT) ? 1 : 0);
114//restrictedArea($user, 'stocktransfer', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
115
116if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) {
118}
119
120
121/*
122 * Actions
123 */
124
125$parameters = array();
126$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
127if ($reshook < 0) {
128 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
129}
130
131if (empty($reshook)) {
132 $error = 0;
133
134 $backurlforlist = dolBuildUrl(DOL_URL_ROOT.'/product/stock/stocktransfer/stocktransfer_list.php');
135
136 if (empty($backtopage) || ($cancel && empty($id))) {
137 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
138 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
139 $backtopage = $backurlforlist;
140 } else {
141 $backtopage = dolBuildUrl(DOL_URL_ROOT.'/product/stock/stocktransfer/stocktransfer_card.php', ['id' => ($id > 0 ? $id : '__ID__')]);
142 }
143 }
144 }
145
146 $triggermodname = 'STOCKTRANSFER_MODIFY'; // Name of trigger action code to execute when we modify record
147
148 // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
149 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
150
151 // 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 example, le bouton supprimer doit disparaître)
152 $permissiontodelete = $user->rights->stocktransfer->stocktransfer->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
153
154 // Actions when linking object each other
155 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
156
157 // Actions when printing a doc from card
158 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
159
160 // Action to move up and down lines of object
161 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
162
163 // Action to build doc
164 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
165
166 if ($action == 'set_thirdparty' && $permissiontoadd) {
167 $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
168 }
169 if ($action == 'classin' && $permissiontoadd) {
170 $object->setProject(GETPOSTINT('projectid'));
171 }
172
173 if ($action == 'addline' && $permissiontoadd) {
174 if ($qty <= 0) {
175 $error++;
176 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
177 $action = 'view';
178 }
179
180 if ($fk_warehouse_source <= 0) {
181 $error++;
182 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
183 $action = 'view';
184 }
185
186 if ($fk_warehouse_destination <= 0) {
187 $error++;
188 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
189 $action = 'view';
190 }
191
192 $prod = new Product($db);
193 $prod->fetch($fk_product);
194 if ($prod->hasbatch()) {
195 if (empty($batch)) {
196 $error++;
197 $langs->load("errors");
198 setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->ref), null, 'errors');
199 }
200 } else {
201 if (!empty($batch)) {
202 $error++;
203 setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), null, 'errors');
204 }
205 }
206
207 if ($prod->status_batch == 2 && abs($qty) > 1) {
208 $error++;
209 setEventMessages($langs->transnoentities('TooManyQtyForSerialNumber', $prod->ref), null, 'errors');
210 }
211
212 if (empty($error)) {
213 $line = new StockTransferLine($db);
214 $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)."'").')');
215 if (!empty($records[key($records)])) {
216 $line = $records[key($records)];
217 }
218 $line->fk_stocktransfer = $id;
219 $line->qty += $qty;
220 $line->fk_warehouse_source = $fk_warehouse_source;
221 $line->fk_warehouse_destination = $fk_warehouse_destination;
222 $line->fk_product = $fk_product;
223 $line->batch = $batch;
224
225 $line->pmp = $prod->pmp;
226 if ($line->id > 0) {
227 $line->update($user);
228 } else {
229 $line->rang = (is_array($object->lines) || $object->lines instanceof Countable) ? count($object->lines) + 1 : 1;
230 $line->create($user);
231 }
232 $object->fetchLines();
233 }
234 } elseif ($action === 'updateline' && $permissiontoadd) {
235 if ($qty <= 0) {
236 $error++;
237 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
238 $action = 'editline';
239 }
240
241 if ($fk_warehouse_source <= 0) {
242 $error++;
243 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
244 $action = 'editline';
245 }
246
247 if ($fk_warehouse_destination <= 0) {
248 $error++;
249 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
250 $action = 'editline';
251 }
252
253 $prod = new Product($db);
254 $prod->fetch($fk_product);
255 if ($prod->hasbatch()) {
256 if (empty($batch)) {
257 $error++;
258 $langs->load("errors");
259 setEventMessages($langs->transnoentities("ErrorTryToMakeMoveOnProductRequiringBatchData", $prod->getNomUrl()), null, 'errors');
260 $action = 'editline';
261 }
262 } else {
263 if (!empty($batch)) {
264 $error++;
265 setEventMessages($langs->transnoentities('StockTransferNoBatchForProduct', $prod->getNomUrl()), null, 'errors');
266 $action = 'editline';
267 }
268 }
269
270 if ($prod->status_batch == 2 && abs($qty) > 1) {
271 $error++;
272 setEventMessages($langs->transnoentities('TooManyQtyForSerialNumber', $prod->ref), null, 'errors');
273 $action = 'editline';
274 }
275
276 if (empty($error)) {
277 $line = new StockTransferLine($db);
278 $line->fetch($lineid);
279 $line->qty = $qty;
280 $line->fk_warehouse_source = $fk_warehouse_source;
281 $line->fk_warehouse_destination = $fk_warehouse_destination;
282 $line->fk_product = $fk_product;
283 $line->batch = $batch;
284 $line->pmp = $prod->pmp;
285 $line->update($user);
286 }
287 }
288
289 // Decrease
290 if ($action == 'confirm_destock' && $confirm == 'yes' && $object->status == $object::STATUS_VALIDATED && $permissiontoadd) {
291 $lines = $object->getLinesArray();
292 if (!empty($lines)) {
293 $db->begin();
294 foreach ($lines as $line) {
295 $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source);
296 if ($res < 0) {
297 $error++;
298 setEventMessages($line->error, $line->errors, 'errors');
299 }
300 }
301 if (empty($error)) {
302 $db->commit();
303 } else {
304 $db->rollback();
305 }
306 }
307 if (empty($error)) {
308 $object->setStatut($object::STATUS_TRANSFERED, $id);
309 $object->status = $object::STATUS_TRANSFERED;
310 $object->date_reelle_depart = dol_now();
311 $object->update($user);
312 setEventMessage('StockStransferDecremented');
313 }
314 }
315
316 // Annulation décrémentation
317 if ($action == 'confirm_destockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED && $permissiontoadd) {
318 $lines = $object->getLinesArray();
319 if (!empty($lines)) {
320 $db->begin();
321 foreach ($lines as $line) {
322 $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_source, 0);
323 if ($res <= 0) {
324 $error++;
325 setEventMessages($line->error, $line->errors, 'errors');
326 }
327 }
328 if (empty($error)) {
329 $db->commit();
330 } else {
331 $db->rollback();
332 }
333 }
334 if (empty($error)) {
335 $object->setStatut($object::STATUS_VALIDATED, $id);
336 $object->status = $object::STATUS_VALIDATED;
337 $object->date_reelle_depart = null;
338 $object->update($user);
339 setEventMessage('StockStransferDecrementedCancel', 'warnings');
340 }
341 }
342
343 // Incrémentation
344 if ($action == 'confirm_addstock' && $confirm == 'yes' && $object->status == $object::STATUS_TRANSFERED && $permissiontoadd) {
345 $lines = $object->getLinesArray();
346 if (!empty($lines)) {
347 $db->begin();
348 foreach ($lines as $line) {
349 $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination, 0);
350 if ($res <= 0) {
351 $error++;
352 setEventMessages($line->error, $line->errors, 'errors');
353 }
354 }
355 if (empty($error)) {
356 $db->commit();
357 } else {
358 $db->rollback();
359 }
360 }
361 if (empty($error)) {
362 $object->setStatut($object::STATUS_CLOSED, $id);
363 $object->status = $object::STATUS_CLOSED;
364 $object->date_reelle_arrivee = dol_now();
365 $object->update($user);
366 $result = $object->call_trigger('STOCKTRANSFER_CLOSE', $user);
367 if ($result < 0) {
368 $error++;
369 setEventMessages($object->error, $object->errors, 'errors');
370 }
371 setEventMessage('StockStransferIncrementedShort');
372 }
373 }
374
375 // Annulation incrémentation
376 if ($action == 'confirm_addstockcancel' && $confirm == 'yes' && $object->status == $object::STATUS_CLOSED && $permissiontoadd) {
377 $lines = $object->getLinesArray();
378 if (!empty($lines)) {
379 $db->begin();
380 foreach ($lines as $line) {
381 $res = $line->doStockMovement($label, $code_inv, $line->fk_warehouse_destination);
382 if ($res <= 0) {
383 $error++;
384 setEventMessages($line->error, $line->errors, 'errors');
385 }
386 }
387 if (empty($error)) {
388 $db->commit();
389 } else {
390 $db->rollback();
391 }
392 }
393 if (empty($error)) {
394 $object->setStatut($object::STATUS_TRANSFERED, $id);
395 $object->status = $object::STATUS_TRANSFERED;
396 $object->date_reelle_arrivee = null;
397 $object->update($user);
398 setEventMessage('StockStransferIncrementedShortCancel', 'warnings');
399 }
400 }
401
402 // Set incoterm
403 if ($action == 'set_incoterms' && isModEnabled('incoterm') && $permissiontoadd) {
404 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
405 }
406 // Actions to send emails
407 $triggersendname = 'STOCKTRANSFER_SENTBYMAIL';
408 $autocopy = 'MAIN_MAIL_AUTOCOPY_STOCKTRANSFER_TO';
409 $trackid = 'stocktransfer'.$object->id;
410 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
411}
412
413
414
415
416/*
417 * View
418 */
419
420$form = new Form($db);
421$formfile = new FormFile($db);
422$formproject = new FormProjets($db);
423
424$title = $langs->trans("StockTransfer");
425$help_url = '';
426
427llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-product page-stock-stocktransfer_stocktransfer_card');
428
429
430// Example : Adding jquery code
431print '<script type="text/javascript" language="javascript">
432jQuery(document).ready(function() {';
433
434// Show alert for planned departure date if the transfer is related
435$date_prevue_depart = $object->date_prevue_depart;
436$date_prevue_depart_plus_delai = $date_prevue_depart;
437if ($object->lead_time_for_warning > 0) {
438 $date_prevue_depart_plus_delai = strtotime(date('Y-m-d', $date_prevue_depart) . ' + '.$object->lead_time_for_warning.' day');
439}
440if (!empty($date_prevue_depart) && $date_prevue_depart_plus_delai < strtotime(date('Y-m-d'))) {
441 print "$('.valuefield.fieldname_date_prevue_depart').append('";
442 print img_warning($langs->trans('Alert').' - '.$langs->trans('Late'));
443 print "');";
444}
445
446print '});
447</script>';
448
449
450// Part to create
451if ($action == 'create') {
452 if (empty($permissiontoadd)) {
453 accessforbidden('NotEnoughPermissions', 0, 1);
454 }
455
456 print load_fiche_titre($title, '', 'object_'.$object->picto);
457
458 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
459 print '<input type="hidden" name="token" value="'.newToken().'">';
460 print '<input type="hidden" name="action" value="add">';
461 if ($backtopage) {
462 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
463 }
464 if ($backtopageforcancel) {
465 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
466 }
467
468 print dol_get_fiche_head(array(), '');
469
470
471 print '<table class="border centpercent tableforfieldcreate">'."\n";
472
473 // Common attributes
474 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
475
476 if (isModEnabled('incoterm')) {
477 $soc = new Societe($db);
478 if (!empty($object->fk_soc)) {
479 $soc->fetch($object->fk_soc);
480 }
481 print '<tr>';
482 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $soc->label_incoterms, 1).'</label></td>';
483 print '<td class="maxwidthonsmartphone">';
484 print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : ''), '', 'fk_incoterms');
485 print '</td></tr>';
486 }
487 // Template to use by default
488 print '<tr><td>'.$langs->trans('DefaultModel').'</td>';
489 print '<td>';
490 print img_picto('', 'pdf', 'class="pictofixedwidth"');
491 include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
493 $preselected = getDolGlobalString('STOCKTRANSFER_ADDON_PDF');
494 print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
495 print "</td></tr>";
496
497 // Other attributes
498 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
499
500 print '</table>'."\n";
501
502 print dol_get_fiche_end();
503
504 print $form->buttonsSaveCancel("Create");
505
506 print '</form>';
507
508 //dol_set_focus('input[name="ref"]');
509}
510
511// Part to edit record
512if (($id || $ref) && $action == 'edit') {
513 print load_fiche_titre($langs->trans("StockTransfer"), '', 'object_' . $object->picto);
514
515 print '<form method="POST" action="' . $_SERVER["PHP_SELF"] . '">';
516 print '<input type="hidden" name="token" value="' . newToken() . '">';
517 print '<input type="hidden" name="action" value="update">';
518 print '<input type="hidden" name="id" value="' . $object->id . '">';
519 if ($backtopage) {
520 print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
521 }
522 if ($backtopageforcancel) {
523 print '<input type="hidden" name="backtopageforcancel" value="' . $backtopageforcancel . '">';
524 }
525
526 print dol_get_fiche_head();
527
528 print '<table class="border centpercent tableforfieldedit">' . "\n";
529
530 // Common attributes
531 include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php';
532
533 // Other attributes
534 include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php';
535
536 print '</table>';
537
538 print dol_get_fiche_end();
539
540 print $form->buttonsSaveCancel();
541
542 print '</form>';
543}
544
545// Part to show record
546if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
547 $res = $object->fetch_optionals();
548
549 $head = stocktransferPrepareHead($object);
550
551 print dol_get_fiche_head($head, 'card', $langs->trans("StockTransfer"), -1, $object->picto);
552
553 $formconfirm = '';
554
555 // Confirmation to delete (using preloaded confirm popup)
556 if ($action == 'delete' || ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile))) {
557 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMyObject'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 'action-delete');
558 }
559 // Confirmation to delete line
560 if ($action == 'deleteline') {
561 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
562 }
563 $formquestion = array();
564 // Clone confirmation
565 if ($action == 'clone') {
566 // Create an array for form
567 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
568 } elseif ($action == 'destock') { // Destock confirmation
569 // Create an array for form
570 $formquestion = array( 'text' => '',
571 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestock', $object->ref), 'morecss' => 'minwidth300'),
572 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
573 );
574 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProduct'), '', 'confirm_destock', $formquestion, 'yes', 1);
575 } elseif ($action == 'destockcancel') { // Destock confirmation cancel
576 // Create an array for form
577 $formquestion = array( 'text' => '',
578 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label"), 'value' => $langs->trans('ConfirmDestockCancel', $object->ref), 'morecss' => 'minwidth300'),
579 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
580 );
581 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DestockAllProductCancel'), '', 'confirm_destockcancel', $formquestion, 'yes', 1);
582 } elseif ($action == 'addstock') { // Addstock confirmation
583 // Create an array for form
584 $formquestion = array( 'text' => '',
585 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").'&nbsp;:', 'value' => $langs->trans('ConfirmAddStock', $object->ref), 'morecss' => 'minwidth300'),
586 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
587 );
588 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProduct'), '', 'confirm_addstock', $formquestion, 'yes', 1);
589 } elseif ($action == 'addstockcancel') { // Addstock confirmation cancel
590 // Create an array for form
591 $formquestion = array( 'text' => '',
592 0 => array('type' => 'text', 'name' => 'label', 'label' => $langs->trans("Label").'&nbsp;:', 'value' => $langs->trans('ConfirmAddStockCancel', $object->ref), 'morecss' => 'minwidth300'),
593 1 => array('type' => 'text', 'name' => 'inventorycode', 'label' => $langs->trans("InventoryCode"), 'value' => dol_print_date(dol_now(), '%y%m%d%H%M%S'), 'morecss' => 'minwidth200')
594 );
595 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('AddStockAllProductCancel'), '', 'confirm_addstockcancel', $formquestion, 'yes', 1);
596 }
597
598 if ($action == 'valid' && $permissiontoadd) {
599 $nextref = $object->getNextNumRef();
600 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $langs->transnoentities('ConfirmValidateStockTransfer', $nextref), 'confirm_validate', $formquestion, 0, 2);
601 }
602
603 // Call Hook formConfirm
604 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
605 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
606 if (empty($reshook)) {
607 $formconfirm .= $hookmanager->resPrint;
608 } elseif ($reshook > 0) {
609 $formconfirm = $hookmanager->resPrint;
610 }
611
612 // Print form confirm
613 print $formconfirm;
614
615
616 // Object card
617 // ------------------------------------------------------------
618 $linkback = '<a href="'.dol_buildpath('/product/stock/stocktransfer/stocktransfer_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
619
620 $morehtmlref = '<div class="refidno">';
621 // Thirdparty
622 $morehtmlref .= empty($object->thirdparty) ? '' : $object->thirdparty->getNomUrl(1, 'customer');
623 if (!getDolGlobalInt('MAIN_DISABLE_OTHER_LINK') && !empty($object->thirdparty) && $object->thirdparty->id > 0) {
624 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
625 }
626 // Project
627 if (isModEnabled('project')) {
628 $langs->load("projects");
629 $morehtmlref .= (empty($object->thirdparty) ? '' : '<br>');
630 if ($permissiontoadd) {
631 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
632 if ($action != 'classify') {
633 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
634 }
635 $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');
636 } else {
637 if (!empty($object->fk_project)) {
638 $proj = new Project($db);
639 $proj->fetch($object->fk_project);
640 $morehtmlref .= $proj->getNomUrl(1);
641 if ($proj->title) {
642 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
643 }
644 }
645 }
646 }
647 $morehtmlref .= '</div>';
648
649
650 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
651
652
653 print '<div class="fichecenter">';
654 print '<div class="fichehalfleft">';
655 print '<div class="underbanner clearboth"></div>';
656 print '<table class="border centpercent tableforfield">'."\n";
657
658 // Common attributes
659 //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field
660 //unset($object->fields['fk_project']); // Hide field already shown in banner
661 //unset($object->fields['fk_soc']); // Hide field already shown in banner
662
663 $object->fields['fk_soc']['visible'] = 0; // Already available in banner
664 $object->fields['fk_project']['visible'] = 0; // Already available in banner
665 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
666
667 // Incoterms
668 if (isModEnabled('incoterm')) {
669 print '<tr><td>';
670 print '<table width="100%" class="nobordernopadding"><tr><td>';
671 print $langs->trans('IncotermLabel');
672 print '<td><td class="right">';
673 if ($permissiontoadd && $action != 'editincoterm') {
674 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=editincoterm">'.img_edit().'</a>';
675 } else {
676 print '&nbsp;';
677 }
678 print '</td></tr></table>';
679 print '</td>';
680 print '<td>';
681 if ($action != 'editincoterm') {
682 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
683 } else {
684 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
685 }
686 print '</td></tr>';
687 }
688
689 echo '<tr>';
690 echo '<td>'.$langs->trans('EnhancedValue').'&nbsp;'.strtolower($langs->trans('TotalWoman'));
691 echo '<td>'.price($object->getValorisationTotale(), 0, '', 1, -1, -1, $conf->currency).'</td>';
692 echo '</tr>';
693
694 // Other attributes. Fields from hook formObjectOptions and Extrafields.
695 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
696
697 print '</table>';
698 print '</div>';
699 print '</div>';
700
701 print '<div class="clearboth"></div>';
702
703
704
705 /*
706 * Lines
707 */
708
709 if (!empty($object->table_element_line)) {
710 // Show object lines
711 /*
712 $result = $object->getLinesArray();
713
714 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOST('lineid', 'int')).'" method="POST">
715 <input type="hidden" name="token" value="' . newToken().'">
716 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
717 <input type="hidden" name="mode" value="">
718 <input type="hidden" name="page_y" value="">
719 <input type="hidden" name="id" value="' . $object->id.'">
720 ';
721 */
722
723 if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
724 $fk_element = $object->id;
725 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
726 }
727
728 /*
729 print '<div class="div-table-responsive-no-min">';
730 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
731 print '<table id="tablelines" class="noborder noshadow" width="100%">';
732 }
733
734 if (!empty($object->lines)) {
735 $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1);
736 }
737
738 // Form to add new line
739 if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') {
740 if ($action != 'editline') {
741 // Add products/services form
742
743 $parameters = array();
744 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
745 if ($reshook < 0) {
746 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
747 }
748 if (empty($reshook)) {
749 $object->formAddObjectLine(1, $mysoc, $soc);
750 }
751 }
752 }
753
754 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
755 print '</table>';
756 }
757 print '</div>';
758
759 print "</form>\n";
760 */
761 }
762
763
764 $formproduct = new FormProduct($db);
765 print '<div class="div-table-responsive-no-min">';
766 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#addline' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
767 <input type="hidden" name="token" value="' . newToken().'">
768 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
769 <input type="hidden" name="mode" value="">
770 <input type="hidden" name="id" value="' . $object->id.'">
771 ';
772 if ($lineid > 0) {
773 print '<input type="hidden" name="lineid" value="'.$lineid.'" />';
774 }
775 print '<table id="tablelines" class="noborder noshadow centpercent nomarginbottom">';
776 //print '<div class="tagtable centpercent">';
777
778 $param = '';
779
780 print '<tr class="liste_titre">';
781 print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
782 if (isModEnabled('productbatch')) {
783 print getTitleFieldOfList($langs->trans('Batch'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
784 }
785 print getTitleFieldOfList($langs->trans('WarehouseSource'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
786 print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
787 print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
788 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
789 print getTitleFieldOfList($langs->trans('Unit'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
790 }
791 print getTitleFieldOfList($langs->trans('AverageUnitPricePMPShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
792 print getTitleFieldOfList($langs->trans('EstimatedStockValueShort'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
793 if (empty($object->status) && $permissiontoadd) {
794 print getTitleFieldOfList('', 0);
795 print getTitleFieldOfList('', 0);
796 print getTitleFieldOfList('', 0);
797 }
798
799 print '</tr>';
800
801 $listofdata = $object->getLinesArray();
802 $productstatic = new Product($db);
803 $warehousestatics = new Entrepot($db);
804 $warehousestatict = new Entrepot($db);
805 $i = 0;
806
807 foreach ($listofdata as $key => $line) {
808 $productstatic->fetch($line->fk_product);
809 $warehousestatics->fetch($line->fk_warehouse_source);
810 $warehousestatict->fetch($line->fk_warehouse_destination);
811
812 // add html5 elements
813 $domData = ' data-element="'.$line->element.'"';
814 $domData .= ' data-id="'.$line->id.'"';
815 $domData .= ' data-qty="'.$line->qty.'"';
816 //$domData .= ' data-product_type="'.$line->product_type.'"';
817
818 print '<tr id="row-'.$line->id.'" class="drag drop oddeven" '.$domData.'>';
819 print '<td class="titlefield">';
820 if ($action === 'editline' && $line->id == $lineid) {
821 $form->select_produits($line->fk_product, 'fk_product', '', 0, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1);
822 } else {
823 print $productstatic->getNomUrl(1).' - '.$productstatic->label;
824 }
825 print '</td>';
826 if (isModEnabled('productbatch')) {
827 print '<td>';
828 if ($action === 'editline' && $line->id == $lineid) {
829 print '<input type="text" value="'.$line->batch.'" name="batch" class="flat maxwidth50"/>';
830 } else {
831 $productlot = new Productlot($db);
832 if ($productlot->fetch(0, $line->fk_product, $line->batch) > 0) {
833 print $productlot->getNomUrl(1);
834 } elseif (!empty($line->batch)) {
835 print $line->batch.'&nbsp;'.img_warning($langs->trans('BatchNotFound'));
836 }
837 }
838 print '</td>';
839 }
840
841 // Warehouse source
842 print '<td class="tdoverflowmax150">';
843 if ($action === 'editline' && $line->id == $lineid) {
844 print $formproduct->selectWarehouses($line->fk_warehouse_source, 'fk_warehouse_source', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
845 } else {
846 print $warehousestatics->getNomUrl(1);
847 }
848 print '</td>';
849
850 // Warehouse target
851 print '<td class="tdoverflowmax150">';
852 if ($action === 'editline' && $line->id == $lineid) {
853 print $formproduct->selectWarehouses($line->fk_warehouse_destination, 'fk_warehouse_destination', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
854 } else {
855 print $warehousestatict->getNomUrl(1);
856 }
857 print '</td>';
858
859 if ($action === 'editline' && $line->id == $lineid) {
860 print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" value="'.$line->qty.'"></td>';
861 } else {
862 print '<td class="center">'.$line->qty.'</td>';
863 }
864
865 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
866 print '<td class="linecoluseunit nowrap left">';
867 $label = $productstatic->getLabelOfUnit('short');
868 print $label;
869 print '</td>';
870 }
871
872 print '<td class="center">';
873 print price($line->pmp, 0, '', 1, -1, -1, $conf->currency);
874 print '</td>';
875
876 print '<td class="center">';
877 print price($line->pmp * $line->qty, 0, '', 1, -1, -1, $conf->currency);
878 print '</td>';
879
880 if (empty($object->status) && $permissiontoadd) {
881 if ($action === 'editline' && $line->id == $lineid) {
882 //print '<td class="right" colspan="2"><input type="submit" class="button" name="addline" value="' . dol_escape_htmltag($langs->trans('Save')) . '"></td>';
883 print '<td class="center valignmiddle" colspan="2"><input type="submit" class="button buttongen marginbottomonly" id="savelinebutton marginbottomonly" name="save" value="'.$langs->trans("Save").'"><br>';
884 print '<input type="submit" class="button buttongen marginbottomonly" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'"></td>';
885 } else {
886 print '<td class="right">';
887 print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=editline&amp;lineid=' . $line->id . '#line_' . $line->id . '">';
888 print img_edit() . '</a>';
889 print '</td>';
890 print '<td class="right">';
891 // Ensure the delete line link embeds a CSRF token.
892 $deleteLineUrl = $_SERVER["PHP_SELF"] . '?id=' . $id . '&action=deleteline&lineid=' . $line->id . '&token=' . newToken();
893 print '<a href="' . $deleteLineUrl . '">' . img_delete($langs->trans("Remove")) . '</a>';
894 print '</td>';
895 }
896
897 $num = count($object->lines);
898
899 if ($num > 1 && $conf->browser->layout != 'phone' && empty($disablemove)) {
900 print '<td class="linecolmove tdlineupdown center">';
901 if ($i > 0) { ?>
902 <a class="lineupdown" href="<?php print $_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=up&amp;rowid='.$line->id; ?>">
903 <?php print img_up('default', 0, 'imgupforline'); ?>
904 </a>
905 <?php }
906 if ($i < $num - 1) { ?>
907 <a class="lineupdown" href="<?php print $_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=down&amp;rowid='.$line->id; ?>">
908 <?php print img_down('default', 0, 'imgdownforline'); ?>
909 </a>
910 <?php }
911 print '</td>';
912 } else {
913 print '<td '.(($conf->browser->layout != 'phone' && empty($disablemove)) ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'></td>';
914 }
915 }
916
917 $i ++;
918 print '</tr>';
919 }
920
921 // Line to add a new line
922 if (empty($object->status) && $action !== 'editline' && $permissiontoadd) {
923 print '<tr class="oddeven">';
924 // Product
925 print '<td class="titlefield">';
926 $filtertype = 0;
927 if (getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
928 $filtertype = '';
929 }
930 if (getDolGlobalInt('PRODUIT_LIMIT_SIZE') <= 0) {
931 $limit = 0;
932 } else {
933 $limit = getDolGlobalInt('PRODUIT_LIMIT_SIZE');
934 }
935
936 $form->select_produits($fk_product, 'fk_product', $filtertype, $limit, 0, -1, 2, '', 0, array(), 0, 0, 0, 'minwidth200imp maxwidth300', 1);
937 print '</td>';
938 // Batch number
939 if (isModEnabled('productbatch')) {
940 print '<td>';
941 print '<input type="text" name="batch" class="flat maxwidth50" '.(!empty($error) ? 'value="'.$batch.'"' : '').'>';
942 print '</td>';
943 }
944
945 $formproduct->loadWarehouses(); // Pour charger la totalité des entrepôts
946
947 // Define a list of warehouse to not show on the list
948 $TExcludedWarehouseSource = array();
949 if (!empty($object->fk_warehouse_source)) {
950 $source_ent = new Entrepot($db);
951 $source_ent->fetch($object->fk_warehouse_source);
952 foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) {
953 if (strpos($TDataCacheWarehouse['full_label'], $source_ent->label) === false) {
954 $TExcludedWarehouseSource[] = $TDataCacheWarehouse['id'];
955 }
956 }
957 }
958
959 // Define a list of warehouse to not show on the list
960 $TExcludedWarehouseDestination = array();
961 if (!empty($object->fk_warehouse_destination)) {
962 $dest_ent = new Entrepot($db);
963 $dest_ent->fetch($object->fk_warehouse_destination);
964 foreach ($formproduct->cache_warehouses as $TDataCacheWarehouse) {
965 if (strpos($TDataCacheWarehouse['full_label'], $dest_ent->label) === false) {
966 $TExcludedWarehouseDestination[] = $TDataCacheWarehouse['id'];
967 }
968 }
969 }
970
971 // We clean array. It is filled automatically when calling function select_warehouses
972 $formproduct->cache_warehouses = array();
973 // In warehouse
974 print '<td>';
975 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);
976 print '</td>';
977
978 // We clean array. It is filled automatically when calling function select_warehouses
979 $formproduct->cache_warehouses = array();
980 // Out warehouse
981 print '<td>';
982 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);
983 print '</td>';
984
985 // Qty
986 print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" '.(!empty($error) ? 'value="'.(GETPOSTISSET('qty') ? GETPOST('qty') : $qty).'"' : '').'></td>';
987
988 // PMP
989 print '<td></td>';
990 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
991 // Unité
992 print '<td></td>';
993 }
994
995 // PMP * Qty
996 print '<td></td>';
997
998 // Button to add line
999 print '<td class="right" colspan="2"><input type="submit" class="button" name="addline" value="' . dol_escape_htmltag($langs->trans('Add')) . '"></td>';
1000
1001 // Grad and drop lines
1002 print '<td></td>';
1003
1004 print '</tr>';
1005 }
1006
1007 print '</table>';
1008 print '</form>';
1009 print '</div>';
1010
1011 print dol_get_fiche_end();
1012
1013
1014 // Buttons for actions
1015
1016 if ($action != 'presend' && $action != 'editline') {
1017 print '<div class="tabsAction">'."\n";
1018 $parameters = array();
1019 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1020 if ($reshook < 0) {
1021 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1022 }
1023
1024 if (empty($reshook)) {
1025 // Send
1026 if (empty($user->socid)) {
1027 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle');
1028 }
1029
1030 // Back to draft
1031 if ($object->status == $object::STATUS_VALIDATED) {
1032 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken(), '', $permissiontoadd);
1033 }
1034
1035 // Modify
1036 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd);
1037
1038 // Validate
1039 if ($object->status == $object::STATUS_DRAFT) {
1040 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
1041 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_validate&confirm=yes&token='.newToken(), '', $permissiontoadd);
1042 } else {
1043 $langs->load("errors");
1044 print dolGetButtonAction($langs->trans("ErrorAddAtLeastOneLineFirst"), $langs->trans("Validate"), 'default', '#', '', 0);
1045 }
1046 } elseif ($object->status == $object::STATUS_VALIDATED && $permissiontoadd) {
1047 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=destock&token='.newToken().'">'.$langs->trans("StockTransferDecrementation").'</a>';
1048 } elseif ($object->status == $object::STATUS_TRANSFERED && $permissiontoadd) {
1049 print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=destockcancel&token='.newToken().'">'.$langs->trans("StockTransferDecrementationCancel").'</a>';
1050 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=addstock&token='.newToken().'">'.$langs->trans("StockTransferIncrementation").'</a>';
1051 } elseif ($object->status == $object::STATUS_CLOSED && $permissiontoadd) {
1052 print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=addstockcancel&token='.newToken().'">'.$langs->trans("StockTransferIncrementationCancel").'</a>';
1053 }
1054
1055 // Clone
1056 if ($permissiontoadd) {
1057 print dolGetButtonAction('', $langs->trans('ToClone'), 'clone', $_SERVER['PHP_SELF'].'?id='.$object->id.(!empty($object->socid) ? '&socid='.$object->socid : '').'&action=clone&token='.newToken(), '', $permissiontoadd);
1058 }
1059
1060 /*
1061 if ($permissiontoadd) {
1062 if ($object->status == $object::STATUS_ENABLED) {
1063 print dolGetButtonAction('', $langs->trans('Disable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=disable&token='.newToken(), '', $permissiontoadd);
1064 } else {
1065 print dolGetButtonAction('', $langs->trans('Enable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=enable&token='.newToken(), '', $permissiontoadd);
1066 }
1067 }
1068 if ($permissiontoadd) {
1069 if ($object->status == $object::STATUS_VALIDATED) {
1070 print dolGetButtonAction('', $langs->trans('Cancel'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontoadd);
1071 } else {
1072 print dolGetButtonAction('', $langs->trans('Re-Open'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken(), '', $permissiontoadd);
1073 }
1074 }
1075
1076 */
1077
1078 // Delete (with preloaded confirm popup)
1079 $deleteUrl = $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken();
1080 $buttonId = 'action-delete-no-ajax';
1081 if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile)) { // We can use preloaded confirm if not jmobile
1082 $deleteUrl = '';
1083 $buttonId = 'action-delete';
1084 }
1085 $params = array();
1086 print dolGetButtonAction('', $langs->trans("Delete"), 'delete', $deleteUrl, $buttonId, $permissiontodelete, $params);
1087 }
1088 print '</div>'."\n";
1089 }
1090
1091
1092 // Select mail models is same action as presend
1093 if (GETPOST('modelselected')) {
1094 $action = 'presend';
1095 }
1096
1097 if ($action != 'presend') {
1098 print '<div class="fichecenter"><div class="fichehalfleft">';
1099 print '<a name="builddoc"></a>'; // ancre
1100
1101 $includedocgeneration = 1;
1102
1103 // Documents
1104 if ($includedocgeneration) {
1105 $objref = dol_sanitizeFileName($object->ref);
1106 $relativepath = $objref . '/' . $objref . '.pdf';
1107 $filedir = $conf->stocktransfer->dir_output.'/'.$object->element.'/'.$objref;
1108 $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id;
1109 $genallowed = $permissiontoread; // If you can read, you can build the PDF to read content
1110 $delallowed = $permissiontoadd; // If you can create/edit, you can remove a file on card
1111 print $formfile->showdocuments('stocktransfer:StockTransfer', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
1112 }
1113
1114 // Show links to link elements
1115 $tmparray = $form->showLinkToObjectBlock($object, array(), array('stocktransfer'), 1);
1116 $linktoelem = $tmparray['linktoelem'];
1117 $htmltoenteralink = $tmparray['htmltoenteralink'];
1118 print $htmltoenteralink;
1119
1120 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1121
1122
1123 print '</div><div class="fichehalfright">';
1124
1125 $MAXEVENT = 10;
1126
1127 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id);
1128
1129 // List of actions on element
1130 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1131 $formactions = new FormActions($db);
1132 $somethingshown = $formactions->showactions($object, 'stocktransfer', 0, 1, '', $MAXEVENT, '');
1133
1134 print '</div></div>';
1135 }
1136
1137 //Select mail models is same action as presend
1138 if (GETPOST('modelselected')) {
1139 $action = 'presend';
1140 }
1141
1142 // Presend form
1143 $modelmail = 'stocktransfer_send';
1144 $defaulttopic = 'InformationMessage';
1145 $diroutput = $conf->stocktransfer->dir_output.'/'.$object->element;
1146 $trackid = 'stocktransfer'.$object->id;
1147
1148 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1149}
1150
1151// End of page
1152llxFooter();
1153$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.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
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.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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:487
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.