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