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