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