dolibarr 21.0.3
shipment.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2012 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012-2015 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2018-2022 Philippe Grand <philippe.grand@atoo-net.com>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Load Dolibarr environment
31require '../main.inc.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
33require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
34require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php';
37require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
38if (isModEnabled('project')) {
39 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
41}
42if (isModEnabled('stock')) {
43 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
44}
45if (isModEnabled("propal")) {
46 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
47}
48if (isModEnabled("product") || isModEnabled("service")) {
49 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
50}
51
61// Load translation files required by the page
62$langs->loadLangs(array('orders', 'sendings', 'companies', 'bills', 'propal', 'deliveries', 'stocks', 'productbatch', 'incoterm', 'other'));
63
64$id = GETPOSTINT('id'); // id of order
65$ref = GETPOST('ref', 'alpha');
66$action = GETPOST('action', 'aZ09');
67
68$hookmanager->initHooks(array('ordershipmentcard'));
69
70
71// Security check
72$socid = 0;
73if (!empty($user->socid)) {
74 $socid = $user->socid;
75}
76$result = restrictedArea($user, 'commande', $id);
77
78$object = new Commande($db);
79$shipment = new Expedition($db);
80$extrafields = new ExtraFields($db);
81
82// fetch optionals attributes and labels
83$extrafields->fetch_name_optionals_label($object->table_element);
84
85// Load object
86include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'
87
88// Security check
89if ($user->socid) {
90 $socid = $user->socid;
91}
92
93$result = restrictedArea($user, 'expedition', 0, ''); // We use 0 for id, because there is no particular shipment on this tab, only id of order is known
94
95$permissiontoread = $user->hasRight('expedition', 'lire');
96$permissiontoadd = $user->hasRight('expedition', 'creer'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
97$permissiontodelete = $user->hasRight('expedition', 'supprimer') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
98$permissionnote = $user->hasRight('expedition', 'creer'); // Used by the include of actions_setnotes.inc.php
99$permissiondellink = $user->hasRight('expedition', 'creer'); // Used by the include of actions_dellink.inc.php
100
101
102/*
103 * Actions
104 */
105$error = 0;
106$parameters = array('socid' => $socid);
107$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
108if ($reshook < 0) {
109 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
110}
111
112if (empty($reshook)) {
113 // Categorisation dans projet
114 if ($action == 'classin' && $permissiontoadd) {
115 $object->fetch($id);
116 $object->setProject(GETPOSTINT('projectid'));
117 }
118
119 if ($action == 'confirm_cloture' && GETPOST('confirm', 'alpha') == 'yes' && $permissiontoadd) {
120 $object->fetch($id);
121 $result = $object->cloture($user);
122 } elseif ($action == 'setref_client' && $permissiontoadd) {
123 // Positionne ref commande client
124 $result = $object->set_ref_client($user, GETPOST('ref_client'));
125 if ($result < 0) {
126 setEventMessages($object->error, $object->errors, 'errors');
127 }
128 }
129
130 if ($action == 'setdatedelivery' && $permissiontoadd) {
131 $datedelivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
132
133 $object->fetch($id);
134 $result = $object->setDeliveryDate($user, $datedelivery);
135 if ($result < 0) {
136 setEventMessages($object->error, $object->errors, 'errors');
137 }
138 }
139 if ($action == 'setmode' && $permissiontoadd) {
140 $object->fetch($id);
141 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
142 if ($result < 0) {
143 setEventMessages($object->error, $object->errors, 'errors');
144 }
145 }
146
147 if ($action == 'setavailability' && $permissiontoadd) {
148 $object->fetch($id);
149 $result = $object->availability(GETPOST('availability_id'));
150 if ($result < 0) {
151 setEventMessages($object->error, $object->errors, 'errors');
152 }
153 }
154
155 if ($action == 'setdemandreason' && $permissiontoadd) {
156 $object->fetch($id);
157 $result = $object->demand_reason(GETPOST('demand_reason_id'));
158 if ($result < 0) {
159 setEventMessages($object->error, $object->errors, 'errors');
160 }
161 }
162
163 if ($action == 'setconditions' && $permissiontoadd) {
164 $object->fetch($id);
165 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'));
166 if ($result < 0) {
167 setEventMessages($object->error, $object->errors, 'errors');
168 }
169 } elseif ($action == 'set_incoterms' && isModEnabled('incoterm')) {
170 // Set incoterm
171 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
172 if ($result < 0) {
173 setEventMessages($object->error, $object->errors, 'errors');
174 }
175 }
176
177 // shipping method
178 if ($action == 'setshippingmethod' && $permissiontoadd) {
179 $object->fetch($id);
180 $result = $object->setShippingMethod(GETPOSTINT('shipping_method_id'));
181 if ($result < 0) {
182 setEventMessages($object->error, $object->errors, 'errors');
183 }
184 }
185
186 // warehouse
187 if ($action == 'setwarehouse' && $permissiontoadd) {
188 $object->fetch($id);
189 $result = $object->setWarehouse(GETPOSTINT('warehouse_id'));
190 if ($result < 0) {
191 setEventMessages($object->error, $object->errors, 'errors');
192 }
193 }
194
195 if ($action == 'update_extras' && $permissiontoadd) {
196 $object->oldcopy = dol_clone($object, 2);
197
198 // Fill array 'array_options' with data from update form
199 $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
200 if ($ret < 0) {
201 $error++;
202 }
203
204 if (!$error) {
205 // Actions on extra fields
206 $result = $object->insertExtraFields('SHIPMENT_MODIFY');
207 if ($result < 0) {
208 setEventMessages($object->error, $object->errors, 'errors');
209 $error++;
210 }
211 }
212
213 if ($error) {
214 $action = 'edit_extras';
215 }
216 }
217
218 if ($action == 'set_thirdparty' && $permissiontoadd) {
219 $object->fetch($id);
220 $object->setValueFrom('fk_soc', $socid, '', null, 'date', '', $user, 'ORDER_MODIFY');
221
222 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
223 exit();
224 }
225
226 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
227}
228
229
230/*
231 * View
232 */
233
234$form = new Form($db);
235$formfile = new FormFile($db);
236$formproduct = new FormProduct($db);
237if (isModEnabled('project')) {
238 $formproject = new FormProjets($db);
239}
240
241$title = $object->ref." - ".$langs->trans('Shipments');
242$help_url = 'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes|DE:Modul_Kundenaufträge';
243llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-expedition page-shipment');
244
245
246if ($id > 0 || !empty($ref)) {
247 $object = new Commande($db);
248 if ($object->fetch($id, $ref) > 0) {
249 $object->loadExpeditions(1);
250
251 $product_static = new Product($db);
252
253 $soc = new Societe($db);
254 $soc->fetch($object->socid);
255
256 $author = new User($db);
257 $author->fetch($object->user_author_id);
258
259 $head = commande_prepare_head($object);
260 print dol_get_fiche_head($head, 'shipping', $langs->trans("CustomerOrder"), -1, 'order');
261
262
263 $formconfirm = '';
264
265 // Confirm validation
266 if ($action == 'cloture') {
267 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".urlencode((string) ($id)), $langs->trans("CloseShipment"), $langs->trans("ConfirmCloseShipment"), "confirm_cloture");
268 }
269
270 // Call Hook formConfirm
271 $parameters = array('formConfirm' => $formconfirm);
272 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
273 if (empty($reshook)) {
274 $formconfirm .= $hookmanager->resPrint;
275 } elseif ($reshook > 0) {
276 $formconfirm = $hookmanager->resPrint;
277 }
278
279 // Print form confirm
280 print $formconfirm;
281
282
283 // Order card
284
285 $linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '?socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
286
287
288 $morehtmlref = '<div class="refidno">';
289 // Ref customer
290 $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_customer', $object->ref_client, $object, $permissiontoadd, 'string', '', 0, 1);
291 $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_customer', $object->ref_client, $object, $permissiontoadd, 'string', '', null, null, '', 1);
292 // Thirdparty
293 $morehtmlref .= '<br>'.$soc->getNomUrl(1);
294 // Project
295 if (isModEnabled('project')) {
296 $langs->load("projects");
297 $morehtmlref .= '<br>';
298 if (0) { // Do not change on shipment
299 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
300 if ($action != 'classify') {
301 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
302 }
303 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
304 } else {
305 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
306 $proj = new Project($db);
307 $proj->fetch($objectsrc->fk_project);
308 $morehtmlref .= $proj->getNomUrl(1);
309 if ($proj->title) {
310 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
311 }
312 }
313 }
314 }
315 $morehtmlref .= '</div>';
316
317
318 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
319
320
321 print '<div class="fichecenter">';
322 print '<div class="fichehalfleft">';
323 print '<div class="underbanner clearboth"></div>';
324
325 print '<table class="border centpercent tableforfield">';
326
327 // Discounts for third party
328 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
329 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
330 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
331 } else {
332 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
333 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
334 }
335
336 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td colspan="2">';
337
338 $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
339 $absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote);
340 $absolute_discount = price2num($absolute_discount, 'MT');
341 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
342
343 $thirdparty = $soc;
344 $discount_type = 0;
345 $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
346 $cannotApplyDiscount = 1;
347 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
348 print '</td></tr>';
349
350 // Date
351 print '<tr><td>'.$langs->trans('Date').'</td>';
352 print '<td colspan="2">';
353 print dol_print_date($object->date, 'day');
354 if ($object->hasDelay() && empty($object->delivery_date)) { // If there is a delivery date planned, warning should be on this date
355 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
356 }
357 print '</td>';
358 print '</tr>';
359
360 // Delivery date planned
361 print '<tr><td height="10">';
362 print '<table class="nobordernopadding" width="100%"><tr><td>';
363 print $langs->trans('DateDeliveryPlanned');
364 print '</td>';
365
366 if ($action != 'editdate_livraison') {
367 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editdate_livraison&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetDeliveryDate'), 1).'</a></td>';
368 }
369 print '</tr></table>';
370 print '</td><td colspan="2">';
371 if ($action == 'editdate_livraison') {
372 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
373 print '<input type="hidden" name="token" value="'.newToken().'">';
374 print '<input type="hidden" name="action" value="setdatedelivery">';
375 print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
376 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
377 print '</form>';
378 } else {
379 print dol_print_date($object->delivery_date, 'dayhour');
380 if ($object->hasDelay() && !empty($object->delivery_date)) {
381 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
382 }
383 }
384 print '</td>';
385 print '</tr>';
386
387 // Delivery delay
388 print '<tr><td height="10">';
389 print '<table class="nobordernopadding" width="100%"><tr><td>';
390 print $langs->trans('AvailabilityPeriod');
391 print '</td>';
392 if ($action != 'editavailability') {
393 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editavailability&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetAvailability'), 1).'</a></td>';
394 }
395 print '</tr></table>';
396 print '</td><td colspan="2">';
397 if ($action == 'editavailability') {
398 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1);
399 } else {
400 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1);
401 }
402 print '</td></tr>';
403
404 // Shipping Method
405 print '<tr><td>';
406 print '<table width="100%" class="nobordernopadding"><tr><td>';
407 print $langs->trans('SendingMethod');
408 print '</td>';
409 if ($action != 'editshippingmethod' && $user->hasRight('expedition', 'creer')) {
410 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editshippingmethod&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetShippingMode'), 1).'</a></td>';
411 }
412 print '</tr></table>';
413 print '</td><td colspan="2">';
414 if ($action == 'editshippingmethod') {
415 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1);
416 } else {
417 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none');
418 }
419 print '</td>';
420 print '</tr>';
421
422 // Warehouse
423 if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
424 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
425 $formproduct = new FormProduct($db);
426 print '<tr><td>';
427 print '<table width="100%" class="nobordernopadding"><tr><td>';
428 print $langs->trans('Warehouse');
429 print '</td>';
430 if ($action != 'editwarehouse' && $permissiontoadd) {
431 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editwarehouse&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetWarehouse'), 1).'</a></td>';
432 }
433 print '</tr></table>';
434 print '</td><td colspan="2">';
435 if ($action == 'editwarehouse') {
436 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'warehouse_id', 1);
437 } else {
438 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'none');
439 }
440 print '</td>';
441 print '</tr>';
442 }
443
444 // Source reason (why we have an order)
445 print '<tr><td height="10">';
446 print '<table class="nobordernopadding" width="100%"><tr><td>';
447 print $langs->trans('Source');
448 print '</td>';
449 if ($action != 'editdemandreason') {
450 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editdemandreason&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetDemandReason'), 1).'</a></td>';
451 }
452 print '</tr></table>';
453 print '</td><td colspan="2">';
454 if ($action == 'editdemandreason') {
455 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1);
456 } else {
457 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none');
458 }
459
460 // Terms of payment
461 /*
462 print '<tr><td height="10">';
463 print '<table class="nobordernopadding" width="100%"><tr><td>';
464 print $langs->trans('PaymentConditionsShort');
465 print '</td>';
466
467 if ($action != 'editconditions' && $object->statut == Expedition::STATUS_VALIDATED) print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetConditions'),1).'</a></td>';
468 print '</tr></table>';
469 print '</td><td colspan="2">';
470 if ($action == 'editconditions')
471 {
472 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'cond_reglement_id');
473 }
474 else
475 {
476 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'none');
477 }
478 print '</td></tr>';
479
480 // Mode of payment
481 print '<tr><td>';
482 print '<table class="nobordernopadding" width="100%"><tr><td>';
483 print $langs->trans('PaymentMode');
484 print '</td>';
485 if ($action != 'editmode' && $object->statut == Expedition::STATUS_VALIDATED) print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetMode'),1).'</a></td>';
486 print '</tr></table>';
487 print '</td><td colspan="2">';
488 if ($action == 'editmode')
489 {
490 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'mode_reglement_id');
491 }
492 else
493 {
494 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'none');
495 }
496 print '</td></tr>';*/
497
498 $tmparray = $object->getTotalWeightVolume();
499 $totalWeight = $tmparray['weight'];
500 $totalVolume = $tmparray['volume'];
501 if ($totalWeight || $totalVolume) {
502 print '<tr><td>'.$langs->trans("CalculatedWeight").'</td>';
503 print '<td colspan="2">';
504 print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, getDolGlobalInt('MAIN_WEIGHT_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_WEIGHT_DEFAULT_UNIT', 'no'));
505 print '</td></tr>';
506 print '<tr><td>'.$langs->trans("CalculatedVolume").'</td>';
507 print '<td colspan="2">';
508 print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_VOLUME_DEFAULT_UNIT', 'no'));
509 print '</td></tr>';
510 }
511
512 // TODO How record was recorded OrderMode (llx_c_input_method)
513
514 // Incoterms
515 if (isModEnabled('incoterm')) {
516 print '<tr><td>';
517 print '<table width="100%" class="nobordernopadding"><tr><td>';
518 print $langs->trans('IncotermLabel');
519 print '<td><td class="right">';
520 if ($permissiontoadd) {
521 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'/expedition/shipment.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
522 } else {
523 print '&nbsp;';
524 }
525 print '</td></tr></table>';
526 print '</td>';
527 print '<td colspan="2">';
528 if ($action != 'editincoterm') {
529 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
530 } else {
531 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
532 }
533 print '</td></tr>';
534 }
535
536 $expe = new Expedition($db);
537 $extrafields->fetch_name_optionals_label($expe->table_element);
538
539 // Other attributes
540 $cols = 2;
541 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
542
543 print '</table>';
544
545 print '</div>';
546 print '<div class="fichehalfright">';
547 print '<div class="underbanner clearboth"></div>';
548
549 print '<table class="border centpercent tableforfield">';
550
551 if (isModEnabled("multicurrency") && ($object->multicurrency_code != $conf->currency)) {
552 // Multicurrency Amount HT
553 print '<tr><td class="titlefieldmiddle">'.$form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0).'</td>';
554 print '<td class="nowrap">'.price($object->multicurrency_total_ht, 0, $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'</td>';
555 print '</tr>';
556
557 // Multicurrency Amount VAT
558 print '<tr><td>'.$form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0).'</td>';
559 print '<td class="nowrap">'.price($object->multicurrency_total_tva, 0, $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'</td>';
560 print '</tr>';
561
562 // Multicurrency Amount TTC
563 print '<tr><td>'.$form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0).'</td>';
564 print '<td class="nowrap">'.price($object->multicurrency_total_ttc, 0, $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'</td>';
565 print '</tr>';
566 }
567
568 // Total HT
569 print '<tr><td class="titlefieldmiddle">'.$langs->trans('AmountHT').'</td>';
570 print '<td>'.price($object->total_ht, 0, '', 1, -1, -1, $conf->currency).'</td>';
571 print '</tr>';
572
573 // Total VAT
574 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($object->total_tva, 0, '', 1, -1, -1, $conf->currency).'</td>';
575 print '</tr>';
576
577 // Amount Local Taxes
578 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { // Localtax1
579 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td>';
580 print '<td>'.price($object->total_localtax1, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
581 }
582 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { // Localtax2 IRPF
583 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td>';
584 print '<td>'.price($object->total_localtax2, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
585 }
586
587 // Total TTC
588 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($object->total_ttc, 0, '', 1, -1, -1, $conf->currency).'</td>';
589 print '</tr>';
590
591 print '</table>';
592
593 print '</div>';
594 print '</div>';
595
596 print '<div class="clearboth"></div><br>';
597
598
603 print '<div class="div-table-responsive-no-min">';
604 print '<table id="tablelines" class="noborder noshadow centpercent">';
605
606 $sql = "SELECT cd.rowid, cd.fk_product, cd.product_type as type, cd.label, cd.description,";
607 $sql .= " cd.price, cd.tva_tx, cd.subprice,";
608 $sql .= " cd.qty, cd.fk_unit, cd.rang,";
609 $sql .= ' cd.date_start,';
610 $sql .= ' cd.date_end,';
611 $sql .= ' cd.special_code,';
612 $sql .= ' p.rowid as prodid, p.label as product_label, p.entity, p.ref, p.fk_product_type as product_type, p.description as product_desc,';
613 $sql .= ' p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units,';
614 $sql .= ' p.surface, p.surface_units, p.volume, p.volume_units';
615 $sql .= ', p.tobatch, p.tosell, p.tobuy, p.barcode';
616 $sql .= ', u.short_label as unit_order';
617 $sql .= " FROM ".MAIN_DB_PREFIX."commandedet as cd";
618 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid";
619 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_units as u ON cd.fk_unit = u.rowid";
620 $sql .= " WHERE cd.fk_commande = ".((int) $object->id);
621 $sql .= " ORDER BY cd.rang, cd.rowid";
622
623 //print $sql;
624 dol_syslog("shipment.php", LOG_DEBUG);
625 $resql = $db->query($sql);
626 if ($resql) {
627 $num = $db->num_rows($resql);
628 $i = 0;
629 print '<thead>';
630 print '<tr class="liste_titre">';
631 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
632 print '<th>'.$langs->trans("Rank").'</th>';
633 }
634 print '<th>'.$langs->trans("Description").'</th>';
635 print '<th class="center">'.$langs->trans("QtyOrdered").'</th>';
636 print '<th class="center">'.$langs->trans("QtyShipped").'</th>';
637 print '<th class="center">'.$langs->trans("KeepToShip").'</th>';
638 if (isModEnabled('stock')) {
639 print '<th class="center">'.$langs->trans("RealStock").'</th>';
640 } else {
641 print '<th>&nbsp;</th>';
642 }
643 print "</tr>\n";
644 print '</thead>';
645
646 $toBeShipped = array();
647 $toBeShippedTotal = 0;
648 while ($i < $num) {
649 $objp = $db->fetch_object($resql);
650
651 $parameters = array('i' => $i, 'line' => $objp, 'num' => $num);
652 $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $object, $action);
653 if ($reshook < 0) {
654 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
655 }
656
657 if (empty($reshook)) {
658 // Show product and description
659 $type = isset($objp->type) ? $objp->type : $objp->product_type;
660
661 // Try to enhance type detection using date_start and date_end for free lines where type
662 // was not saved.
663 if (!empty($objp->date_start)) {
664 $type = 1;
665 }
666 if (!empty($objp->date_end)) {
667 $type = 1;
668 }
669
670 print '<tr class="oddeven">';
671
672 // Rank
673 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
674 print '<td class="center">'.$objp->rang.'</td>';
675 }
676
677 // Product label
678 if ($objp->fk_product > 0) {
679 // Define output language
680 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
681 $object->fetch_thirdparty();
682
683 $prod = new Product($db);
684 $prod->id = $objp->fk_product;
685 $prod->entity = $objp->entity;
686 $prod->getMultiLangs();
687
688 $outputlangs = $langs;
689 $newlang = '';
690 if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
691 $newlang = GETPOST('lang_id', 'aZ09');
692 }
693 if (empty($newlang)) {
694 $newlang = $object->thirdparty->default_lang;
695 }
696 if (!empty($newlang)) {
697 $outputlangs = new Translate("", $conf);
698 $outputlangs->setDefaultLang($newlang);
699 }
700
701 $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $objp->product_label;
702 } else {
703 $label = (!empty($objp->label) ? $objp->label : $objp->product_label);
704 }
705
706 print '<td>';
707 print '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne
708
709 // Show product and description
710 $product_static->type = $type;
711 $product_static->id = $objp->fk_product;
712 $product_static->ref = $objp->ref;
713 $product_static->entity = $objp->entity;
714 $product_static->status = $objp->tosell;
715 $product_static->status_buy = $objp->tobuy;
716 $product_static->status_batch = $objp->tobatch;
717 $product_static->barcode = $objp->barcode;
718
719 $product_static->weight = $objp->weight;
720 $product_static->weight_units = $objp->weight_units;
721 $product_static->length = $objp->length;
722 $product_static->length_units = $objp->length_units;
723 $product_static->width = $objp->width;
724 $product_static->width_units = $objp->width_units;
725 $product_static->height = $objp->height;
726 $product_static->height_units = $objp->height_units;
727 $product_static->surface = $objp->surface;
728 $product_static->surface_units = $objp->surface_units;
729 $product_static->volume = $objp->volume;
730 $product_static->volume_units = $objp->volume_units;
731
732 $text = $product_static->getNomUrl(1);
733 $text .= ' - '.$label;
734 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($objp->description)).'<br>';
735 $description .= $product_static->show_photos('product', $conf->product->multidir_output[$product_static->entity], 1, 1, 0, 0, 0, 80);
736 print $form->textwithtooltip($text, $description, 3, '', '', $i);
737
738 // Show range
739 print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end));
740
741 // Add description in form
742 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
743 print ($objp->description && $objp->description != $objp->product_label) ? '<br>'.dol_htmlentitiesbr($objp->description) : '';
744 }
745
746 print '</td>';
747 } else {
748 print "<td>";
749 if ($type == 1) {
750 $text = img_object($langs->trans('Service'), 'service');
751 } else {
752 $text = img_object($langs->trans('Product'), 'product');
753 }
754
755 if (!empty($objp->label)) {
756 $text .= ' <strong>'.$objp->label.'</strong>';
757 print $form->textwithtooltip($text, $objp->description, 3, '', '', $i);
758 } else {
759 print $text.' '.nl2br($objp->description);
760 }
761
762 // Show range
763 print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end));
764 print "</td>\n";
765 }
766
767 // Qty ordered
768 print '<td class="center">'.$objp->qty.($objp->unit_order ? ' '.$objp->unit_order : '').'</td>';
769
770 // Qty already shipped
771 $qtyProdCom = $objp->qty;
772 print '<td class="center">';
773 // Nb of sending products for this line of order
774 $qtyAlreadyShipped = (!empty($object->expeditions[$objp->rowid]) ? $object->expeditions[$objp->rowid] : 0);
775 print $qtyAlreadyShipped;
776 print($objp->unit_order ? ' '.$objp->unit_order : '').'</td>';
777
778 // Qty remains to ship
779 print '<td class="center">';
780 if ($type == 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES') || getDolGlobalString('SHIPMENT_SUPPORTS_SERVICES')) {
781 $toBeShipped[$objp->fk_product] = $objp->qty - $qtyAlreadyShipped;
782 $toBeShippedTotal += $toBeShipped[$objp->fk_product];
783 print $toBeShipped[$objp->fk_product];
784 } else {
785 print '0 <span class="opacitymedium">('.$langs->trans("Service").')</span>';
786 }
787 print($objp->unit_order ? ' '.$objp->unit_order : '').'</td>';
788
789 if ($objp->fk_product > 0) {
790 $product = new Product($db);
791 $product->fetch($objp->fk_product);
792 $product->load_stock('warehouseopen');
793 }
794
795 if ($objp->fk_product > 0 && ($type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) && isModEnabled('stock')) {
796 print '<td class="center">';
797 print $product->stock_reel;
798 if ($product->stock_reel < $toBeShipped[$objp->fk_product]) {
799 print ' '.img_warning($langs->trans("StockTooLow"));
800 if (getDolGlobalString('STOCK_CORRECT_STOCK_IN_SHIPMENT')) {
801 $nbPiece = $toBeShipped[$objp->fk_product] - $product->stock_reel;
802 print ' &nbsp; '.$langs->trans("GoTo").' <a href="'.DOL_URL_ROOT.'/product/stock/product.php?id='.((int) $product->id).'&action=correction&token='.newToken().'&nbpiece='.urlencode((string) ($nbPiece)).'&backtopage='.urlencode((string) ($_SERVER["PHP_SELF"].'?id='.((int) $object->id))).'">'.$langs->trans("CorrectStock").'</a>';
803 }
804 }
805 print '</td>';
806 } elseif ($objp->fk_product > 0 && $type == Product::TYPE_SERVICE && getDolGlobalString('SHIPMENT_SUPPORTS_SERVICES') && isModEnabled('stock')) {
807 print '<td class="center"><span class="opacitymedium">('.$langs->trans("Service").')</span></td>';
808 } else {
809 print '<td>&nbsp;</td>';
810 }
811 print "</tr>\n";
812
813 // Show subproducts lines
814 if ($objp->fk_product > 0 && getDolGlobalString('PRODUIT_SOUSPRODUITS')) {
815 // Set tree of subproducts in product->sousprods
816 $product->get_sousproduits_arbo();
817 //var_dump($product->sousprods);exit;
818
819 // Define a new tree with quantiies recalculated
820 $prods_arbo = $product->get_arbo_each_prod($qtyProdCom);
821 //var_dump($prods_arbo);
822 if (count($prods_arbo) > 0) {
823 foreach ($prods_arbo as $key => $value) {
824 $img = '';
825 if ($value['stock'] < $value['stock_alert']) {
826 $img = img_warning($langs->trans("StockTooLow"));
827 }
828 print '<tr class="oddeven"><td>&nbsp; &nbsp; &nbsp; -> <a href="'.DOL_URL_ROOT."/product/card.php?id=".$value['id'].'">'.$value['fullpath'].'</a> ('.$value['nb'].')</td>';
829 print '<td class="center"> '.$value['nb_total'].'</td>';
830 print '<td>&nbsp;</td>';
831 print '<td>&nbsp;</td>';
832 print '<td class="center">'.$value['stock'].' '.$img.'</td></tr>'."\n";
833 }
834 }
835 }
836 }
837 $i++;
838 }
839 $db->free($resql);
840
841 if (!$num) {
842 print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("NoArticleOfTypeProduct").'</span></td></tr>';
843 }
844 } else {
845 dol_print_error($db);
846 }
847
848 print "</table>";
849 print '</div>';
850
851
852 /*
853 * Boutons Actions
854 */
855
856 if (empty($user->socid)) {
857 print '<div class="tabsAction">';
858
859 // Bouton expedier sans gestion des stocks
860 if (!isModEnabled('stock') && ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED)) {
861 if ($user->hasRight('expedition', 'creer')) {
862 print '<a class="butAction" href="'.DOL_URL_ROOT.'/expedition/card.php?action=create&amp;origin=commande&amp;object_id='.$id.'">'.$langs->trans("CreateShipment").'</a>';
863 if ($toBeShippedTotal <= 0) {
864 print ' '.img_warning($langs->trans("WarningNoQtyLeftToSend"));
865 }
866 } else {
867 print '<a class="butActionRefused classfortooltip" href="#">'.$langs->trans("CreateShipment").'</a>';
868 }
869 }
870 print "</div>";
871 }
872
873
874 // Button to create a shipment
875
876 if (isModEnabled('stock') && $object->statut == Commande::STATUS_DRAFT) {
877 print $langs->trans("ValidateOrderFirstBeforeShipment");
878 }
879
880 if (isModEnabled('stock') && ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED)) {
881 if ($user->hasRight('expedition', 'creer')) {
882 //print load_fiche_titre($langs->trans("CreateShipment"));
883 print '<div class="tabsAction">';
884
885 print '<form method="GET" action="'.DOL_URL_ROOT.'/expedition/card.php">';
886 print '<input type="hidden" name="action" value="create">';
887 //print '<input type="hidden" name="id" value="'.$object->id.'">';
888 print '<input type="hidden" name="shipping_method_id" value="'.$object->shipping_method_id.'">';
889 print '<input type="hidden" name="origin" value="commande">';
890 print '<input type="hidden" name="origin_id" value="'.$object->id.'">';
891 print '<input type="hidden" name="projectid" value="'.$object->fk_project.'">';
892 //print '<table class="border centpercent">';
893
894 $langs->load("stocks");
895
896 //print '<tr>';
897
898 if (isModEnabled('stock')) {
899 //print '<td>';
900 print $langs->trans("WarehouseSource");
901 //print '</td>';
902 //print '<td>';
903 print $formproduct->selectWarehouses(!empty($object->warehouse_id) ? $object->warehouse_id : 'ifone', 'entrepot_id', '', 1, 0, 0, '', 0, 0, array(), 'minwidth200');
904 if (count($formproduct->cache_warehouses) <= 0) {
905 print ' &nbsp; '.$langs->trans("WarehouseSourceNotDefined").' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create">'.$langs->trans("AddOne").'</a>';
906 }
907 //print '</td>';
908 }
909 //print '<td class="center">';
910 print '<input type="submit" class="butAction" named="save" value="'.$langs->trans("CreateShipment").'">';
911 if ($toBeShippedTotal <= 0) {
912 print ' '.img_warning($langs->trans("WarningNoQtyLeftToSend"));
913 }
914 //print '</td></tr>';
915
916 //print "</table>";
917 print "</form>\n";
918
919 print '</div>';
920
921 $somethingshown = 1;
922 } else {
923 print '<div class="tabsAction">';
924 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("CreateShipment").'</a>';
925 print '</div>';
926 }
927 }
928
929 show_list_sending_receive('commande', $object->id);
930 } else {
931 /* Order not found */
932 setEventMessages($langs->trans("NonExistentOrder"), null, 'errors');
933 }
934}
935
936// End of page
937llxFooter();
938$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
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:71
Class to manage customers orders.
const STATUS_CLOSED
Closed (Sent, billed or not)
const STATUS_DRAFT
Draft status.
Class to manage standard extra fields.
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.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
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.
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)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=-1, $forceunitoutput='no', $use_short_label=0)
Output a dimension with best unit.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
print_date_range($date_start, $date_end, $format='', $outputlangs=null)
Format output for start and end date.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_clone($object, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
commande_prepare_head(Commande $object)
Prepare array with list of tabs.
Definition order.lib.php:35
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
show_list_sending_receive($origin, $origin_id, $filter='')
List sendings and receive receipts.