function _genInfoEtiquette(&$db, &$PDOdb, &$TPrintTicket)
{
    global $conf;
    $TInfoEtiquette = array();
    if (empty($TPrintTicket)) {
        return $TInfoEtiquette;
    }
    dol_include_once('/commande/class/commande.class.php');
    $assetOf = new TAssetOF();
    $cmd = new Commande($db);
    $product = new Product($db);
    $pos = 1;
    $cpt = 0;
    foreach ($TPrintTicket as $fk_assetOf => $qty) {
        if ($qty <= 0) {
            continue;
        }
        $load = $assetOf->load($PDOdb, $fk_assetOf);
        if ($load === true) {
            $cmd->fetch($assetOf->fk_commande);
            foreach ($assetOf->TAssetOFLine as &$assetOfLine) {
                if ($assetOfLine->type == 'TO_MAKE' && $product->fetch($assetOfLine->fk_product) > 0) {
                    for ($i = 0; $i < $qty; $i++) {
                        $cpt++;
                        if ($cpt % 2 == 0) {
                            $div = 'pair';
                        } else {
                            $div = 'impair';
                        }
                        $TInfoEtiquette[] = array('numOf' => $assetOf->numero, 'float' => $div, 'refCmd' => $cmd->ref, 'refCliCmd' => $cmd->ref_client, 'refProd' => $product->ref, 'qty_to_print' => $qty, 'qty_to_make' => $assetOfLine->qty, 'label' => wordwrap(preg_replace('/\\s\\s+/', ' ', $product->label), 20, $conf->global->DEFAULT_ETIQUETTES == 2 ? "\n" : "</br>"), 'pos' => ceil($pos / 8));
                        //var_dump($TInfoEtiquette);exit;
                        $pos++;
                        //var_dump($TInfoEtiquette);
                    }
                }
            }
        }
    }
    //exit;
    return $TInfoEtiquette;
}
function _updateToMake($TAssetOFChildId = array(), &$PDOdb, &$db, &$conf, $fk_product, $qty, &$TIdLineModified, &$TNewIdAssetOF)
{
    if (empty($TAssetOFChildId)) {
        return false;
    }
    foreach ($TAssetOFChildId as $idOF) {
        $TAssetOF = new TAssetOF();
        $TAssetOF->load($PDOdb, $idOF);
        foreach ($TAssetOF->TAssetOFLine as $line) {
            //Si le produit TO_MAKE de cette OF correspond au notre, on maj sa qté ainsi que ces needed et on stop le traitement pcq pas besoin d'aller plus loin
            if ($line->type == 'TO_MAKE' && $line->fk_product == $fk_product) {
                $TIdLineModified[] = $TAssetOF->getId();
                $line->qty_needed = $line->qty = $line->qty_used = $qty;
                $line->save($PDOdb);
                _updateNeeded($TAssetOF, $PDOdb, $db, $conf, $line->fk_product, $line->qty, $TIdLineModified, $TNewIdAssetOF, $line);
                return true;
                // on a trouvé la ligne concernée
            }
        }
    }
    return false;
}
/*
 * 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';
    $ATMdb = new TPDOdb();
    $ATMdb->debug = true;
} else {
    $ATMdb = new TPDOdb();
}
global $db;
dol_include_once('/of/class/ordre_fabrication_asset.class.php');
$o = new TAssetOF();
$o->init_db_by_vars($ATMdb);
$o = new TAssetOFLine();
$o->init_db_by_vars($ATMdb);
if (class_exists('TWorkstation')) {
    $o = new TAssetWorkstation();
    $o->init_db_by_vars($ATMdb);
} else {
    exit($langs->trans("moduleWorkstationNeeded") . ' : <a href="https://github.com/ATM-Consulting/dolibarr_module_workstation" target="_blank">' . $langs->trans('DownloadModule') . '</a>');
}
$o = new TAssetWorkstationOF();
$o->init_db_by_vars($ATMdb);
$o = new TAssetWorkstationProduct();
$o->init_db_by_vars($ATMdb);
$o = new TAssetControl();
$o->init_db_by_vars($ATMdb);
function _task(&$db, $id_task, $values = array())
{
    global $user, $langs, $conf;
    $task = new Task($db);
    if ($id_task) {
        $task->fetch($id_task);
        $task->fetch_optionals($id_task);
    }
    if (!empty($values)) {
        _set_values($task, $values);
        if ($values['status'] == 'inprogress') {
            if ($task->progress == 0) {
                $task->progress = 5;
            } else {
                if ($task->progress == 100) {
                    $task->progress = 95;
                }
            }
        } else {
            if ($values['status'] == 'finish') {
                $task->progress = 100;
            } else {
                if ($values['status'] == 'todo') {
                    $task->progress = 0;
                }
            }
        }
        $task->status = $values['status'];
        $task->update($user);
    }
    $task->date_delivery = 0;
    if ($task->date_end > 0 && $task->planned_workload > 0) {
        $velocity = scrum_getVelocity($db, $task->fk_project);
        $task->date_delivery = _get_delivery_date_with_velocity($db, $task, $velocity);
    }
    $dayInSecond = 86400;
    if ($conf->global->TIMESHEET_WORKING_HOUR_PER_DAY) {
        $dayInSecond = 60 * 60 * $conf->global->TIMESHEET_WORKING_HOUR_PER_DAY;
    }
    $task->aff_time = convertSecondToTime($task->duration_effective, 'all', $dayInSecond);
    $task->aff_planned_workload = convertSecondToTime($task->planned_workload, 'all', $dayInSecond);
    $task->time_rest = $task->planned_workload * (1 - $task->progress / 100);
    $task->aff_time_rest = $langs->trans('TimeRest') . ' : ' . convertSecondToTime($task->time_rest, 'all', $dayInSecond);
    $task->long_description = $task->divers = '';
    if ((int) $task->array_options['options_fk_of'] > 0 && $conf->of->enabled) {
        if (!isset($PDOdb)) {
            $PDOdb = new TPDOdb();
        }
        $of = new TAssetOF();
        $of->withChild = false;
        $of->load($PDOdb, $task->array_options['options_fk_of']);
        $link_of = !empty($conf->of->enabled) ? dol_buildpath('/of/fiche_of.php?id=' . $task->array_options['options_fk_of'], 1) : '';
        if ($of->fk_soc > 0) {
            $soc = new Societe($db);
            $soc->fetch($of->fk_soc);
        }
        $task->divers .= '[<a href="' . $link_of . '">' . $of->numero . '</a>] ' . (!empty($soc) ? $soc->getNomUrl() : '') . '<br />';
        if ($of->fk_commande > 0) {
            dol_include_once('/commande/class/commande.class.php');
            $commande = new Commande($db);
            $commande->fetch($of->fk_commande);
            $task->divers .= $commande->getNomUrl(1) . '<br />';
        }
    }
    if ((int) $task->array_options['options_fk_product'] > 0 && (empty($conf->global->SCRUMBOARD_ICON_SET) || $conf->global->SCRUMBOARD_ICON_SET != 'null')) {
        dol_include_once('/product/class/product.class.php');
        $product = new Product($db);
        if ($product->fetch((int) $task->array_options['options_fk_product']) > 0) {
            $task->divers .= '[' . $product->getNomUrl() . ' ' . $product->label . ']<br />';
            $nb_picto = $product->id % 49 - 1;
            $y_picto = floor($nb_picto / 7);
            $x_picto = $nb_picto - $y_picto * 7;
            $w_cell = 27;
            $h_cell = 28;
            $task->divers .= '<div class="picto" style="float:left; margin-left:3px; background-image:url(./img/' . (!empty($conf->global->SCRUMBOARD_ICON_SET) ? $conf->global->SCRUMBOARD_ICON_SET : 'animal-icons-mini') . '.png);background-position:' . $w_cell * -$x_picto . 'px ' . $h_cell * -$y_picto . 'px;width:' . $w_cell . 'px; height:' . $h_cell . 'px;"></div>';
            //var_dump(array($nb_picto,$y_picto, $x_picto,$task->divers));
        }
    }
    if (!empty($task->note_private)) {
        $task->divers .= '<br />' . $task->note_private;
    }
    if ($task->date_start > 0) {
        $task->long_description .= $langs->trans('TaskDateStart') . ' : ' . dol_print_date($task->date_start) . '<br />';
    }
    if ($task->date_end > 0) {
        $task->long_description .= $langs->trans('TaskDateEnd') . ' : ' . dol_print_date($task->date_end) . '<br />';
    }
    if ($task->date_delivery > 0 && $task->date_delivery > $task->date_end) {
        $task->long_description .= $langs->trans('TaskDateShouldDelivery') . ' : ' . dol_print_date($task->date_delivery) . '<br />';
    }
    $task->long_description .= $task->description;
    $task->project = new Project($db);
    $task->project->fetch($task->fk_project);
    $task->project->fetch_optionals($task->fk_project, 'color');
    if (!empty($conf->global->SCRUM_SHOW_LINKED_CONTACT)) {
        getTContact($task);
    }
    return _as_array($task);
}
function _fiche(&$PDOdb, &$assetOf, $mode = 'edit', $fk_product_to_add = 0, $fk_nomenclature = 0)
{
    global $langs, $db, $conf, $user, $hookmanager;
    /***************************************************
     * PAGE
     *
     * Put here all code to build page
     ****************************************************/
    $parameters = array('id' => $assetOf->getId());
    $reshook = $hookmanager->executeHooks('doActions', $parameters, $assetOf, $mode);
    // Note that $action and $object may have been modified by hook
    //pre($assetOf,true);
    llxHeader('', $langs->trans('OFAsset'), '', '');
    print dol_get_fiche_head(ofPrepareHead($assetOf, 'assetOF'), 'fiche', $langs->trans('OFAsset'));
    ?>
<style type="text/css">
		#assetChildContener .OFMaster {
			
			background:#fff;
			-webkit-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.52);
			-moz-box-shadow:    4px 4px 5px 0px rgba(50, 50, 50, 0.52);
			box-shadow:         4px 4px 5px 0px rgba(50, 50, 50, 0.52);
			
			margin-bottom:20px;
		}
		
	</style>
		<div class="OFContent" rel="<?php 
    echo $assetOf->getId();
    ?>
">	<?php 
    $TPrixFournisseurs = array();
    //$form=new TFormCore($_SERVER['PHP_SELF'],'formeq'.$assetOf->getId(),'POST');
    //Affichage des erreurs
    if (!empty($assetOf->errors)) {
        ?>
		<br><div class="error">
		<?php 
        foreach ($assetOf->errors as $error) {
            echo $error . "<br>";
            setEventMessage($error, 'errors');
        }
        $assetOf->errors = array();
        ?>
		</div><br>
		<?php 
    }
    $form = new TFormCore();
    $form->Set_typeaff($mode);
    $doliform = new Form($db);
    if (!empty($_REQUEST['fk_product'])) {
        echo $form->hidden('fk_product', $_REQUEST['fk_product']);
    }
    $TBS = new TTemplateTBS();
    $liste = new TListviewTBS('asset');
    $TBS->TBS->protect = false;
    $TBS->TBS->noerr = true;
    $PDOdb = new TPDOdb();
    $TNeeded = array();
    $TToMake = array();
    $TNeeded = _fiche_ligne($form, $assetOf, "NEEDED");
    $TToMake = _fiche_ligne($form, $assetOf, "TO_MAKE");
    $TIdCommandeFourn = $assetOf->getElementElement($PDOdb);
    $HtmlCmdFourn = '';
    if (count($TIdCommandeFourn)) {
        foreach ($TIdCommandeFourn as $idcommandeFourn) {
            $cmd = new CommandeFournisseur($db);
            $cmd->fetch($idcommandeFourn);
            $HtmlCmdFourn .= $cmd->getNomUrl(1) . " - " . $cmd->getLibStatut(0);
        }
    }
    ob_start();
    $doliform->select_produits('', 'fk_product', '', $conf->product->limit_size, 0, -1, 2, '', 3, array());
    $select_product = ob_get_clean();
    $Tid = array();
    //$Tid[] = $assetOf->rowid;
    if ($assetOf->getId() > 0) {
        $assetOf->getListeOFEnfants($PDOdb, $Tid);
    }
    $TWorkstation = array();
    foreach ($assetOf->TAssetWorkstationOF as $k => &$TAssetWorkstationOF) {
        $ws =& $TAssetWorkstationOF->ws;
        $TWorkstation[] = array('libelle' => '<a href="' . dol_buildpath('workstation/workstation.php?id=' . $ws->rowid . '&action=view', 2) . '">' . $ws->name . '</a>', 'fk_user' => visu_checkbox_user($PDOdb, $form, $ws->fk_usergroup, $TAssetWorkstationOF->users, 'TAssetWorkstationOF[' . $k . '][fk_user][]', $assetOf->status), 'fk_project_task' => visu_project_task($db, $TAssetWorkstationOF->fk_project_task, $form->type_aff, 'TAssetWorkstationOF[' . $k . '][progress]'), 'fk_task' => visu_checkbox_task($PDOdb, $form, $TAssetWorkstationOF->fk_asset_workstation, $TAssetWorkstationOF->tasks, 'TAssetWorkstationOF[' . $k . '][fk_task][]', $assetOf->status), 'nb_hour' => $assetOf->status == 'DRAFT' && $mode == "edit" ? $form->texte('', 'TAssetWorkstationOF[' . $k . '][nb_hour]', $TAssetWorkstationOF->nb_hour, 3, 10) : ($conf->global->ASSET_USE_CONVERT_TO_TIME ? convertSecondToTime($TAssetWorkstationOF->nb_hour * 3600) : price($TAssetWorkstationOF->nb_hour)), 'nb_hour_real' => $assetOf->status == 'OPEN' && $mode == "edit" ? $form->texte('', 'TAssetWorkstationOF[' . $k . '][nb_hour_real]', $TAssetWorkstationOF->nb_hour_real, 3, 10) : ($conf->global->ASSET_USE_CONVERT_TO_TIME ? convertSecondToTime($TAssetWorkstationOF->nb_hour_real * 3600) : price($TAssetWorkstationOF->nb_hour_real)), 'nb_days_before_beginning' => $assetOf->status == 'DRAFT' && $mode == "edit" ? $form->texte('', 'TAssetWorkstationOF[' . $k . '][nb_days_before_beginning]', $TAssetWorkstationOF->nb_days_before_beginning, 3, 10) : $TAssetWorkstationOF->nb_days_before_beginning, 'delete' => $mode == 'edit' && $assetOf->status == 'DRAFT' ? '<a href="javascript:deleteWS(' . $assetOf->getId() . ',' . $TAssetWorkstationOF->getId() . ');">' . img_picto('Supprimer', 'delete.png') . '</a>' : '', 'note_private' => $assetOf->status == 'DRAFT' && $mode == 'edit' ? $form->zonetexte('', 'TAssetWorkstationOF[' . $k . '][note_private]', $TAssetWorkstationOF->note_private, 50, 1) : $TAssetWorkstationOF->note_private, 'rang' => $assetOf->status == 'DRAFT' && $mode == "edit" ? $form->texte('', 'TAssetWorkstationOF[' . $k . '][rang]', $TAssetWorkstationOF->rang, 3, 10) : $TAssetWorkstationOF->rang, 'id' => $ws->getId());
    }
    $client = new Societe($db);
    if ($assetOf->fk_soc > 0) {
        $client->fetch($assetOf->fk_soc);
    }
    $commande = new Commande($db);
    if ($assetOf->fk_commande > 0) {
        $commande->fetch($assetOf->fk_commande);
    }
    $TOFParent = array_merge(array(0 => ''), $assetOf->getCanBeParent($PDOdb));
    $hasParent = false;
    if (!empty($assetOf->fk_assetOf_parent)) {
        $TAssetOFParent = new TAssetOF();
        $TAssetOFParent->load($PDOdb, $assetOf->fk_assetOf_parent);
        $hasParent = true;
    }
    $parameters = array('id' => $assetOf->getId());
    $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $assetOf, $mode);
    // Note that $action and $object may have been modified by hook
    if ($fk_product_to_add > 0) {
        $product_to_add = new Product($db);
        $product_to_add->fetch($fk_product_to_add);
        $link_product_to_add = $product_to_add->getNomUrl(1) . ' ' . $product_to_add->label;
        $quantity_to_create = $form->texte('', 'quantity_to_create', 1, 3, 255);
    } else {
        $link_product_to_add = '';
        $quantity_to_create = '';
    }
    print $TBS->render('tpl/fiche_of.tpl.php', array('TNeeded' => $TNeeded, 'TTomake' => $TToMake, 'workstation' => $TWorkstation), array('assetOf' => array('id' => $assetOf->getId(), 'numero' => $assetOf->getId() > 0 ? '<a href="fiche_of.php?id=' . $assetOf->getId() . '">' . $assetOf->getNumero($PDOdb) . '</a>' : $assetOf->getNumero($PDOdb), 'ordre' => $form->combo('', 'ordre', TAssetOf::$TOrdre, $assetOf->ordre), 'fk_commande' => $assetOf->fk_commande == 0 ? '' : $commande->getNomUrl(1), 'commande_fournisseur' => $HtmlCmdFourn, 'date_besoin' => $form->calendrier('', 'date_besoin', $assetOf->date_besoin, 12, 12), 'date_lancement' => $form->calendrier('', 'date_lancement', $assetOf->date_lancement, 12, 12), 'temps_estime_fabrication' => price($assetOf->temps_estime_fabrication, 0, '', 1, -1, 2), 'temps_reel_fabrication' => price($assetOf->temps_reel_fabrication, 0, '', 1, -1, 2), 'fk_soc' => $mode == 'edit' ? $doliform->select_company($assetOf->fk_soc, 'fk_soc', 'client=1', 1) : ($client->id ? $client->getNomUrl(1) : ''), 'fk_project' => custom_select_projects(-1, $assetOf->fk_project, 'fk_project', $mode), 'note' => $form->zonetexte('', 'note', $assetOf->note, 80, 5), 'quantity_to_create' => $quantity_to_create, 'product_to_create' => $link_product_to_add, 'status' => $form->combo('', 'status', TAssetOf::$TStatus, $assetOf->status), 'statustxt' => TAssetOf::$TStatus[$assetOf->status], 'idChild' => !empty($Tid) ? '"' . implode('","', $Tid) . '"' : '', 'url' => dol_buildpath('/of/fiche_of.php', 2), 'url_liste' => $assetOf->getId() ? dol_buildpath('/of/fiche_of.php?id=' . $assetOf->getId(), 2) : dol_buildpath('/of/liste_of.php', 2), 'fk_product_to_add' => $fk_product_to_add, 'fk_nomenclature' => $fk_nomenclature, 'fk_assetOf_parent' => $assetOf->fk_assetOf_parent ? $assetOf->fk_assetOf_parent : '', 'link_assetOf_parent' => $hasParent ? '<a href="' . dol_buildpath('/of/fiche_of.php?id=' . $TAssetOFParent->rowid, 2) . '">' . $TAssetOFParent->numero . '</a>' : '', 'total_cost' => price($assetOf->total_cost, 0, '', 1, -1, 2), 'total_estimated_cost' => price($assetOf->total_estimated_cost, 0, '', 1, -1, 2), 'mo_cost' => price($assetOf->mo_cost, 0, '', 1, -1, 2), 'mo_estimated_cost' => price($assetOf->mo_estimated_cost, 0, '', 1, -1, 2), 'compo_cost' => price($assetOf->compo_cost, 0, '', 1, -1, 2), 'compo_estimated_cost' => price($assetOf->compo_estimated_cost, 0, '', 1, -1, 2), 'current_cost_for_to_make' => price($assetOf->current_cost_for_to_make, 0, '', 1, -1, 2)), 'view' => array('mode' => $mode, 'status' => $assetOf->status, 'allow_delete_of_finish' => $user->rights->of->of->allow_delete_of_finish, 'ASSET_USE_MOD_NOMENCLATURE' => (int) $conf->nomenclature->enabled, 'OF_MINIMAL_VIEW_CHILD_OF' => (int) $conf->global->OF_MINIMAL_VIEW_CHILD_OF, 'select_product' => $select_product, 'select_workstation' => $form->combo('', 'fk_asset_workstation', TWorkstation::getWorstations($PDOdb), -1), 'actionChild' => $mode == 'edit' ? __get('actionChild', 'edit') : __get('actionChild', 'view'), 'use_lot_in_of' => (int) (!empty($conf->asset->enabled) && !empty($conf->global->USE_LOT_IN_OF)), 'use_project_task' => (int) $conf->global->ASSET_USE_PROJECT_TASK, 'defined_user_by_workstation' => (int) $conf->global->ASSET_DEFINED_USER_BY_WORKSTATION, 'defined_task_by_workstation' => (int) $conf->global->ASSET_DEFINED_OPERATION_BY_WORKSTATION, 'defined_workstation_by_needed' => (int) $conf->global->ASSET_DEFINED_WORKSTATION_BY_NEEDED, 'defined_manual_wharehouse' => (int) $conf->global->ASSET_MANUAL_WAREHOUSE, 'hasChildren' => (int) (!empty($Tid)), 'user_id' => $user->id, 'workstation_module_activate' => (int) $conf->workstation->enabled, 'show_cost' => (int) $user->rights->of->of->price), 'rights' => array('show_ws_time' => $user->rights->of->of->show_ws_time)));
    echo $form->end_form();
    llxFooter('$Date: 2011/07/31 22:21:57 $ - $Revision: 1.19 $');
}
 /**
  * Overloading the doActions function : replacing the parent's function with the one below
  *
  * @param   array()         $parameters     Hook metadatas (context, etc...)
  * @param   CommonObject    &$object        The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
  * @param   string          &$action        Current action (if set). Generally create or edit or null
  * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
  * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
  */
 function doActions($parameters, &$object, &$action, $hookmanager)
 {
     global $langs, $db, $conf, $user;
     // Constante PRODUIT_SOUSPRODUITS passée à 0 pour ne pas déstocker les sous produits lors de la validation de l'expédition
     /*if(in_array('expeditioncard',explode(':',$parameters['context'])) && $action === "confirm_valid") {
     			
     			$conf->global->PRODUIT_SOUSPRODUITS = 0;
     			
     		}*/
     // --> Maintenant Géré grâce à la constante INDEPENDANT_SUBPRODUCT_STOCK que j'ai rajoutée sur notre Dolibarr
     if ($parameters['currentcontext'] === 'ordersuppliercard') {
         if (GETPOST('action') === 'confirm_commande' && GETPOST('confirm') === 'yes') {
             $time_livraison = $object->date_livraison;
             $res = $db->query("SELECT fk_source as 'fk_of' \n                            FROM " . MAIN_DB_PREFIX . "element_element \n                            WHERE sourcetype='ordre_fabrication' AND fk_target=" . $object->id . " AND targettype='order_supplier' ");
             define('INC_FROM_DOLIBARR', true);
             dol_include_once("/of/config.php");
             dol_include_once("/of/class/ordre_fabrication_asset.class.php");
             if ($obj = $db->fetch_object($res)) {
                 // of lié à la commande
                 $PDOdb = new TPDOdb();
                 $OF = new TAssetOF();
                 $OF->load($PDOdb, $obj->fk_of);
                 $OF->date_lancement = $time_livraison;
                 $OF->save($PDOdb);
             } else {
                 // pas d'of liés directement
                 $TProduct = $TProd = array();
                 foreach ($object->lines as &$l) {
                     if ($l->product_type == 0) {
                         if (empty($l->fk_product)) {
                             continue;
                         }
                         $TProduct[] = $l->fk_product;
                         if (!isset($TProd[$l->fk_product])) {
                             $TProd[$l->fk_product] = 0;
                         }
                         $TProd[$l->fk_product] += $l->qty;
                     }
                 }
                 $res = $db->query("SELECT DISTINCT of.rowid as 'fk_of' \n                            FROM " . MAIN_DB_PREFIX . "assetOf_line ofl\n                            LEFT JOIN " . MAIN_DB_PREFIX . "assetOf of ON (of.rowid = ofl.fk_assetOf)\n                            WHERE ofl.fk_product IN (" . implode(',', $TProduct) . ")\n                            AND of.status='ONORDER'\n                            ORDER BY of.date_besoin ASC");
                 $PDOdb = new TPDOdb();
                 while ($obj = $db->fetch_object($res)) {
                     $OF = new TAssetOF();
                     $OF->load($PDOdb, $obj->fk_of);
                     $to_save = false;
                     foreach ($OF->TAssetOFLine as &$line) {
                         if (isset($TProd[$line->fk_product]) && $TProd[$line->fk_product] > 0) {
                             $TProd[$line->fk_product] -= $line->qty_needed > 0 ? $line->qty_needed : $line->qty;
                             if ($OF->date_lancement < $time_livraison) {
                                 $OF->date_lancement = $time_livraison;
                                 $to_save = true;
                             }
                         }
                     }
                     if ($to_save) {
                         // print 'OF '.$OF->getId().'$time_livraison'.$time_livraison;
                         $OF->save($PDOdb);
                     }
                 }
                 //exit;
             }
         }
     }
     return 0;
 }
 /**
  * Function called when a Dolibarrr business event is done.
  * All functions "run_trigger" are triggered if file
  * is inside directory 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
  */
 public function run_trigger($action, $object, $user, $langs, $conf)
 {
     if ($action === 'ORDER_VALIDATE') {
         global $conf, $db;
         if ($conf->global->CREATE_OF_ON_ORDER_VALIDATE) {
             define('INC_FROM_DOLIBARR', true);
             dol_include_once('/product/class/product.class.php');
             dol_include_once('/of/config.php');
             dol_include_once('/of/class/ordre_fabrication_asset.class.php');
             $PDOdb = new TPDOdb();
             foreach ($object->lines as $line) {
                 // Uniquement si c'est un produit
                 if (!empty($line->fk_product) && $line->fk_product_type == 0) {
                     // On charge le produit pour vérifier son stock
                     $prod = new Product($db);
                     $prod->fetch($line->fk_product);
                     $prod->load_stock();
                     if ($prod->stock_reel < $line->qty) {
                         $assetOF = new TAssetOF();
                         $assetOF->fk_commande = $_REQUEST['id'];
                         $assetOF->fk_soc = $object->socid;
                         $assetOF->addLine($PDOdb, $line->fk_product, 'TO_MAKE', $line->qty);
                         $assetOF->save($PDOdb);
                     }
                 }
             }
         }
     } elseif ($action === 'ORDER_CANCEL') {
         if ($conf->global->DELETE_OF_ON_ORDER_CANCEL) {
             define('INC_FROM_DOLIBARR', true);
             dol_include_once('/of/config.php');
             dol_include_once('/of/class/ordre_fabrication_asset.class.php');
             $PDOdb = new TPDOdb();
             // On récupère les identifiants des of créés à partir de cette commande
             $TID_OF_command = TAssetOF::getTID_OF_command($_REQUEST['id']);
             foreach ($TID_OF_command as $id_of) {
                 $asset = new TAssetOF();
                 $asset->load($PDOdb, $id_of);
                 if ($asset->status == "DRAFT" || $asset->status == "VALID") {
                     $asset->delete($PDOdb);
                 }
             }
         }
     } elseif ($action === 'TASK_TIMESPENT_CREATE') {
         if ($conf->workstation->enabled) {
             define('INC_FROM_DOLIBARR', true);
             dol_include_once('/of/config.php');
             dol_include_once('/of/class/ordre_fabrication_asset.class.php');
             $PDOdb = new TPDOdb();
             $PDOdb->Execute("SELECT rowid \n\t\t\t\t\t\tFROM " . MAIN_DB_PREFIX . "asset_workstation_of \n\t\t\t\t\t\tWHERE fk_project_task=" . $object->id);
             if ($obj = $PDOdb->Get_line()) {
                 $wsof = new TAssetWorkstationOF();
                 $wsof->load($PDOdb, $obj->rowid);
                 $wsof->nb_hour_real = ($object->duration_effective + $object->timespent_duration) / 3600;
                 // Parce que Dolibarr mets le THM à jour après la création de la tâche :/
                 $sql = "UPDATE " . MAIN_DB_PREFIX . "projet_task_time";
                 $sql .= " SET thm = (SELECT thm FROM " . MAIN_DB_PREFIX . "user WHERE rowid = " . $object->timespent_fk_user . ")";
                 // set average hour rate of user
                 $sql .= " WHERE rowid = " . $object->timespent_id;
                 $object->db->query($sql);
                 $wsof->db =& $object->db;
                 $wsof->save($PDOdb);
             }
         }
     } elseif ($action === 'ORDERSUPPLIER_ADD_LIVRAISON') {
         global $db;
         if ($conf->of->enabled) {
             define('INC_FROM_DOLIBARR', true);
             dol_include_once('/of/config.php');
             dol_include_once('/of/class/ordre_fabrication_asset.class.php');
             $resql = $db->query('SELECT fk_statut FROM llx_commande_fournisseur WHERE rowid = ' . $_REQUEST['id']);
             $res = $db->fetch_object($resql);
             if ($res->fk_statut == 5) {
                 // La livraison est totale
                 //On cherche l'OF lié
                 $resql = $db->query("SELECT fk_source \n\t\t\t\t\t\t\t\t\t\t\tFROM " . MAIN_DB_PREFIX . "element_element \n\t\t\t\t\t\t\t\t\t\t\tWHERE fk_target = " . $_REQUEST['id'] . " \n\t\t\t\t\t\t\t\t\t\t\t\tAND sourcetype = 'ordre_fabrication' \n\t\t\t\t\t\t\t\t\t\t\t\tAND targettype = 'order_supplier'");
                 $res = $db->fetch_object($resql);
                 $id_of = $res->fk_source;
                 if ($id_of > 0) {
                     $of = new TAssetOF();
                     $of->load($PDOdb, $id_of);
                     if ($of->status != 'CLOSE') {
                         $of->closeOF($PDOdb);
                         setEventMessage($langs->trans('OFAttachedClosedAutomatically', '<a href="' . dol_buildpath('/of/fiche_of.php?id=' . $id_of, 2) . '">' . $of->numero . '</a>'));
                     }
                 }
             }
         }
     }
     return 0;
 }
 function save(&$PDOdb)
 {
     global $conf;
     $this->setTHM();
     if (!empty($conf->global->ASSET_USE_PROJECT_TASK)) {
         $of = new TAssetOF();
         $of->load($PDOdb, $this->fk_assetOf);
         if ($of->status === 'VALID') {
             $this->manageProjectTask($PDOdb, $of);
         }
     }
     parent::save($PDOdb);
 }