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