function loadLines(&$PDOdb, $id_expeditionLine)
 {
     $sql = "SELECT rowid FROM " . $this->get_table() . " WHERE fk_expeditiondet = " . $id_expeditionLine . " ORDER BY rang";
     $TIdExpedet = TRequeteCore::_get_id_by_sql($PDOdb, $sql);
     foreach ($TIdExpedet as $idexpedet) {
         $dispatchdetail_temp = new TDispatchDetail();
         $dispatchdetail_temp->load($PDOdb, $idexpedet);
         $this->lines[] = $dispatchdetail_temp;
         $this->nbLines = $this->nbLines + 1;
     }
 }
function _addExpeditiondetLine(&$PDOdb, &$TImport, &$expedition, $numserie)
{
    global $db;
    //Charge l'asset lié au numéro de série dans le fichier
    $asset = new TAsset();
    if ($asset->loadBy($PDOdb, $numserie, 'serial_number')) {
        //Charge le produit associé à l'équipement
        $prodAsset = new Product($db);
        $prodAsset->fetch($asset->fk_product);
        $fk_line_expe = (int) GETPOST('lineexpeditionid');
        if (empty($fk_line_expe)) {
            //Récupération de l'indentifiant de la ligne d'expédition concerné par le produit
            foreach ($expedition->lines as $expeline) {
                if ($expeline->fk_product == $prodAsset->id) {
                    $fk_line_expe = $expeline->line_id;
                }
            }
        }
        //Sauvegarde (ajout/MAJ) des lignes de détail d'expédition
        $dispatchdetail = new TDispatchDetail();
        //Si déjà existant => MAj
        $PDOdb->Execute("SELECT rowid FROM " . MAIN_DB_PREFIX . "expeditiondet_asset WHERE fk_asset = " . $asset->rowid . " AND fk_expeditiondet = " . $fk_line_expe . " ");
        if ($PDOdb->Get_line()) {
            $dispatchdetail->load($PDOdb, $PDOdb->Get_field('rowid'));
        }
        $keys = array_keys($TImport);
        $rang = $keys[count($keys) - 1];
        $dispatchdetail->fk_expeditiondet = $fk_line_expe;
        $dispatchdetail->fk_asset = $asset->rowid;
        $dispatchdetail->rang = $rang;
        $dispatchdetail->lot_number = $asset->lot_number;
        $dispatchdetail->weight = GETPOST('quantity') ? GETPOST('quantity') : $asset->contenancereel_value;
        $dispatchdetail->weight_reel = GETPOST('quantity') ? GETPOST('quantity') : $asset->contenancereel_value;
        $dispatchdetail->weight_unit = $asset->contenancereel_units;
        $dispatchdetail->weight_reel_unit = $asset->contenancereel_units;
        $dispatchdetail->save($PDOdb);
        //Rempli le tableau utilisé pour l'affichage des lignes
        $TImport[] = array('ref' => $prodAsset->ref, 'numserie' => $numserie, 'fk_product' => $prodAsset->id, 'fk_expeditiondet' => $expedition->id, 'lot_number' => $asset->lot_number, 'quantity' => GETPOST('quantity') ? GETPOST('quantity') : $asset->contenancereel_value, 'quantity_unit' => GETPOST('quantity') ? GETPOST('quantity') : $asset->contenancereel_units);
    }
    //pre($TImport,true);
    return $TImport;
}
 /** Overloading the doActions function : replacing the parent's function with the one below 
  *  @param      parameters  meta datas of the hook (context, etc...) 
  *  @param      object             the object you want to process (an invoice if you are in invoice module, a propale in propale's module, etc...) 
  *  @param      action             current action (if set). Generally create or edit or null 
  *  @return       void 
  */
 function beforePDFCreation($parameters, &$object, &$action, $hookmanager)
 {
     // pour implementation dans Dolibarr 3.7
     if (in_array('pdfgeneration', explode(':', $parameters['context']))) {
         define('INC_FROM_DOLIBARR', true);
         dol_include_once('/dispatch/config.php');
         dol_include_once('/asset/class/asset.class.php');
         dol_include_once('/dispatch/class/dispatchdetail.class.php');
         global $conf;
         if (isset($parameters['object']) && get_class($object) == 'Expedition') {
             $PDOdb = new TPDOdb();
             foreach ($object->lines as &$line) {
                 $sql = 'SELECT DISTINCT(lot_number),rowid FROM ' . MAIN_DB_PREFIX . 'expeditiondet_asset WHERE fk_expeditiondet = ' . $line->line_id;
                 $PDOdb->Execute($sql);
                 $TRes = $PDOdb->Get_All();
                 if (count($TRes) > 0) {
                     $line->desc .= "<br>Lot(s) expédié(s) : ";
                     foreach ($TRes as $res) {
                         $dispatchDetail = new TDispatchDetail();
                         $dispatchDetail->load($PDOdb, $res->rowid);
                         $asset = new TAsset();
                         $asset->load($PDOdb, $dispatchDetail->fk_asset);
                         $asset->load_asset_type($PDOdb);
                         $unite = $asset->assetType->measuring_units == 'unit' ? 'unité(s)' : measuring_units_string($dispatchDetail->weight_reel_unit, $asset->assetType->measuring_units);
                         $desc = "<br>- " . $res->lot_number . " x " . $dispatchDetail->weight_reel . " " . $unite;
                         if (empty($conf->global->DISPATCH_HIDE_DLUO_PDF)) {
                             $desc .= ' (DLUO : ' . $asset->get_date('dluo') . ')';
                         }
                         $line->desc .= $desc;
                     }
                 }
             }
         }
         //pre($object,true);exit;
     }
 }
<?php

/*
 * Script créant et vérifiant que les champs requis s'ajoutent bien
 * 
 */
if (!defined('INC_FROM_DOLIBARR')) {
    define('INC_FROM_CRON_SCRIPT', true);
    require '../config.php';
    $PDOdb = new TPDOdb();
    $PDOdb->debug = true;
} else {
    $PDOdb = new TPDOdb();
}
dol_include_once('/dispatch/class/dispatchdetail.class.php');
dol_include_once('/dispatch/class/dispatchasset.class.php');
dol_include_once('/asset/class/asset.class.php');
$o = new TDispatchDetail();
$o->init_db_by_vars($PDOdb);
$o = new TRecepDetail();
$o->init_db_by_vars($PDOdb);
$o = new TDispatch();
$o->init_db_by_vars($PDOdb);
$o = new TDispatchAsset();
$o->init_db_by_vars($PDOdb);
 /**
  *      Function called when a Dolibarrr business event is done.
  *      All functions "run_trigger" are triggered if file is inside directory htdocs/core/triggers
  *
  *      @param	string		$action		Event action code
  *      @param  Object		$object     Object
  *      @param  User		$user       Object user
  *      @param  Translate	$langs      Object langs
  *      @param  conf		$conf       Object conf
  *      @return int         			<0 if KO, 0 if no triggered ran, >0 if OK
  */
 function run_trigger($action, $object, $user, $langs, $conf)
 {
     global $conf, $db;
     if (!defined('INC_FROM_DOLIBARR')) {
         define('INC_FROM_DOLIBARR', true);
     }
     if ($action == 'SHIPPING_VALIDATE') {
         dol_include_once('/dispatch/config.php');
         dol_include_once('/dispatch/class/dispatchdetail.class.php');
         $PDOdb = new TPDOdb();
         // Pour chaque ligne de l'expédition
         foreach ($object->lines as $line) {
             // Chargement de l'objet detail dispatch relié à la ligne d'expédition
             $dd = new TDispatchDetail();
             $TIdExpeditionDet = TRequeteCore::get_id_from_what_you_want($PDOdb, MAIN_DB_PREFIX . 'expeditiondet', array('fk_expedition' => $object->id, 'fk_origin_line' => $line->fk_origin_line));
             $idExpeditionDet = $TIdExpeditionDet[0];
             //if(!empty($idExpeditionDet) && $dd->loadBy($PDOdb, $idExpeditionDet, 'fk_expeditiondet')) {
             if (!empty($idExpeditionDet)) {
                 $dd->loadLines($PDOdb, $idExpeditionDet);
                 if ($conf->asset->enabled) {
                     // Création des mouvements de stock de flacon
                     foreach ($dd->lines as $detail) {
                         // Création du mouvement de stock standard
                         $poids_destocke = $this->create_flacon_stock_mouvement($PDOdb, $detail, $object->ref, empty($object->fk_soc) ? $object->socid : $object->fk_soc);
                         //$this->create_standard_stock_mouvement($line, $poids_destocke, $object->ref);
                         if ($conf->clinomadic->enabled) {
                             $asset = new TAsset();
                             $asset->load($PDOdb, $detail->fk_asset);
                             $prod = new Product($db);
                             $prod->fetch($asset->fk_product);
                             //Affectation du type d'équipement pour avoir accès aux extrafields équipement
                             $asset->fk_asset_type = $asset->get_asset_type($PDOdb, $prod->id);
                             $asset->load_asset_type($PDOdb);
                             //Localisation client
                             $asset->fk_societe_localisation = $object->socid;
                             if (!empty($object->linkedObjects['commande'][0]->array_options['options_duree_pret'])) {
                                 $asset->etat = 2;
                                 //Prêté
                                 $asset->set_date('date_deb_pret', $object->date_valid);
                                 $asset->set_date('date_fin_pret', strtotime('+' . $object->commande[0]->array_options['options_duree_pret'] . 'year', $object->date_valid));
                             } else {
                                 $asset->etat = 1;
                                 //Vendu
                             }
                             foreach ($object->linkedObjects['commande'][0]->lines as $line) {
                                 if ($line->fk_product == $asset->fk_product) {
                                     $extension_garantie = $line->array_options['options_extension_garantie'];
                                 }
                             }
                             $nb_year_garantie += $prod->array_options['options_duree_garantie_client'];
                             $asset->date_fin_garantie_cli = strtotime('+' . $nb_year_garantie . 'year', $object->date_valid);
                             $asset->date_fin_garantie_cli = strtotime('+' . $extension_garantie . 'year', $asset->date_fin_garantie_cli);
                             $asset->save($PDOdb);
                         }
                     }
                 }
                 //exit;
             }
             /* else { // Pas de détail, on déstocke la quantité comme Dolibarr standard
             				$this->create_standard_stock_mouvement($line, $line->qty, $object->ref);
             			}*/
         }
         dol_syslog("Trigger '" . $this->name . "' for action '{$action}' launched by " . __FILE__ . ". id=" . $object->id);
     }
     return 0;
 }