39require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
40require_once DOL_DOCUMENT_ROOT.
"/expedition/class/expeditionligne.class.php";
41require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
42if (isModEnabled(
"propal")) {
43 require_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
45if (isModEnabled(
'order')) {
46 require_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
48require_once DOL_DOCUMENT_ROOT.
'/expedition/class/expeditionlinebatch.class.php';
49require_once DOL_DOCUMENT_ROOT.
'/core/class/commonsignedobject.class.php';
60 use CommonSignedObject;
65 public $element =
"shipping";
70 public $fk_element =
"fk_expedition";
75 public $table_element =
"expedition";
80 public $table_element_line =
"expeditiondet";
85 public $picto =
'dolly';
91 public $fields = array();
96 public $user_author_id;
101 public $fk_user_author;
118 public $ref_customer;
128 public $tracking_number;
133 public $tracking_url;
151 public $weight_units;
167 public $height_units;
184 public $livraison_id;
189 public $multicurrency_subprice;
219 public $date_delivery;
233 public $date_expedition;
239 public $date_shipping;
268 public $lines = array();
274 public $fk_multicurrency;
279 public $multicurrency_code;
283 public $multicurrency_tx;
287 public $multicurrency_total_ht;
291 public $multicurrency_total_tva;
295 public $multicurrency_total_ttc;
343 $this->ismultientitymanaged = 1;
344 $this->isextrafieldmanaged = 1;
347 $this->labelStatus = array();
348 $this->labelStatus[-1] =
'StatusSendingCanceled';
349 $this->labelStatus[0] =
'StatusSendingDraft';
350 $this->labelStatus[1] =
'StatusSendingValidated';
351 $this->labelStatus[2] =
'StatusSendingProcessed';
354 $this->labelStatusShort = array();
355 $this->labelStatusShort[-1] =
'StatusSendingCanceledShort';
356 $this->labelStatusShort[0] =
'StatusSendingDraftShort';
357 $this->labelStatusShort[1] =
'StatusSendingValidatedShort';
358 $this->labelStatusShort[2] =
'StatusSendingProcessedShort';
369 global $langs, $conf;
370 $langs->load(
"sendings");
379 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
381 foreach ($dirmodels as $reldir) {
385 $mybool = ((bool) @include_once $dir.$file) || $mybool;
393 $obj =
new $classname();
394 '@phan-var-force ModelNumRefExpedition $obj';
395 $numref = $obj->getNextValue($soc, $this);
400 dol_print_error($this->db, get_class($this).
"::getNextNumRef ".$obj->error);
404 print $langs->trans(
"Error").
" ".$langs->trans(
"Error_EXPEDITION_ADDON_NUMBER_NotDefined");
416 public function create($user, $notrigger = 0)
418 global $conf, $hookmanager;
422 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
427 if (empty($this->fk_project)) {
428 $this->fk_project = 0;
430 if (empty($this->date_shipping) && !empty($this->date_expedition)) {
431 $this->date_shipping = $this->date_expedition;
438 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"expedition (";
441 $sql .=
", ref_customer";
443 $sql .=
", date_creation";
444 $sql .=
", fk_user_author";
445 $sql .=
", date_expedition";
446 $sql .=
", date_delivery";
448 $sql .=
", fk_projet";
449 $sql .=
", fk_address";
450 $sql .=
", fk_shipping_method";
451 $sql .=
", tracking_number";
456 $sql .=
", weight_units";
457 $sql .=
", size_units";
458 $sql .=
", note_private";
459 $sql .=
", note_public";
460 $sql .=
", model_pdf";
461 $sql .=
", fk_incoterms, location_incoterms";
462 $sql .=
", signed_status";
463 $sql .=
") VALUES (";
465 $sql .=
", ".((int) $conf->entity);
466 $sql .=
", ".($this->ref_customer ?
"'".$this->db->escape($this->ref_customer).
"'" :
"null");
467 $sql .=
", ".($this->ref_ext ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null");
468 $sql .=
", '".$this->db->idate($now).
"'";
469 $sql .=
", ".((int) $user->id);
470 $sql .=
", ".($this->date_shipping > 0 ?
"'".$this->db->idate($this->date_shipping).
"'" :
"null");
471 $sql .=
", ".($this->date_delivery > 0 ?
"'".$this->db->idate($this->date_delivery).
"'" :
"null");
472 $sql .=
", ".($this->socid > 0 ? ((int) $this->socid) :
"null");
473 $sql .=
", ".($this->fk_project > 0 ? ((int) $this->fk_project) :
"null");
474 $sql .=
", ".($this->fk_delivery_address > 0 ? $this->fk_delivery_address :
"null");
475 $sql .=
", ".($this->shipping_method_id > 0 ? ((int) $this->shipping_method_id) :
"null");
476 $sql .=
", '".$this->db->escape($this->tracking_number).
"'";
477 $sql .=
", ".(is_numeric($this->weight) ? $this->weight :
'NULL');
478 $sql .=
", ".(is_numeric($this->sizeS) ? $this->sizeS :
'NULL');
479 $sql .=
", ".(is_numeric($this->sizeW) ? $this->sizeW :
'NULL');
480 $sql .=
", ".(is_numeric($this->sizeH) ? $this->sizeH :
'NULL');
481 $sql .=
", ".($this->weight_units !=
'' ? (int) $this->weight_units :
'NULL');
482 $sql .=
", ".($this->size_units !=
'' ? (int) $this->size_units :
'NULL');
483 $sql .=
", ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
484 $sql .=
", ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
485 $sql .=
", ".(!empty($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null");
486 $sql .=
", ".(int) $this->fk_incoterms;
487 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
488 $sql .=
", ".($this->signed_status);
491 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
492 $resql = $this->db->query($sql);
494 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"expedition");
496 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expedition";
497 $sql .=
" SET ref = '(PROV".$this->id.
")'";
498 $sql .=
" WHERE rowid = ".((int) $this->
id);
500 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
501 if ($this->db->query($sql)) {
503 $num = count($this->lines);
504 for ($i = 0; $i < $num; $i++) {
506 if (!isset($this->lines[$i]->detail_batch)) {
507 if ($this->
create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) {
511 if ($this->
create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) {
518 if (!$error && $this->
id && $this->origin_id) {
533 if (!$error && !$notrigger) {
535 $result = $this->
call_trigger(
'SHIPPING_CREATE', $user);
545 foreach ($this->errors as $errmsg) {
546 dol_syslog(get_class($this).
"::create ".$errmsg, LOG_ERR);
547 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
549 $this->db->rollback();
554 $this->db->rollback();
559 $this->error = $this->db->lasterror().
" - sql=$sql";
560 $this->db->rollback();
565 $this->error = $this->db->error().
" - sql=$sql";
566 $this->db->rollback();
582 public function create_line($entrepot_id, $origin_line_id, $qty, $rang = 0, $array_options = [])
588 $expeditionline->fk_expedition = $this->id;
589 $expeditionline->entrepot_id = $entrepot_id;
590 $expeditionline->fk_elementdet = $origin_line_id;
591 $expeditionline->element_type = $this->origin;
592 $expeditionline->qty = $qty;
593 $expeditionline->rang = $rang;
594 $expeditionline->array_options = $array_options;
596 if (($lineId = $expeditionline->insert($user)) < 0) {
597 $this->errors[] = $expeditionline->error;
615 $stockLocationQty = array();
617 $tab = $line_ext->detail_batch;
619 foreach ($tab as $detbatch) {
620 if (!empty($detbatch->entrepot_id)) {
621 if (empty($stockLocationQty[$detbatch->entrepot_id])) {
622 $stockLocationQty[$detbatch->entrepot_id] = 0;
624 $stockLocationQty[$detbatch->entrepot_id] += $detbatch->qty;
628 foreach ($stockLocationQty as $stockLocation => $qty) {
629 $line_id = $this->
create_line($stockLocation, $line_ext->origin_line_id, $qty, $line_ext->rang, $array_options);
634 foreach ($tab as $detbatch) {
635 if ($detbatch->entrepot_id == $stockLocation) {
636 if (!($detbatch->create($line_id) > 0)) {
637 $this->errors = $detbatch->errors;
661 public function fetch($id, $ref =
'', $ref_ext =
'', $notused =
'')
666 if (empty($id) && empty($ref) && empty($ref_ext)) {
670 $sql =
"SELECT e.rowid, e.entity, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.fk_user_author, e.fk_statut, e.signed_status, e.fk_projet as fk_project, e.billed";
671 $sql .=
", e.date_valid";
672 $sql .=
", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height";
673 $sql .=
", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery";
674 $sql .=
", e.fk_shipping_method, e.tracking_number";
675 $sql .=
", e.note_private, e.note_public";
676 $sql .=
', e.fk_incoterms, e.location_incoterms';
677 $sql .=
', e.signed_status';
678 $sql .=
', i.libelle as label_incoterms';
679 $sql .=
', s.libelle as shipping_method';
680 $sql .=
", el.fk_source as origin_id, el.sourcetype as origin_type";
681 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expedition as e";
682 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element).
"'";
683 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON e.fk_incoterms = i.rowid';
684 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_shipment_mode as s ON e.fk_shipping_method = s.rowid';
685 $sql .=
" WHERE e.entity IN (".getEntity(
'expedition').
")";
687 $sql .=
" AND e.rowid = ".((int) $id);
690 $sql .=
" AND e.ref='".$this->db->escape($ref).
"'";
693 $sql .=
" AND e.ref_ext='".$this->db->escape($ref_ext).
"'";
696 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
697 $result = $this->db->query($sql);
699 if ($this->db->num_rows($result)) {
700 $obj = $this->db->fetch_object($result);
702 $this->
id = $obj->rowid;
703 $this->entity = $obj->entity;
704 $this->
ref = $obj->ref;
705 $this->socid = $obj->socid;
706 $this->ref_customer = $obj->ref_customer;
707 $this->ref_ext = $obj->ref_ext;
708 $this->
status = $obj->fk_statut;
709 $this->statut = $this->status;
710 $this->signed_status = $obj->signed_status;
711 $this->user_author_id = $obj->fk_user_author;
712 $this->fk_user_author = $obj->fk_user_author;
713 $this->date_creation = $this->db->jdate($obj->date_creation);
714 $this->date_valid = $this->db->jdate($obj->date_valid);
715 $this->date = $this->db->jdate($obj->date_expedition);
716 $this->date_expedition = $this->db->jdate($obj->date_expedition);
717 $this->date_shipping = $this->db->jdate($obj->date_expedition);
718 $this->date_delivery = $this->db->jdate($obj->date_delivery);
719 $this->fk_delivery_address = $obj->fk_address;
720 $this->model_pdf = $obj->model_pdf;
721 $this->shipping_method_id = $obj->fk_shipping_method;
722 $this->shipping_method = $obj->shipping_method;
723 $this->tracking_number = $obj->tracking_number;
724 $this->origin = ($obj->origin_type ? $obj->origin_type :
'commande');
725 $this->origin_type = ($obj->origin_type ? $obj->origin_type :
'commande');
726 $this->origin_id = $obj->origin_id;
727 $this->billed = $obj->billed;
728 $this->fk_project = $obj->fk_project;
729 $this->signed_status = $obj->signed_status;
730 $this->trueWeight = $obj->weight;
731 $this->weight_units = $obj->weight_units;
733 $this->trueWidth = $obj->width;
734 $this->width_units = $obj->size_units;
735 $this->trueHeight = $obj->height;
736 $this->height_units = $obj->size_units;
737 $this->trueDepth = $obj->size;
738 $this->depth_units = $obj->size_units;
740 $this->note_public = $obj->note_public;
741 $this->note_private = $obj->note_private;
744 $this->trueSize = $obj->size.
"x".$obj->width.
"x".$obj->height;
745 $this->size_units = $obj->size_units;
748 $this->fk_incoterms = $obj->fk_incoterms;
749 $this->location_incoterms = $obj->location_incoterms;
750 $this->label_incoterms = $obj->label_incoterms;
752 $this->db->free($result);
764 if (isModEnabled(
'multicurrency')) {
765 if (!empty($this->multicurrency_code)) {
766 $this->multicurrency_code = $this->thirdparty->multicurrency_code;
768 if (
getDolGlobalString(
'MULTICURRENCY_USE_ORIGIN_TX') && !empty($this->thirdparty->multicurrency_tx)) {
769 $this->multicurrency_tx = $this->thirdparty->multicurrency_tx;
783 dol_syslog(get_class($this).
'::Fetch no expedition found', LOG_ERR);
784 $this->error =
'Shipment with id '.$id.
' not found';
788 $this->error = $this->db->error();
800 public function valid($user, $notrigger = 0)
804 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
810 dol_syslog(get_class($this).
"::valid not in draft status", LOG_WARNING);
814 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'expedition',
'creer'))
815 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'expedition',
'shipping_advance',
'validate')))) {
816 $this->error =
'Permission denied';
817 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
827 $soc->fetch($this->socid);
830 $result = $soc->setAsCustomer();
833 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
835 } elseif (!empty($this->
ref)) {
836 $numref = $this->ref;
838 $numref =
"EXP".$this->id;
845 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expedition SET";
846 $sql .=
" ref='".$this->db->escape($numref).
"'";
847 $sql .=
", fk_statut = 1";
848 $sql .=
", date_valid = '".$this->db->idate($now).
"'";
849 $sql .=
", fk_user_valid = ".((int) $user->id);
850 $sql .=
" WHERE rowid = ".((int) $this->
id);
852 dol_syslog(get_class($this).
"::valid update expedition", LOG_DEBUG);
853 $resql = $this->db->query($sql);
855 $this->error = $this->db->lasterror();
860 if (!$error && isModEnabled(
'stock') &&
getDolGlobalString(
'STOCK_CALCULATE_ON_SHIPMENT')) {
873 if (!$error && !$notrigger) {
875 $result = $this->
call_trigger(
'SHIPPING_VALIDATE', $user);
883 $this->oldref = $this->ref;
886 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
888 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'expedition/sending/".$this->db->escape($this->newref).
"'";
889 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expedition/sending/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
890 $resql = $this->db->query($sql);
893 $this->error = $this->db->lasterror();
895 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expedition/sending/".$this->db->escape($this->newref).
"'";
896 $sql .=
" WHERE filepath = 'expedition/sending/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
897 $resql = $this->db->query($sql);
900 $this->error = $this->db->lasterror();
906 $dirsource = $conf->expedition->dir_output.
'/sending/'.$oldref;
907 $dirdest = $conf->expedition->dir_output.
'/sending/'.$newref;
908 if (!$error && file_exists($dirsource)) {
909 dol_syslog(get_class($this).
"::valid rename dir ".$dirsource.
" into ".$dirdest);
911 if (@rename($dirsource, $dirdest)) {
914 $listoffiles =
dol_dir_list($conf->expedition->dir_output.
'/sending/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
915 foreach ($listoffiles as $fileentry) {
916 $dirsource = $fileentry[
'name'];
917 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
918 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
919 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
920 @rename($dirsource, $dirdest);
929 $this->
ref = $numref;
938 $this->db->rollback();
957 if ($this->statut == self::STATUS_VALIDATED || $this->statut == self::STATUS_CLOSED) {
959 include_once DOL_DOCUMENT_ROOT.
'/delivery/class/delivery.class.php';
960 $delivery =
new Delivery($this->db);
961 $result = $delivery->create_from_sending($user, $this->
id);
965 $this->error = $delivery->error;
988 public function addline($entrepot_id, $id, $qty, $array_options = [])
990 global $conf, $langs;
992 $num = count($this->lines);
995 $line->entrepot_id = $entrepot_id;
996 $line->origin_line_id = $id;
997 $line->fk_elementdet = $id;
998 $line->element_type =
'order';
1002 $orderline->fetch($id);
1005 $line->rang = $orderline->rang;
1006 $line->product_type = $orderline->product_type;
1008 if (isModEnabled(
'stock') && !empty($orderline->fk_product)) {
1009 $fk_product = $orderline->fk_product;
1012 $langs->load(
"errors");
1013 $this->error = $langs->trans(
"ErrorWarehouseRequiredIntoShipmentLine");
1018 $product =
new Product($this->db);
1019 $product->fetch($fk_product);
1022 if ($entrepot_id > 0) {
1023 $product->load_stock(
'warehouseopen');
1024 $product_stock = $product->stock_warehouse[$entrepot_id]->real;
1026 $product_stock = $product->stock_reel;
1029 $product_type = $product->type;
1031 $isavirtualproduct = ($product->hasFatherOrChild(1) > 0);
1034 if ($product_stock < $qty) {
1035 $langs->load(
"errors");
1036 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref);
1037 $this->errorhidden =
'ErrorStockIsNotEnoughToAddProductOnShipment';
1039 $this->db->rollback();
1049 if (isModEnabled(
'productbatch') && !empty($orderline->fk_product) && !empty($orderline->product_tobatch)) {
1050 $this->error =
'ADDLINE_WAS_CALLED_INSTEAD_OF_ADDLINEBATCH '.$orderline->id.
' '.$orderline->fk_product;
1055 if (!
getDolGlobalString(
'MAIN_EXTRAFIELDS_DISABLED') && is_array($array_options) && count($array_options) > 0) {
1056 $line->array_options = $array_options;
1059 $this->lines[$num] = $line;
1075 global $conf, $langs;
1077 $num = count($this->lines);
1079 if ($dbatch[
'qty'] > 0 || ($dbatch[
'qty'] == 0 &&
getDolGlobalString(
'SHIPMENT_GETS_ALL_ORDER_PRODUCTS'))) {
1082 foreach ($dbatch[
'detail'] as $key => $value) {
1083 if ($value[
'q'] > 0 || ($value[
'q'] == 0 &&
getDolGlobalString(
'SHIPMENT_GETS_ALL_ORDER_PRODUCTS'))) {
1089 $ret = $linebatch->fetchFromStock($value[
'id_batch']);
1094 $linebatch->qty = $value[
'q'];
1095 if ($linebatch->qty == 0 &&
getDolGlobalString(
'SHIPMENT_GETS_ALL_ORDER_PRODUCTS')) {
1096 $linebatch->batch =
null;
1098 $tab[] = $linebatch;
1101 require_once DOL_DOCUMENT_ROOT.
'/product/class/productbatch.class.php';
1103 $prod_batch->fetch($value[
'id_batch']);
1105 if ($prod_batch->qty < $linebatch->qty) {
1106 $langs->load(
"errors");
1107 $this->errors[] = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnShipment', $prod_batch->fk_product);
1108 dol_syslog(get_class($this).
"::addline_batch error=Product ".$prod_batch->batch.
": ".$this->errorsToString(), LOG_ERR);
1109 $this->db->rollback();
1117 if (is_object($linebatch)) {
1118 $line->entrepot_id = $linebatch->entrepot_id;
1120 $line->origin_line_id = $dbatch[
'ix_l'];
1121 $line->fk_elementdet = $dbatch[
'ix_l'];
1122 $line->qty = $dbatch[
'qty'];
1123 $line->detail_batch = $tab;
1126 if (!
getDolGlobalString(
'MAIN_EXTRAFIELDS_DISABLED') && is_array($array_options) && count($array_options) > 0) {
1127 $line->array_options = $array_options;
1131 $this->lines[$num] = $line;
1144 public function update($user =
null, $notrigger = 0)
1151 if (isset($this->
ref)) {
1152 $this->
ref = trim($this->
ref);
1154 if (isset($this->entity)) {
1155 $this->entity = (int) $this->entity;
1157 if (isset($this->ref_customer)) {
1158 $this->ref_customer = trim($this->ref_customer);
1160 if (isset($this->socid)) {
1161 $this->socid = (int) $this->socid;
1163 if (isset($this->fk_user_author)) {
1164 $this->fk_user_author = (int) $this->fk_user_author;
1166 if (isset($this->fk_user_valid)) {
1168 $this->fk_user_valid = (int) $this->fk_user_valid;
1170 if (isset($this->fk_delivery_address)) {
1171 $this->fk_delivery_address = (int) $this->fk_delivery_address;
1173 if (isset($this->shipping_method_id)) {
1174 $this->shipping_method_id = (int) $this->shipping_method_id;
1176 if (isset($this->tracking_number)) {
1177 $this->tracking_number = trim($this->tracking_number);
1179 if (isset($this->statut)) {
1180 $this->statut = (int) $this->statut;
1182 if (isset($this->trueDepth)) {
1183 $this->trueDepth = trim($this->trueDepth);
1185 if (isset($this->trueWidth)) {
1186 $this->trueWidth = trim($this->trueWidth);
1188 if (isset($this->trueHeight)) {
1189 $this->trueHeight = trim($this->trueHeight);
1191 if (isset($this->size_units)) {
1192 $this->size_units = trim($this->size_units);
1194 if (isset($this->weight_units)) {
1195 $this->weight_units = (int) $this->weight_units;
1197 if (isset($this->trueWeight)) {
1198 $this->weight = trim((
string) $this->trueWeight);
1200 if (isset($this->note_private)) {
1201 $this->note_private = trim($this->note_private);
1203 if (isset($this->note_public)) {
1204 $this->note_public = trim($this->note_public);
1206 if (isset($this->model_pdf)) {
1207 $this->model_pdf = trim($this->model_pdf);
1214 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expedition SET";
1215 $sql .=
" ref = ".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1216 $sql .=
" ref_ext = ".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1217 $sql .=
" ref_customer = ".(isset($this->ref_customer) ?
"'".$this->db->escape($this->ref_customer).
"'" :
"null").
",";
1218 $sql .=
" fk_soc = ".(isset($this->socid) ? $this->socid :
"null").
",";
1219 $sql .=
" date_creation = ".(dol_strlen($this->date_creation) != 0 ?
"'".$this->db->idate($this->date_creation).
"'" :
'null').
",";
1220 $sql .=
" fk_user_author = ".(isset($this->fk_user_author) ? $this->fk_user_author :
"null").
",";
1221 $sql .=
" date_valid = ".(dol_strlen($this->date_valid) != 0 ?
"'".$this->db->idate($this->date_valid).
"'" :
'null').
",";
1222 $sql .=
" fk_user_valid = ".(isset($this->fk_user_valid) ? $this->fk_user_valid :
"null").
",";
1223 $sql .=
" date_expedition = ".(dol_strlen($this->date_expedition) != 0 ?
"'".$this->db->idate($this->date_expedition).
"'" :
'null').
",";
1224 $sql .=
" date_delivery = ".(dol_strlen($this->date_delivery) != 0 ?
"'".$this->db->idate($this->date_delivery).
"'" :
'null').
",";
1225 $sql .=
" fk_address = ".(isset($this->fk_delivery_address) ? $this->fk_delivery_address :
"null").
",";
1226 $sql .=
" fk_shipping_method = ".((isset($this->shipping_method_id) && $this->shipping_method_id > 0) ? $this->shipping_method_id :
"null").
",";
1227 $sql .=
" tracking_number = ".(isset($this->tracking_number) ?
"'".$this->db->escape($this->tracking_number).
"'" :
"null").
",";
1228 $sql .=
" fk_statut = ".(isset($this->statut) ? $this->statut :
"null").
",";
1229 $sql .=
" fk_projet = ".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1230 $sql .=
" height = ".(($this->trueHeight !=
'') ? $this->trueHeight :
"null").
",";
1231 $sql .=
" width = ".(($this->trueWidth !=
'') ? $this->trueWidth :
"null").
",";
1232 $sql .=
" size_units = ".(isset($this->size_units) ? $this->size_units :
"null").
",";
1233 $sql .=
" size = ".(($this->trueDepth !=
'') ? $this->trueDepth :
"null").
",";
1234 $sql .=
" weight_units = ".(isset($this->weight_units) ? $this->weight_units :
"null").
",";
1235 $sql .=
" weight = ".(($this->trueWeight !=
'') ? $this->trueWeight :
"null").
",";
1236 $sql .=
" note_private = ".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1237 $sql .=
" note_public = ".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1238 $sql .=
" model_pdf = ".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1239 $sql .=
" entity = ".((int) $conf->entity);
1240 $sql .=
" WHERE rowid = ".((int) $this->
id);
1244 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1245 $resql = $this->db->query($sql);
1248 $this->errors[] =
"Error ".$this->db->lasterror();
1251 if (!$error && !$notrigger) {
1253 $result = $this->
call_trigger(
'SHIPPING_MODIFY', $user);
1262 foreach ($this->errors as $errmsg) {
1263 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1264 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1266 $this->db->rollback();
1269 $this->db->commit();
1282 public function cancel($notrigger = 0, $also_update_stock =
false)
1284 global $conf, $langs, $user;
1286 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1295 if (count($this->linkedObjectsIds) > 0) {
1296 $this->error =
'ErrorThereIsSomeDeliveries';
1300 if (!$error && !$notrigger) {
1302 $result = $this->
call_trigger(
'SHIPPING_CANCEL', $user);
1310 if (!$error && isModEnabled(
'stock') &&
1311 ((
getDolGlobalString(
'STOCK_CALCULATE_ON_SHIPMENT') && $this->statut > self::STATUS_DRAFT) ||
1312 (
getDolGlobalString(
'STOCK_CALCULATE_ON_SHIPMENT_CLOSE') && $this->statut == self::STATUS_CLOSED && $also_update_stock))) {
1313 require_once DOL_DOCUMENT_ROOT.
"/product/stock/class/mouvementstock.class.php";
1315 $langs->load(
"agenda");
1318 $sql =
"SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid as expeditiondet_id";
1319 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commandedet as cd,";
1320 $sql .=
" ".MAIN_DB_PREFIX.
"expeditiondet as ed";
1321 $sql .=
" WHERE ed.fk_expedition = ".((int) $this->
id);
1322 $sql .=
" AND cd.rowid = ed.fk_elementdet";
1324 dol_syslog(get_class($this).
"::delete select details", LOG_DEBUG);
1325 $resql = $this->db->query($sql);
1327 $cpt = $this->db->num_rows($resql);
1331 for ($i = 0; $i < $cpt; $i++) {
1332 dol_syslog(get_class($this).
"::delete movement index ".$i);
1333 $obj = $this->db->fetch_object($resql);
1337 $mouvS->origin =
'';
1340 if (isModEnabled(
'productbatch')) {
1341 $lotArray = $shipmentlinebatch->fetchAll($obj->expeditiondet_id);
1342 if (!is_array($lotArray)) {
1344 $this->errors[] =
"Error ".$this->db->lasterror();
1348 if (empty($lotArray)) {
1352 $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans(
"ShipmentCanceledInDolibarr", $this->ref));
1355 $this->errors = array_merge($this->errors, $mouvS->errors);
1361 foreach ($lotArray as $lot) {
1362 $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $lot->qty, 0, $langs->trans(
"ShipmentCanceledInDolibarr", $this->ref), $lot->eatby, $lot->sellby, $lot->batch);
1365 $this->errors = array_merge($this->errors, $mouvS->errors);
1376 $this->errors[] =
"Error ".$this->db->lasterror();
1381 if (!$error && isModEnabled(
'productbatch')) {
1383 if ($shipmentlinebatch->deleteFromShipment($this->id) < 0) {
1385 $this->errors[] =
"Error ".$this->db->lasterror();
1391 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"expeditiondet";
1392 $sql .=
" WHERE fk_expedition = ".((int) $this->
id);
1394 if ($this->db->query($sql)) {
1403 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"expedition";
1404 $sql .=
" WHERE rowid = ".((int) $this->
id);
1406 if ($this->db->query($sql)) {
1407 if (!empty($this->origin) && $this->origin_id > 0) {
1410 '@phan-var-force Facture|Commande $origin_object';
1422 $this->db->commit();
1426 if (!empty($conf->expedition->dir_output)) {
1427 $dir = $conf->expedition->dir_output.
'/sending/'.$ref;
1428 $file = $dir.
'/'.$ref.
'.pdf';
1429 if (file_exists($file)) {
1434 if (file_exists($dir)) {
1436 $this->error = $langs->trans(
"ErrorCanNotDeleteDir", $dir);
1444 $this->db->rollback();
1448 $this->error = $this->db->lasterror().
" - sql=$sql";
1449 $this->db->rollback();
1453 $this->error = $this->db->lasterror().
" - sql=$sql";
1454 $this->db->rollback();
1458 $this->error = $this->db->lasterror().
" - sql=$sql";
1459 $this->db->rollback();
1463 $this->db->rollback();
1477 public function delete($user =
null, $notrigger = 0, $also_update_stock =
false)
1479 global $conf, $langs;
1485 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1494 if (count($this->linkedObjectsIds) > 0) {
1495 $this->error =
'ErrorThereIsSomeDeliveries';
1499 if (!$error && !$notrigger) {
1501 $result = $this->
call_trigger(
'SHIPPING_DELETE', $user);
1509 if (!$error && isModEnabled(
'stock') &&
1510 ((
getDolGlobalString(
'STOCK_CALCULATE_ON_SHIPMENT') && $this->statut > self::STATUS_DRAFT) ||
1511 (
getDolGlobalString(
'STOCK_CALCULATE_ON_SHIPMENT_CLOSE') && $this->statut == self::STATUS_CLOSED && $also_update_stock))) {
1512 require_once DOL_DOCUMENT_ROOT.
"/product/stock/class/mouvementstock.class.php";
1514 $langs->load(
"agenda");
1520 $sql =
"SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid as expeditiondet_id";
1521 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commandedet as cd,";
1522 $sql .=
" ".MAIN_DB_PREFIX.
"expeditiondet as ed";
1523 $sql .=
" WHERE ed.fk_expedition = ".((int) $this->
id);
1524 $sql .=
" AND cd.rowid = ed.fk_elementdet";
1526 dol_syslog(get_class($this).
"::delete select details", LOG_DEBUG);
1527 $resql = $this->db->query($sql);
1529 $cpt = $this->db->num_rows($resql);
1530 for ($i = 0; $i < $cpt; $i++) {
1531 dol_syslog(get_class($this).
"::delete movement index ".$i);
1532 $obj = $this->db->fetch_object($resql);
1536 $mouvS->origin =
'';
1538 $lotArray = $shipmentlinebatch->fetchAll($obj->expeditiondet_id);
1539 if (!is_array($lotArray)) {
1541 $this->errors[] =
"Error ".$this->db->lasterror();
1543 if (empty($lotArray)) {
1547 $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans(
"ShipmentDeletedInDolibarr", $this->ref));
1550 $this->errors = array_merge($this->errors, $mouvS->errors);
1556 foreach ($lotArray as $lot) {
1557 $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $lot->qty, 0, $langs->trans(
"ShipmentDeletedInDolibarr", $this->ref), $lot->eatby, $lot->sellby, $lot->batch);
1560 $this->errors = array_merge($this->errors, $mouvS->errors);
1571 $this->errors[] =
"Error ".$this->db->lasterror();
1578 if ($shipmentlinebatch->deleteFromShipment($this->id) < 0) {
1580 $this->errors[] =
"Error ".$this->db->lasterror();
1585 $main = MAIN_DB_PREFIX.
'expeditiondet';
1586 $ef = $main.
"_extrafields";
1587 $sqlef =
"DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_expedition = ".((int) $this->
id).
")";
1589 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"expeditiondet";
1590 $sql .=
" WHERE fk_expedition = ".((int) $this->
id);
1592 if ($this->db->query($sqlef) && $this->db->query($sql)) {
1606 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"expedition";
1607 $sql .=
" WHERE rowid = ".((int) $this->
id);
1609 if ($this->db->query($sql)) {
1610 if (!empty($this->origin) && $this->origin_id > 0) {
1613 '@phan-var-force Facture|Commande $origin_object';
1625 $this->db->commit();
1633 if (!empty($conf->expedition->dir_output)) {
1634 $dir = $conf->expedition->dir_output.
'/sending/'.$ref;
1635 $file = $dir.
'/'.$ref.
'.pdf';
1636 if (file_exists($file)) {
1641 if (file_exists($dir)) {
1643 $this->error = $langs->trans(
"ErrorCanNotDeleteDir", $dir);
1651 $this->db->rollback();
1655 $this->error = $this->db->lasterror().
" - sql=$sql";
1656 $this->db->rollback();
1660 $this->error = $this->db->lasterror().
" - sql=$sql";
1661 $this->db->rollback();
1665 $this->error = $this->db->lasterror().
" - sql=$sql";
1666 $this->db->rollback();
1670 $this->db->rollback();
1686 $this->lines = array();
1691 $sql =
"SELECT cd.rowid, cd.fk_product, cd.label as custom_label, cd.description, cd.qty as qty_asked, cd.product_type, cd.fk_unit";
1692 $sql .=
", cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva";
1693 $sql .=
", cd.fk_remise_except, cd.fk_product_fournisseur_price as fk_fournprice";
1694 $sql .=
", cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.info_bits, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht";
1695 $sql .=
", cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc, cd.rang, cd.date_start, cd.date_end";
1696 $sql .=
", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_element, ed.fk_elementdet, ed.element_type, ed.fk_entrepot";
1697 $sql .=
", p.ref as product_ref, p.label as product_label, p.fk_product_type, p.barcode as product_barcode";
1698 $sql .=
", p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch";
1699 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expeditiondet as ed, ".MAIN_DB_PREFIX.
"commandedet as cd";
1700 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"product as p ON p.rowid = cd.fk_product";
1701 $sql .=
" WHERE ed.fk_expedition = ".((int) $this->
id);
1702 $sql .=
" AND ed.fk_elementdet = cd.rowid";
1703 $sql .=
" ORDER BY cd.rang, ed.fk_elementdet";
1705 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1706 $resql = $this->db->query($sql);
1708 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
1710 $num = $this->db->num_rows($resql);
1715 $this->total_ht = 0;
1716 $this->total_tva = 0;
1717 $this->total_ttc = 0;
1718 $this->total_localtax1 = 0;
1719 $this->total_localtax2 = 0;
1721 $this->multicurrency_total_ht = 0;
1722 $this->multicurrency_total_tva = 0;
1723 $this->multicurrency_total_ttc = 0;
1728 $obj = $this->db->fetch_object($resql);
1731 if ($originline > 0 && $originline == $obj->fk_elementdet) {
1732 '@phan-var-force ExpeditionLigne $line';
1733 $line->entrepot_id = 0;
1734 $line->qty_shipped += $obj->qty_shipped;
1737 $line->entrepot_id = $obj->fk_entrepot;
1738 $line->qty_shipped = $obj->qty_shipped;
1742 $detail_entrepot->entrepot_id = $obj->fk_entrepot;
1743 $detail_entrepot->qty_shipped = $obj->qty_shipped;
1744 $detail_entrepot->line_id = $obj->line_id;
1745 $line->details_entrepot[] = $detail_entrepot;
1747 $line->line_id = $obj->line_id;
1748 $line->rowid = $obj->line_id;
1749 $line->id = $obj->line_id;
1751 $line->fk_origin =
'orderline';
1753 $line->fk_element = $obj->fk_element;
1754 $line->origin_id = $obj->fk_element;
1755 $line->fk_elementdet = $obj->fk_elementdet;
1756 $line->origin_line_id = $obj->fk_elementdet;
1757 $line->element_type = $obj->element_type;
1759 $line->fk_expedition = $this->id;
1761 $line->product_type = $obj->product_type;
1762 $line->fk_product = $obj->fk_product;
1763 $line->fk_product_type = $obj->fk_product_type;
1764 $line->ref = $obj->product_ref;
1765 $line->product_ref = $obj->product_ref;
1766 $line->product_label = $obj->product_label;
1767 $line->libelle = $obj->product_label;
1768 $line->product_barcode = $obj->product_barcode;
1769 $line->product_tosell = $obj->product_tosell;
1770 $line->product_tobuy = $obj->product_tobuy;
1771 $line->product_tobatch = $obj->product_tobatch;
1772 $line->fk_fournprice = $obj->fk_fournprice;
1773 $line->label = $obj->custom_label;
1774 $line->description = $obj->description;
1775 $line->qty_asked = $obj->qty_asked;
1776 $line->rang = $obj->rang;
1777 $line->weight = $obj->weight;
1778 $line->weight_units = $obj->weight_units;
1779 $line->length = $obj->length;
1780 $line->length_units = $obj->length_units;
1781 $line->width = $obj->width;
1782 $line->width_units = $obj->width_units;
1783 $line->height = $obj->height;
1784 $line->height_units = $obj->height_units;
1785 $line->surface = $obj->surface;
1786 $line->surface_units = $obj->surface_units;
1787 $line->volume = $obj->volume;
1788 $line->volume_units = $obj->volume_units;
1789 $line->fk_unit = $obj->fk_unit;
1791 $line->pa_ht = $obj->pa_ht;
1794 $localtax_array = array(0 => $obj->localtax1_type, 1 => $obj->localtax1_tx, 2 => $obj->localtax2_type, 3 => $obj->localtax2_tx);
1795 $localtax1_tx =
get_localtax($obj->tva_tx, 1, $this->thirdparty);
1796 $localtax2_tx =
get_localtax($obj->tva_tx, 2, $this->thirdparty);
1799 $tabprice =
calcul_price_total($obj->qty_shipped, $obj->subprice, $obj->remise_percent, $obj->tva_tx, $localtax1_tx, $localtax2_tx, 0,
'HT', $obj->info_bits, $obj->fk_product_type, $mysoc, $localtax_array);
1800 $line->desc = $obj->description;
1801 $line->qty = $line->qty_shipped;
1802 $line->total_ht = $tabprice[0];
1803 $line->total_localtax1 = $tabprice[9];
1804 $line->total_localtax2 = $tabprice[10];
1805 $line->total_ttc = $tabprice[2];
1806 $line->total_tva = $tabprice[1];
1807 $line->vat_src_code = $obj->vat_src_code;
1808 $line->tva_tx = $obj->tva_tx;
1809 $line->localtax1_tx = $obj->localtax1_tx;
1810 $line->localtax2_tx = $obj->localtax2_tx;
1811 $line->info_bits = $obj->info_bits;
1812 $line->price = $obj->price;
1813 $line->subprice = $obj->subprice;
1814 $line->fk_remise_except = $obj->fk_remise_except;
1815 $line->remise_percent = $obj->remise_percent;
1817 $this->total_ht += $tabprice[0];
1818 $this->total_tva += $tabprice[1];
1819 $this->total_ttc += $tabprice[2];
1820 $this->total_localtax1 += $tabprice[9];
1821 $this->total_localtax2 += $tabprice[10];
1823 $line->date_start = $this->db->jdate($obj->date_start);
1824 $line->date_end = $this->db->jdate($obj->date_end);
1827 $this->fk_multicurrency = $obj->fk_multicurrency;
1828 $this->multicurrency_code = $obj->multicurrency_code;
1829 $line->multicurrency_subprice = $obj->multicurrency_subprice;
1830 $line->multicurrency_total_ht = $obj->multicurrency_total_ht;
1831 $line->multicurrency_total_tva = $obj->multicurrency_total_tva;
1832 $line->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1834 $this->multicurrency_total_ht += $obj->multicurrency_total_ht;
1835 $this->multicurrency_total_tva += $obj->multicurrency_total_tva;
1836 $this->multicurrency_total_ttc += $obj->multicurrency_total_ttc;
1838 if ($originline != $obj->fk_elementdet) {
1839 $line->detail_batch = array();
1843 if (isModEnabled(
'productbatch') && $obj->line_id > 0 && $obj->product_tobatch > 0) {
1844 $newdetailbatch = $shipmentlinebatch->fetchAll($obj->line_id, $obj->fk_product);
1846 if (is_array($newdetailbatch)) {
1847 if ($originline != $obj->fk_elementdet) {
1848 $line->detail_batch = $newdetailbatch;
1850 $line->detail_batch = array_merge($line->detail_batch, $newdetailbatch);
1855 $line->fetch_optionals();
1857 if ($originline != $obj->fk_elementdet) {
1858 $this->lines[$lineindex] = $line;
1861 $line->total_ht += $tabprice[0];
1862 $line->total_localtax1 += $tabprice[9];
1863 $line->total_localtax2 += $tabprice[10];
1864 $line->total_ttc += $tabprice[2];
1865 $line->total_tva += $tabprice[1];
1869 $originline = $obj->fk_elementdet;
1871 $this->db->free($resql);
1874 $this->error = $this->db->error();
1890 if ($this->statut == self::STATUS_DRAFT) {
1896 $line->fetch($lineid);
1898 if ($line->delete($user) > 0) {
1901 $this->db->commit();
1904 $this->db->rollback();
1908 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1922 global $conf, $langs;
1924 $langs->load(
'sendings');
1926 $nofetch = !empty($params[
'nofetch']);
1929 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Shipment").
'</u>';
1930 if (isset($this->statut)) {
1931 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1933 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1934 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.($this->ref_customer ? $this->ref_customer : $this->ref_client);
1936 $langs->load(
'companies');
1937 if (empty($this->thirdparty)) {
1940 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
1957 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1)
1959 global $langs, $hookmanager;
1964 'objecttype' => $this->element,
1965 'option' => $option,
1968 $classfortooltip =
'classfortooltip';
1971 $classfortooltip =
'classforajaxtooltip';
1972 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1978 $url = DOL_URL_ROOT.
'/expedition/card.php?id='.$this->id;
1984 if ($option !==
'nolink') {
1986 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1987 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1988 $add_save_lastsearch_values = 1;
1990 if ($add_save_lastsearch_values) {
1991 $url .=
'&save_lastsearch_values=1';
1996 if (empty($notooltip)) {
1998 $label = $langs->trans(
"Shipment");
1999 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
2001 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
2002 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
2005 $linkstart =
'<a href="'.$url.
'"';
2006 $linkstart .= $linkclose.
'>';
2009 $result .= $linkstart;
2011 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
2013 if ($withpicto != 2) {
2014 $result .= $this->ref;
2016 $result .= $linkend;
2018 $hookmanager->initHooks(array($this->element .
'dao'));
2019 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
2020 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
2022 $result = $hookmanager->resPrint;
2024 $result .= $hookmanager->resPrint;
2037 return $this->
LibStatut($this->statut, $mode);
2053 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
2054 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
2056 $statusType =
'status'.$status;
2057 if ($status == self::STATUS_VALIDATED) {
2058 $statusType =
'status4';
2060 if ($status == self::STATUS_CLOSED) {
2061 $statusType =
'status6';
2063 if ($status == self::STATUS_CANCELED) {
2064 $statusType =
'status9';
2068 $status_label = $this->signed_status ? $labelStatus . $signed_label : $labelStatus;
2069 $status_label_short = $this->signed_status ? $labelStatusShort . $signed_label : $labelStatusShort;
2071 return dolGetStatus($status_label, $status_label_short,
'', $statusType, $mode);
2083 global $langs, $conf;
2085 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2087 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2088 $return .=
'<div class="info-box info-box-sm">';
2089 $return .=
'<div class="info-box-icon bg-infobox-action">';
2091 $return .=
'</div>';
2092 $return .=
'<div class="info-box-content">';
2093 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
2094 if ($selected >= 0) {
2095 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2097 if (property_exists($this,
'thirdparty') && is_object($this->thirdparty)) {
2098 $return .=
'<br><div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).
'</div>';
2100 if (property_exists($this,
'total_ht')) {
2101 $return .=
'<div class="info-box-ref amount">'.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency).
' '.$langs->trans(
'HT').
'</div>';
2103 if (method_exists($this,
'getLibStatut')) {
2104 $return .=
'<div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2106 $return .=
'</div>';
2107 $return .=
'</div>';
2108 $return .=
'</div>';
2126 dol_syslog(get_class($this).
"::initAsSpecimen");
2129 $order->initAsSpecimen();
2133 $this->
ref =
'SPECIMEN';
2134 $this->specimen = 1;
2136 $this->livraison_id = 0;
2138 $this->date_creation = $now;
2139 $this->date_valid = $now;
2140 $this->date_delivery = $now + 24 * 3600;
2141 $this->date_expedition = $now + 24 * 3600;
2143 $this->entrepot_id = 0;
2144 $this->fk_delivery_address = 0;
2147 $this->commande_id = 0;
2148 $this->commande = $order;
2150 $this->origin_id = 1;
2151 $this->origin =
'commande';
2153 $this->note_private =
'Private note';
2154 $this->note_public =
'Public note';
2158 while ($xnbp < $nbp) {
2160 $line->product_desc = $langs->trans(
"Description").
" ".$xnbp;
2161 $line->product_label = $langs->trans(
"Description").
" ".$xnbp;
2163 $line->qty_asked = 5;
2164 $line->qty_shipped = 4;
2165 $line->fk_product = $this->commande->lines[$xnbp]->fk_product;
2167 $this->lines[] = $line;
2198 if ($user->hasRight(
'expedition',
'creer')) {
2199 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expedition";
2200 $sql .=
" SET date_delivery = ".($delivery_date ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2201 $sql .=
" WHERE rowid = ".((int) $this->
id);
2203 dol_syslog(get_class($this).
"::setDeliveryDate", LOG_DEBUG);
2204 $resql = $this->db->query($sql);
2206 $this->date_delivery = $delivery_date;
2209 $this->error = $this->db->error();
2227 $this->meths = array();
2229 $sql =
"SELECT em.rowid, em.code, em.libelle as label";
2230 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_shipment_mode as em";
2231 $sql .=
" WHERE em.active = 1";
2232 $sql .=
" ORDER BY em.libelle ASC";
2234 $resql = $this->db->query($sql);
2236 while ($obj = $this->db->fetch_object($resql)) {
2237 $label = $langs->trans(
'SendingMethod'.$obj->code);
2238 $this->meths[$obj->rowid] = ($label !=
'SendingMethod'.$obj->code ? $label : $obj->label);
2255 $this->listmeths = array();
2258 $sql =
"SELECT em.rowid, em.code, em.libelle as label, em.description, em.tracking, em.active";
2259 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_shipment_mode as em";
2261 $sql .=
" WHERE em.rowid=".((int) $id);
2264 $resql = $this->db->query($sql);
2266 while ($obj = $this->db->fetch_object($resql)) {
2267 $this->listmeths[$i][
'rowid'] = $obj->rowid;
2268 $this->listmeths[$i][
'code'] = $obj->code;
2269 $label = $langs->trans(
'SendingMethod'.$obj->code);
2270 $this->listmeths[$i][
'libelle'] = ($label !=
'SendingMethod'.$obj->code ? $label : $obj->label);
2271 $this->listmeths[$i][
'description'] = $obj->description;
2272 $this->listmeths[$i][
'tracking'] = $obj->tracking;
2273 $this->listmeths[$i][
'active'] = $obj->active;
2287 if (!empty($this->shipping_method_id)) {
2288 $sql =
"SELECT em.code, em.tracking";
2289 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_shipment_mode as em";
2290 $sql .=
" WHERE em.rowid = ".((int) $this->shipping_method_id);
2292 $resql = $this->db->query($sql);
2294 if ($obj = $this->db->fetch_object($resql)) {
2295 $tracking = $obj->tracking;
2300 if (!empty($tracking) && !empty($value)) {
2301 $url = str_replace(
'{TRACKID}', $value, $tracking);
2302 $this->tracking_url = sprintf(
'<a target="_blank" rel="noopener noreferrer" href="%s">%s</a>', $url, ($value ? $value :
'url'));
2304 $this->tracking_url = $value;
2320 if ($this->statut == self::STATUS_CLOSED) {
2326 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expedition SET fk_statut = ".self::STATUS_CLOSED.
", date_expedition = '".$this->db->escape($this->db->idate(
dol_now())).
"'";
2327 $sql .=
" WHERE rowid = ".((int) $this->
id).
" AND fk_statut > 0";
2329 $resql = $this->db->query($sql);
2332 if ($this->origin ==
'commande' && $this->origin_id > 0) {
2334 $order->fetch($this->origin_id);
2336 $order->loadExpeditions(self::STATUS_CLOSED);
2338 $shipments_match_order = 1;
2339 foreach ($order->lines as $line) {
2340 $lineid = $line->id;
2342 if (($line->product_type == 0 ||
getDolGlobalString(
'STOCK_SUPPORTS_SERVICES')) && $order->expeditions[$lineid] != $qty) {
2343 $shipments_match_order = 0;
2344 $text =
'Qty for order line id '.$lineid.
' is '.$qty.
'. However in the shipments with status Expedition::STATUS_CLOSED='.self::STATUS_CLOSED.
' we have qty = '.$order->expeditions[$lineid].
', so we can t close order';
2349 if ($shipments_match_order) {
2350 dol_syslog(
"Qty for the ".count($order->lines).
" lines of the origin order is same than qty for lines in the shipment we close (shipments_match_order is true), with new status Expedition::STATUS_CLOSED=".self::STATUS_CLOSED.
', so we close order');
2352 $order->cloture($user);
2360 if (!$error && isModEnabled(
'stock') &&
getDolGlobalString(
'STOCK_CALCULATE_ON_SHIPMENT_CLOSE')) {
2369 $result = $this->
call_trigger(
'SHIPPING_CLOSED', $user);
2380 $this->db->commit();
2386 $this->db->rollback();
2406 require_once DOL_DOCUMENT_ROOT .
'/product/stock/class/mouvementstock.class.php';
2408 $langs->load(
"agenda");
2411 $sql =
"SELECT cd.fk_product, cd.subprice,";
2412 $sql .=
" ed.rowid, ed.qty, ed.fk_entrepot,";
2414 $sql .=
" edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock,";
2415 $sql .=
" cd.rowid as cdid, ed.rowid as edid";
2416 $sql .=
" FROM " . MAIN_DB_PREFIX .
"commandedet as cd,";
2417 $sql .=
" " . MAIN_DB_PREFIX .
"expeditiondet as ed";
2418 $sql .=
" LEFT JOIN " . MAIN_DB_PREFIX .
"expeditiondet_batch as edb on edb.fk_expeditiondet = ed.rowid";
2419 $sql .=
" INNER JOIN " . MAIN_DB_PREFIX .
"expedition as e ON ed.fk_expedition = e.rowid";
2420 $sql .=
" WHERE ed.fk_expedition = " . ((int) $this->
id);
2421 $sql .=
" AND cd.rowid = ed.fk_elementdet";
2423 dol_syslog(get_class($this) .
"::valid select details", LOG_DEBUG);
2424 $resql = $this->db->query($sql);
2426 $cpt = $this->db->num_rows($resql);
2427 for ($i = 0; $i < $cpt; $i++) {
2428 $obj = $this->db->fetch_object($resql);
2429 if (empty($obj->edbrowid)) {
2432 $qty = $obj->edbqty;
2434 if ($qty <= 0 || ($qty < 0 && !
getDolGlobalInt(
'SHIPMENT_ALLOW_NEGATIVE_QTY'))) {
2437 dol_syslog(get_class($this) .
"::valid movement index " . $i .
" ed.rowid=" . $obj->rowid .
" edb.rowid=" . $obj->edbrowid);
2440 $mouvS->origin = &$this;
2441 $mouvS->setOrigin($this->element, $this->
id, $obj->cdid, $obj->edid);
2443 if (empty($obj->edbrowid)) {
2447 $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans($labelmovement, $obj->ref));
2449 $this->error = $mouvS->error;
2450 $this->errors = $mouvS->errors;
2458 $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans($labelmovement, $obj->ref),
'', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock);
2460 $this->error = $mouvS->error;
2461 $this->errors = $mouvS->errors;
2469 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_stock WHERE reel = 0 AND rowid NOT IN (SELECT fk_product_stock FROM ".MAIN_DB_PREFIX.
"product_batch as pb)";
2470 $resqldelete = $this->db->query($sqldelete);
2474 $this->error = $this->db->lasterror();
2475 $this->errors[] = $this->db->lasterror();
2494 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'expedition SET billed = 1';
2495 $sql .=
" WHERE rowid = ".((int) $this->
id).
' AND fk_statut > 0';
2497 $resql = $this->db->query($sql);
2502 $result = $this->
call_trigger(
'SHIPPING_BILLED', $user);
2509 $this->errors[] = $this->db->lasterror;
2512 if (empty($error)) {
2513 $this->db->commit();
2516 $this->db->rollback();
2531 if ($this->statut <= self::STATUS_DRAFT) {
2535 return $this->
setStatusCommon($user, self::STATUS_DRAFT, $notrigger,
'SHIPMENT_UNVALIDATE');
2545 global $langs, $user;
2550 if ($this->statut == self::STATUS_VALIDATED) {
2556 $oldbilled = $this->billed;
2558 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'expedition SET fk_statut = 1';
2559 $sql .=
" WHERE rowid = ".((int) $this->
id).
' AND fk_statut > 0';
2561 $resql = $this->db->query($sql);
2568 if (!$error && isModEnabled(
'stock') &&
getDolGlobalString(
'STOCK_CALCULATE_ON_SHIPMENT_CLOSE')) {
2569 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
2571 $langs->load(
"agenda");
2575 $sql =
"SELECT cd.fk_product, cd.subprice,";
2576 $sql .=
" ed.rowid, ed.qty, ed.fk_entrepot,";
2577 $sql .=
" edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock";
2578 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commandedet as cd,";
2579 $sql .=
" ".MAIN_DB_PREFIX.
"expeditiondet as ed";
2580 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expeditiondet_batch as edb on edb.fk_expeditiondet = ed.rowid";
2581 $sql .=
" WHERE ed.fk_expedition = ".((int) $this->
id);
2582 $sql .=
" AND cd.rowid = ed.fk_elementdet";
2584 dol_syslog(get_class($this).
"::valid select details", LOG_DEBUG);
2585 $resql = $this->db->query($sql);
2587 $cpt = $this->db->num_rows($resql);
2588 for ($i = 0; $i < $cpt; $i++) {
2589 $obj = $this->db->fetch_object($resql);
2590 if (empty($obj->edbrowid)) {
2593 $qty = $obj->edbqty;
2598 dol_syslog(get_class($this).
"::reopen expedition movement index ".$i.
" ed.rowid=".$obj->rowid.
" edb.rowid=".$obj->edbrowid);
2602 $mouvS->origin = &$this;
2603 $mouvS->setOrigin($this->element, $this->
id);
2605 if (empty($obj->edbrowid)) {
2609 $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans(
"ShipmentUnClassifyCloseddInDolibarr", $this->ref));
2611 $this->error = $mouvS->error;
2612 $this->errors = $mouvS->errors;
2620 $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans(
"ShipmentUnClassifyCloseddInDolibarr", $this->ref),
'', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock);
2622 $this->error = $mouvS->error;
2623 $this->errors = $mouvS->errors;
2630 $this->error = $this->db->lasterror();
2637 $result = $this->
call_trigger(
'SHIPPING_REOPEN', $user);
2644 $this->errors[] = $this->db->lasterror();
2648 $this->db->commit();
2653 $this->billed = $oldbilled;
2654 $this->db->rollback();
2670 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2672 $outputlangs->load(
"products");
2677 if (!empty($this->model_pdf)) {
2678 $modele = $this->model_pdf;
2684 $modelpath =
"core/modules/expedition/doc/";
2688 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
Class to manage customers orders.
const STATUS_SHIPMENTONPROCESS
Shipment on process.
const STATUS_VALIDATED
Validated status.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteEcmFiles($mode=0)
Delete related files of object in database.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
setStatut($status, $elementId=null, $elementType='', $trigkey='', $fieldstatus='fk_statut')
Set status of an object.
deleteExtraFields()
Delete all extra fields values for the current object.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
fetchObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $clause='OR', $alsosametype=1, $orderby='sourcetype', $loadalsoobjects=1)
Fetch array of objects linked to current object (object of enabled modules only).
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
fetch_origin()
Read linked origin object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage receptions.
Class to manage Dolibarr database access.
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $notooltip=0, $save_lastsearch_value=-1)
Return clickable link of object (with eventually picto)
create_delivery($user)
Create a delivery receipt from a shipment.
setDraft($user, $notrigger=0)
Set draft status.
const STATUS_SHIPMENT_IN_PROGRESS
Expedition in progress -> package exit the warehouse and is now in the truck or into the hand of the ...
getUrlTrackingStatus($value='')
Forge an set tracking url.
setClosed()
Classify the shipping as closed (this records also the stock movement)
__construct($db)
Constructor.
create($user, $notrigger=0)
Create expedition en base.
LibStatut($status, $mode)
Return label of a status.
setBilled()
Classify the shipping as invoiced (used for example by trigger when WORKFLOW_SHIPPING_CLASSIFY_BILLED...
addline($entrepot_id, $id, $qty, $array_options=[])
Add an expedition line.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
getTooltipContentArray($params)
getTooltipContentArray
setDeliveryDate($user, $delivery_date)
Set the planned delivery date.
create_line($entrepot_id, $origin_line_id, $qty, $rang=0, $array_options=[])
Create a expedition line.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
const STATUS_DRAFT
Draft status.
const STATUS_CANCELED
Canceled status.
getLibStatut($mode=0)
Return status label.
set_date_livraison($user, $delivery_date)
Set delivery date.
initAsSpecimen()
Initialise an instance with random values.
addline_batch($dbatch, $array_options=[])
Add a shipment line with batch record.
getNextNumRef($soc)
Return next expedition ref.
const STATUS_CLOSED
Closed status -> parcel was received by customer / end of process prev status : validated or shipment...
const STATUS_VALIDATED
Validated status -> parcel is ready to be sent prev status : draft next status : closed or shipment_i...
create_line_batch($line_ext, $array_options=[])
Create the detail of the expedition line.
manageStockMvtOnEvt($user, $labelmovement='ShipmentClassifyClosedInDolibarr')
Manage Stock MVt onb Close or valid Shipment.
valid($user, $notrigger=0)
Validate object and update stock if option enabled.
update($user=null, $notrigger=0)
Update database.
cancel($notrigger=0, $also_update_stock=false)
Cancel shipment.
fetch_delivery_methods()
Fetch deliveries method and return an array.
fetch($id, $ref='', $ref_ext='', $notused='')
Get object and lines from database.
reOpen()
Classify the shipping as validated/opened.
deleteLine($user, $lineid)
Delete detail line.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
list_delivery_methods($id=0)
Fetch all deliveries method and return an array.
Class to manage lines of shipment.
CRUD class for batch number management within shipment.
Class to manage stock movements.
Class to manage order lines.
Class to manage products or services.
const TYPE_SERVICE
Service.
Manage record for batch number management.
Class to manage third parties objects (customers, suppliers, prospects...)
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
getLibSignedStatus(int $mode=0)
Returns the label for signed status.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
$conf db user
Active Directory does not allow anonymous connections.