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