dolibarr 20.0.5
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'), GETPOST('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 $head = commande_prepare_head($object);
249 print dol_get_fiche_head($head, 'shipping', $langs->trans("CustomerOrder"), -1, 'order');
250
251
252 $formconfirm = '';
253
254 // Confirm validation
255 if ($action == 'cloture') {
256 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".urlencode((string) ($id)), $langs->trans("CloseShipment"), $langs->trans("ConfirmCloseShipment"), "confirm_cloture");
257 }
258
259 // Call Hook formConfirm
260 $parameters = array('formConfirm' => $formconfirm);
261 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
262 if (empty($reshook)) {
263 $formconfirm .= $hookmanager->resPrint;
264 } elseif ($reshook > 0) {
265 $formconfirm = $hookmanager->resPrint;
266 }
267
268 // Print form confirm
269 print $formconfirm;
270
271
272 // Order card
273
274 $linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '?socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
275
276
277 $morehtmlref = '<div class="refidno">';
278 // Ref customer
279 $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_customer', $object->ref_client, $object, $permissiontoadd, 'string', '', 0, 1);
280 $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_customer', $object->ref_client, $object, $permissiontoadd, 'string', '', null, null, '', 1);
281 // Thirdparty
282 $morehtmlref .= '<br>'.$soc->getNomUrl(1);
283 // Project
284 if (isModEnabled('project')) {
285 $langs->load("projects");
286 $morehtmlref .= '<br>';
287 if (0) { // Do not change on shipment
288 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
289 if ($action != 'classify') {
290 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
291 }
292 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
293 } else {
294 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
295 $proj = new Project($db);
296 $proj->fetch($objectsrc->fk_project);
297 $morehtmlref .= $proj->getNomUrl(1);
298 if ($proj->title) {
299 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
300 }
301 }
302 }
303 }
304 $morehtmlref .= '</div>';
305
306
307 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
308
309
310 print '<div class="fichecenter">';
311 print '<div class="fichehalfleft">';
312 print '<div class="underbanner clearboth"></div>';
313
314 print '<table class="border centpercent tableforfield">';
315
316 // Discounts for third party
317 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
318 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
319 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
320 } else {
321 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
322 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
323 }
324
325 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td colspan="2">';
326
327 $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
328 $absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote);
329 $absolute_discount = price2num($absolute_discount, 'MT');
330 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
331
332 $thirdparty = $soc;
333 $discount_type = 0;
334 $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
335 $cannotApplyDiscount = 1;
336 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
337 print '</td></tr>';
338
339 // Date
340 print '<tr><td>'.$langs->trans('Date').'</td>';
341 print '<td colspan="2">';
342 print dol_print_date($object->date, 'day');
343 if ($object->hasDelay() && empty($object->delivery_date)) { // If there is a delivery date planned, warning should be on this date
344 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
345 }
346 print '</td>';
347 print '</tr>';
348
349 // Delivery date planned
350 print '<tr><td height="10">';
351 print '<table class="nobordernopadding" width="100%"><tr><td>';
352 print $langs->trans('DateDeliveryPlanned');
353 print '</td>';
354
355 if ($action != 'editdate_livraison') {
356 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>';
357 }
358 print '</tr></table>';
359 print '</td><td colspan="2">';
360 if ($action == 'editdate_livraison') {
361 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
362 print '<input type="hidden" name="token" value="'.newToken().'">';
363 print '<input type="hidden" name="action" value="setdatedelivery">';
364 print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
365 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
366 print '</form>';
367 } else {
368 print dol_print_date($object->delivery_date, 'dayhour');
369 if ($object->hasDelay() && !empty($object->delivery_date)) {
370 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
371 }
372 }
373 print '</td>';
374 print '</tr>';
375
376 // Delivery delay
377 print '<tr><td height="10">';
378 print '<table class="nobordernopadding" width="100%"><tr><td>';
379 print $langs->trans('AvailabilityPeriod');
380 print '</td>';
381 if ($action != 'editavailability') {
382 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>';
383 }
384 print '</tr></table>';
385 print '</td><td colspan="2">';
386 if ($action == 'editavailability') {
387 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1);
388 } else {
389 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1);
390 }
391 print '</td></tr>';
392
393 // Shipping Method
394 print '<tr><td>';
395 print '<table width="100%" class="nobordernopadding"><tr><td>';
396 print $langs->trans('SendingMethod');
397 print '</td>';
398 if ($action != 'editshippingmethod' && $user->hasRight('expedition', 'creer')) {
399 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>';
400 }
401 print '</tr></table>';
402 print '</td><td colspan="2">';
403 if ($action == 'editshippingmethod') {
404 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1);
405 } else {
406 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none');
407 }
408 print '</td>';
409 print '</tr>';
410
411 // Warehouse
412 if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
413 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
414 $formproduct = new FormProduct($db);
415 print '<tr><td>';
416 print '<table width="100%" class="nobordernopadding"><tr><td>';
417 print $langs->trans('Warehouse');
418 print '</td>';
419 if ($action != 'editwarehouse' && $permissiontoadd) {
420 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>';
421 }
422 print '</tr></table>';
423 print '</td><td colspan="2">';
424 if ($action == 'editwarehouse') {
425 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'warehouse_id', 1);
426 } else {
427 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'none');
428 }
429 print '</td>';
430 print '</tr>';
431 }
432
433 // Source reason (why we have an order)
434 print '<tr><td height="10">';
435 print '<table class="nobordernopadding" width="100%"><tr><td>';
436 print $langs->trans('Source');
437 print '</td>';
438 if ($action != 'editdemandreason') {
439 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>';
440 }
441 print '</tr></table>';
442 print '</td><td colspan="2">';
443 if ($action == 'editdemandreason') {
444 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1);
445 } else {
446 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none');
447 }
448
449 // Terms of payment
450 /*
451 print '<tr><td height="10">';
452 print '<table class="nobordernopadding" width="100%"><tr><td>';
453 print $langs->trans('PaymentConditionsShort');
454 print '</td>';
455
456 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>';
457 print '</tr></table>';
458 print '</td><td colspan="2">';
459 if ($action == 'editconditions')
460 {
461 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'cond_reglement_id');
462 }
463 else
464 {
465 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'none');
466 }
467 print '</td></tr>';
468
469 // Mode of payment
470 print '<tr><td>';
471 print '<table class="nobordernopadding" width="100%"><tr><td>';
472 print $langs->trans('PaymentMode');
473 print '</td>';
474 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>';
475 print '</tr></table>';
476 print '</td><td colspan="2">';
477 if ($action == 'editmode')
478 {
479 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'mode_reglement_id');
480 }
481 else
482 {
483 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'none');
484 }
485 print '</td></tr>';*/
486
487 $tmparray = $object->getTotalWeightVolume();
488 $totalWeight = $tmparray['weight'];
489 $totalVolume = $tmparray['volume'];
490 if ($totalWeight || $totalVolume) {
491 print '<tr><td>'.$langs->trans("CalculatedWeight").'</td>';
492 print '<td colspan="2">';
493 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');
494 print '</td></tr>';
495 print '<tr><td>'.$langs->trans("CalculatedVolume").'</td>';
496 print '<td colspan="2">';
497 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');
498 print '</td></tr>';
499 }
500
501 // TODO How record was recorded OrderMode (llx_c_input_method)
502
503 // Incoterms
504 if (isModEnabled('incoterm')) {
505 print '<tr><td>';
506 print '<table width="100%" class="nobordernopadding"><tr><td>';
507 print $langs->trans('IncotermLabel');
508 print '<td><td class="right">';
509 if ($permissiontoadd) {
510 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'/expedition/shipment.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
511 } else {
512 print '&nbsp;';
513 }
514 print '</td></tr></table>';
515 print '</td>';
516 print '<td colspan="2">';
517 if ($action != 'editincoterm') {
518 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
519 } else {
520 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
521 }
522 print '</td></tr>';
523 }
524
525 $expe = new Expedition($db);
526 $extrafields->fetch_name_optionals_label($expe->table_element);
527
528 // Other attributes
529 $cols = 2;
530 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
531
532 print '</table>';
533
534 print '</div>';
535 print '<div class="fichehalfright">';
536 print '<div class="underbanner clearboth"></div>';
537
538 print '<table class="border centpercent tableforfield">';
539
540 if (isModEnabled("multicurrency") && ($object->multicurrency_code != $conf->currency)) {
541 // Multicurrency Amount HT
542 print '<tr><td class="titlefieldmiddle">'.$form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0).'</td>';
543 print '<td class="nowrap">'.price($object->multicurrency_total_ht, 0, $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'</td>';
544 print '</tr>';
545
546 // Multicurrency Amount VAT
547 print '<tr><td>'.$form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0).'</td>';
548 print '<td class="nowrap">'.price($object->multicurrency_total_tva, 0, $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'</td>';
549 print '</tr>';
550
551 // Multicurrency Amount TTC
552 print '<tr><td>'.$form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0).'</td>';
553 print '<td class="nowrap">'.price($object->multicurrency_total_ttc, 0, $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'</td>';
554 print '</tr>';
555 }
556
557 // Total HT
558 print '<tr><td class="titlefieldmiddle">'.$langs->trans('AmountHT').'</td>';
559 print '<td>'.price($object->total_ht, 0, '', 1, -1, -1, $conf->currency).'</td>';
560 print '</tr>';
561
562 // Total VAT
563 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($object->total_tva, 0, '', 1, -1, -1, $conf->currency).'</td>';
564 print '</tr>';
565
566 // Amount Local Taxes
567 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { // Localtax1
568 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td>';
569 print '<td>'.price($object->total_localtax1, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
570 }
571 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { // Localtax2 IRPF
572 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td>';
573 print '<td>'.price($object->total_localtax2, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
574 }
575
576 // Total TTC
577 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($object->total_ttc, 0, '', 1, -1, -1, $conf->currency).'</td>';
578 print '</tr>';
579
580 print '</table>';
581
582 print '</div>';
583 print '</div>';
584
585 print '<div class="clearboth"></div><br>';
586
587
592 print '<table id="tablelines" class="noborder noshadow" width="100%">';
593
594 $sql = "SELECT cd.rowid, cd.fk_product, cd.product_type as type, cd.label, cd.description,";
595 $sql .= " cd.price, cd.tva_tx, cd.subprice,";
596 $sql .= " cd.qty, cd.fk_unit, cd.rang,";
597 $sql .= ' cd.date_start,';
598 $sql .= ' cd.date_end,';
599 $sql .= ' cd.special_code,';
600 $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,';
601 $sql .= ' p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units,';
602 $sql .= ' p.surface, p.surface_units, p.volume, p.volume_units';
603 $sql .= ', p.tobatch, p.tosell, p.tobuy, p.barcode';
604 $sql .= ', u.short_label as unit_order';
605 $sql .= " FROM ".MAIN_DB_PREFIX."commandedet as cd";
606 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid";
607 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_units as u ON cd.fk_unit = u.rowid";
608 $sql .= " WHERE cd.fk_commande = ".((int) $object->id);
609 $sql .= " ORDER BY cd.rang, cd.rowid";
610
611 //print $sql;
612 dol_syslog("shipment.php", LOG_DEBUG);
613 $resql = $db->query($sql);
614 if ($resql) {
615 $num = $db->num_rows($resql);
616 $i = 0;
617 print '<thead>';
618 print '<tr class="liste_titre">';
619 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
620 print '<th>'.$langs->trans("Rank").'</th>';
621 }
622 print '<th>'.$langs->trans("Description").'</th>';
623 print '<th class="center">'.$langs->trans("QtyOrdered").'</th>';
624 print '<th class="center">'.$langs->trans("QtyShipped").'</th>';
625 print '<th class="center">'.$langs->trans("KeepToShip").'</th>';
626 if (isModEnabled('stock')) {
627 print '<th class="center">'.$langs->trans("RealStock").'</th>';
628 } else {
629 print '<th>&nbsp;</th>';
630 }
631 print "</tr>\n";
632 print '</thead>';
633
634 $toBeShipped = array();
635 $toBeShippedTotal = 0;
636 while ($i < $num) {
637 $objp = $db->fetch_object($resql);
638
639 $parameters = array('i' => $i, 'line' => $objp, 'num' => $num);
640 $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $object, $action);
641 if ($reshook < 0) {
642 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
643 }
644
645 if (empty($reshook)) {
646 // Show product and description
647 $type = isset($objp->type) ? $objp->type : $objp->product_type;
648
649 // Try to enhance type detection using date_start and date_end for free lines where type
650 // was not saved.
651 if (!empty($objp->date_start)) {
652 $type = 1;
653 }
654 if (!empty($objp->date_end)) {
655 $type = 1;
656 }
657
658 print '<tr class="oddeven">';
659
660 // Rank
661 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
662 print '<td class="center">'.$objp->rang.'</td>';
663 }
664
665 // Product label
666 if ($objp->fk_product > 0) {
667 // Define output language
668 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
669 $object->fetch_thirdparty();
670
671 $prod = new Product($db);
672 $prod->id = $objp->fk_product;
673 $prod->entity = $objp->entity;
674 $prod->getMultiLangs();
675
676 $outputlangs = $langs;
677 $newlang = '';
678 if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
679 $newlang = GETPOST('lang_id', 'aZ09');
680 }
681 if (empty($newlang)) {
682 $newlang = $object->thirdparty->default_lang;
683 }
684 if (!empty($newlang)) {
685 $outputlangs = new Translate("", $conf);
686 $outputlangs->setDefaultLang($newlang);
687 }
688
689 $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $objp->product_label;
690 } else {
691 $label = (!empty($objp->label) ? $objp->label : $objp->product_label);
692 }
693
694 print '<td>';
695 print '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne
696
697 // Show product and description
698 $product_static->type = $type;
699 $product_static->id = $objp->fk_product;
700 $product_static->ref = $objp->ref;
701 $product_static->entity = $objp->entity;
702 $product_static->status = $objp->tosell;
703 $product_static->status_buy = $objp->tobuy;
704 $product_static->status_batch = $objp->tobatch;
705 $product_static->barcode = $objp->barcode;
706
707 $product_static->weight = $objp->weight;
708 $product_static->weight_units = $objp->weight_units;
709 $product_static->length = $objp->length;
710 $product_static->length_units = $objp->length_units;
711 $product_static->width = $objp->width;
712 $product_static->width_units = $objp->width_units;
713 $product_static->height = $objp->height;
714 $product_static->height_units = $objp->height_units;
715 $product_static->surface = $objp->surface;
716 $product_static->surface_units = $objp->surface_units;
717 $product_static->volume = $objp->volume;
718 $product_static->volume_units = $objp->volume_units;
719
720 $text = $product_static->getNomUrl(1);
721 $text .= ' - '.$label;
722 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($objp->description)).'<br>';
723 $description .= $product_static->show_photos('product', $conf->product->multidir_output[$product_static->entity], 1, 1, 0, 0, 0, 80);
724 print $form->textwithtooltip($text, $description, 3, '', '', $i);
725
726 // Show range
727 print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end));
728
729 // Add description in form
730 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
731 print ($objp->description && $objp->description != $objp->product_label) ? '<br>'.dol_htmlentitiesbr($objp->description) : '';
732 }
733
734 print '</td>';
735 } else {
736 print "<td>";
737 if ($type == 1) {
738 $text = img_object($langs->trans('Service'), 'service');
739 } else {
740 $text = img_object($langs->trans('Product'), 'product');
741 }
742
743 if (!empty($objp->label)) {
744 $text .= ' <strong>'.$objp->label.'</strong>';
745 print $form->textwithtooltip($text, $objp->description, 3, '', '', $i);
746 } else {
747 print $text.' '.nl2br($objp->description);
748 }
749
750 // Show range
751 print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end));
752 print "</td>\n";
753 }
754
755 // Qty ordered
756 print '<td class="center">'.$objp->qty.($objp->unit_order ? ' '.$objp->unit_order : '').'</td>';
757
758 // Qty already shipped
759 $qtyProdCom = $objp->qty;
760 print '<td class="center">';
761 // Nb of sending products for this line of order
762 $qtyAlreadyShipped = (!empty($object->expeditions[$objp->rowid]) ? $object->expeditions[$objp->rowid] : 0);
763 print $qtyAlreadyShipped;
764 print($objp->unit_order ? ' '.$objp->unit_order : '').'</td>';
765
766 // Qty remains to ship
767 print '<td class="center">';
768 if ($type == 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES') || getDolGlobalString('SHIPMENT_SUPPORTS_SERVICES')) {
769 $toBeShipped[$objp->fk_product] = $objp->qty - $qtyAlreadyShipped;
770 $toBeShippedTotal += $toBeShipped[$objp->fk_product];
771 print $toBeShipped[$objp->fk_product];
772 } else {
773 print '0 <span class="opacitymedium">('.$langs->trans("Service").')</span>';
774 }
775 print($objp->unit_order ? ' '.$objp->unit_order : '').'</td>';
776
777 if ($objp->fk_product > 0) {
778 $product = new Product($db);
779 $product->fetch($objp->fk_product);
780 $product->load_stock('warehouseopen');
781 }
782
783 if ($objp->fk_product > 0 && ($type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) && isModEnabled('stock')) {
784 print '<td class="center">';
785 print $product->stock_reel;
786 if ($product->stock_reel < $toBeShipped[$objp->fk_product]) {
787 print ' '.img_warning($langs->trans("StockTooLow"));
788 if (getDolGlobalString('STOCK_CORRECT_STOCK_IN_SHIPMENT')) {
789 $nbPiece = $toBeShipped[$objp->fk_product] - $product->stock_reel;
790 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>';
791 }
792 }
793 print '</td>';
794 } elseif ($objp->fk_product > 0 && $type == Product::TYPE_SERVICE && getDolGlobalString('SHIPMENT_SUPPORTS_SERVICES') && isModEnabled('stock')) {
795 print '<td class="center"><span class="opacitymedium">('.$langs->trans("Service").')</span></td>';
796 } else {
797 print '<td>&nbsp;</td>';
798 }
799 print "</tr>\n";
800
801 // Show subproducts lines
802 if ($objp->fk_product > 0 && getDolGlobalString('PRODUIT_SOUSPRODUITS')) {
803 // Set tree of subproducts in product->sousprods
804 $product->get_sousproduits_arbo();
805 //var_dump($product->sousprods);exit;
806
807 // Define a new tree with quantiies recalculated
808 $prods_arbo = $product->get_arbo_each_prod($qtyProdCom);
809 //var_dump($prods_arbo);
810 if (count($prods_arbo) > 0) {
811 foreach ($prods_arbo as $key => $value) {
812 $img = '';
813 if ($value['stock'] < $value['stock_alert']) {
814 $img = img_warning($langs->trans("StockTooLow"));
815 }
816 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>';
817 print '<td class="center"> '.$value['nb_total'].'</td>';
818 print '<td>&nbsp;</td>';
819 print '<td>&nbsp;</td>';
820 print '<td class="center">'.$value['stock'].' '.$img.'</td></tr>'."\n";
821 }
822 }
823 }
824 }
825 $i++;
826 }
827 $db->free($resql);
828
829 if (!$num) {
830 print '<tr '.$bc[false].'><td colspan="5">'.$langs->trans("NoArticleOfTypeProduct").'<br>';
831 }
832
833 print "</table>";
834 } else {
835 dol_print_error($db);
836 }
837
838 print '</div>';
839
840
841 /*
842 * Boutons Actions
843 */
844
845 if (empty($user->socid)) {
846 print '<div class="tabsAction">';
847
848 // Bouton expedier sans gestion des stocks
849 if (!isModEnabled('stock') && ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED)) {
850 if ($user->hasRight('expedition', 'creer')) {
851 print '<a class="butAction" href="'.DOL_URL_ROOT.'/expedition/card.php?action=create&amp;origin=commande&amp;object_id='.$id.'">'.$langs->trans("CreateShipment").'</a>';
852 if ($toBeShippedTotal <= 0) {
853 print ' '.img_warning($langs->trans("WarningNoQtyLeftToSend"));
854 }
855 } else {
856 print '<a class="butActionRefused classfortooltip" href="#">'.$langs->trans("CreateShipment").'</a>';
857 }
858 }
859 print "</div>";
860 }
861
862
863 // Button to create a shipment
864
865 if (isModEnabled('stock') && $object->statut == Commande::STATUS_DRAFT) {
866 print $langs->trans("ValidateOrderFirstBeforeShipment");
867 }
868
869 if (isModEnabled('stock') && ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED)) {
870 if ($user->hasRight('expedition', 'creer')) {
871 //print load_fiche_titre($langs->trans("CreateShipment"));
872 print '<div class="tabsAction">';
873
874 print '<form method="GET" action="'.DOL_URL_ROOT.'/expedition/card.php">';
875 print '<input type="hidden" name="action" value="create">';
876 //print '<input type="hidden" name="id" value="'.$object->id.'">';
877 print '<input type="hidden" name="shipping_method_id" value="'.$object->shipping_method_id.'">';
878 print '<input type="hidden" name="origin" value="commande">';
879 print '<input type="hidden" name="origin_id" value="'.$object->id.'">';
880 print '<input type="hidden" name="projectid" value="'.$object->fk_project.'">';
881 //print '<table class="border centpercent">';
882
883 $langs->load("stocks");
884
885 //print '<tr>';
886
887 if (isModEnabled('stock')) {
888 //print '<td>';
889 print $langs->trans("WarehouseSource");
890 //print '</td>';
891 //print '<td>';
892 print $formproduct->selectWarehouses(!empty($object->warehouse_id) ? $object->warehouse_id : 'ifone', 'entrepot_id', '', 1, 0, 0, '', 0, 0, array(), 'minwidth200');
893 if (count($formproduct->cache_warehouses) <= 0) {
894 print ' &nbsp; '.$langs->trans("WarehouseSourceNotDefined").' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create">'.$langs->trans("AddOne").'</a>';
895 }
896 //print '</td>';
897 }
898 //print '<td class="center">';
899 print '<input type="submit" class="butAction" named="save" value="'.$langs->trans("CreateShipment").'">';
900 if ($toBeShippedTotal <= 0) {
901 print ' '.img_warning($langs->trans("WarningNoQtyLeftToSend"));
902 }
903 //print '</td></tr>';
904
905 //print "</table>";
906 print "</form>\n";
907
908 print '</div>';
909
910 $somethingshown = 1;
911 } else {
912 print '<div class="tabsAction">';
913 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("CreateShipment").'</a>';
914 print '</div>';
915 }
916 }
917
918 show_list_sending_receive('commande', $object->id);
919 } else {
920 /* Order not found */
921 setEventMessages($langs->trans("NonExistentOrder"), null, 'errors');
922 }
923}
924
925// End of page
926llxFooter();
927$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.