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