function _getArbo(&$PDOdb, &$TAssetOFLine, $fk_product, $fk_nomenclature)
{
    include_once DOL_DOCUMENT_ROOT . '/custom/nomenclature/class/nomenclature.class.php';
    $TRes = array();
    //$TNomen = TNomenclature::get($PDOdb, $fk_product);
    $TCompare = array();
    foreach ($TAssetOFLine->TAssetOFLine as $line) {
        // TODO manque encore les sous-sous-enfants
        $TCompare[$line->fk_product] = $line;
        // Ceci me permet de récupérer le fk_nomenclature associé à la ligne de l'OF
    }
    if ($fk_nomenclature) {
        $TNomen = new TNomenclature();
        $TNomen->load($PDOdb, $fk_nomenclature);
    } else {
        $TNomen = TNomenclature::getDefaultNomenclature($PDOdb, $fk_product);
    }
    if (!empty($TNomen)) {
        foreach ($TNomen->TNomenclatureDet as $key => $TNomenclatureDet) {
            //Vérification que le produit de la nomenclature est bien dans la liste des lignes de l'OF
            if (isset($TCompare[$TNomenclatureDet->fk_product])) {
                $TRes[$TNomenclatureDet->fk_product] = array(0 => $TNomenclatureDet->fk_product, 1 => $TNomenclatureDet->qty, 'childs' => _getArbo($PDOdb, $TCompare[$TNomenclatureDet->fk_product], $TNomenclatureDet->fk_product, $TCompare[$TNomenclatureDet->fk_product]->fk_nomenclature));
            }
        }
    }
    return $TRes;
}
function _liste(&$PDOdb)
{
    global $langs, $db, $user, $conf;
    llxHeader('', $langs->trans('ListOFAsset'), '', '');
    //getStandartJS();
    if (isset($_REQUEST['delete_ok'])) {
        ?>
		<br><div class="error"><?php 
        echo $langs->trans('OFAssetDeleted');
        ?>
</div><br>
		<?php 
    }
    $fk_soc = __get('fk_soc', 0, 'integer');
    $fk_product = __get('fk_product', 0, 'integer');
    $fk_commande = __get('fk_commande', 0, 'integer');
    if ($fk_product > 0) {
        dol_include_once('/core/lib/product.lib.php');
        $product = new Product($db);
        $result = $product->fetch($fk_product);
        $head = product_prepare_head($product, $user);
        $titre = $langs->trans("CardProduct" . $product->type);
        $picto = $product->type == 1 ? 'service' : 'product';
        dol_fiche_head($head, 'tabOF2', $titre, 0, $picto);
    } elseif ($fk_commande > 0) {
        dol_include_once("/core/lib/order.lib.php");
        $commande = new Commande($db);
        $result = $commande->fetch($fk_commande);
        $head = commande_prepare_head($commande, $user);
        $titre = $langs->trans("CustomerOrder" . $product->type);
        dol_fiche_head($head, 'tabOF3', $titre, 0, "order");
    }
    $form = new TFormCore();
    $assetOf = new TAssetOF();
    $r = new TSSRenderControler($assetOf);
    $sql = "SELECT ofe.rowid, ofe.numero, ofe.fk_soc, s.nom as client, SUM(ofel.qty) as nb_product_to_make\n\t\t, GROUP_CONCAT(DISTINCT ofel.fk_product SEPARATOR ',') as fk_product, p.label as product, ofe.ordre, ofe.date_lancement , ofe.date_besoin, ofe.fk_commande,ofe.fk_project\n\t\t, ofe.status, ofe.fk_user,ofe.total_estimated_cost, ofe.total_cost, '' AS printTicket\n\t\t  FROM " . MAIN_DB_PREFIX . "assetOf as ofe \n\t\t  LEFT JOIN " . MAIN_DB_PREFIX . "assetOf_line ofel ON (ofel.fk_assetOf=ofe.rowid AND ofel.type = 'TO_MAKE')\n\t\t  LEFT JOIN " . MAIN_DB_PREFIX . "product p ON (p.rowid = ofel.fk_product)\n\t\t  LEFT JOIN " . MAIN_DB_PREFIX . "societe s ON (s.rowid = ofe.fk_soc)\n\t\t  WHERE ofe.entity=" . $conf->entity;
    if ($fk_soc > 0) {
        $sql .= " AND ofe.fk_soc=" . $fk_soc;
    }
    if ($fk_product > 0) {
        $sql .= " AND ofel.fk_product=" . $fk_product;
    }
    if ($fk_commande > 0) {
        $sql .= " AND ofe.fk_commande=" . $fk_commande;
    }
    $sql .= " GROUP BY ofe.rowid ";
    // TODO je me rappelle plus pourquoi j'ai fait cette merde mais ça fait planter le tri, donc à virer.
    /*if($conf->global->ASSET_OF_LIST_BY_ROWID_DESC) $orderBy['ofe.rowid']='DESC';
    	else $orderBy['ofe.date_cre']='DESC';*/
    $TMath = array();
    $THide = array('rowid', 'fk_user', 'fk_product', 'fk_soc');
    if ($fk_commande > 0) {
        $THide[] = 'fk_commande';
    }
    if ($conf->global->OF_NB_TICKET_PER_PAGE == -1) {
        $THide[] = 'printTicket';
    }
    if (empty($user->rights->of->of->price)) {
        $THide[] = 'total_cost';
        $THide[] = 'total_estimated_cost';
    } else {
        $TMath['total_estimated_cost'] = 'sum';
        $TMath['total_cost'] = 'sum';
    }
    if (!empty($fk_product)) {
        $TMath['nb_product_to_make'] = 'sum';
    }
    $form = new TFormCore($_SERVER['PHP_SELF'], 'form', 'GET');
    echo $form->hidden('action', '');
    if ($fk_commande > 0) {
        echo $form->hidden('fk_commande', $fk_commande);
    }
    if ($fk_product > 0) {
        echo $form->hidden('fk_product', $fk_product);
    }
    // permet de garder le filtre produit quand on est sur l'onglet OF d'une fiche produit
    $r->liste($PDOdb, $sql, array('limit' => array('nbLine' => $conf->liste_limit), 'orderBy' => $orderBy, 'subQuery' => array(), 'link' => array('Utilisateur en charge' => '<a href="' . dol_buildpath('/user/card.php?id=@fk_user@', 2) . '">' . img_picto('', 'object_user.png', '', 0) . ' @val@</a>', 'numero' => '<a href="' . dol_buildpath('/of/fiche_of.php?id=@rowid@"', 2) . '>' . img_picto('', 'object_list.png', '', 0) . ' @val@</a>', 'printTicket' => '<input style=width:40px;"" type="number" value="' . (int) $conf->global->OF_NB_TICKET_PER_PAGE . '" name="printTicket[@rowid@]" min="0" />'), 'translate' => array(), 'hide' => $THide, 'type' => array('date_lancement' => 'date', 'date_besoin' => 'date', 'total_cost' => 'money', 'total_estimated_cost' => 'money', 'nb_product_to_make' => 'number'), 'math' => $TMath, 'liste' => array('titre' => $langs->trans('ListOFAsset'), 'image' => img_picto('', 'title.png', '', 0), 'picto_precedent' => img_picto('', 'back.png', '', 0), 'picto_suivant' => img_picto('', 'next.png', '', 0), 'noheader' => (int) isset($_REQUEST['fk_soc']) | (int) isset($_REQUEST['fk_product']), 'messageNothing' => "Il n'y a aucun " . $langs->trans('OFAsset') . " à afficher", 'picto_search' => img_picto('', 'search.png', '', 0)), 'title' => array('numero' => 'Numéro', 'fk_commande' => 'Commande client', 'ordre' => 'Priorité', 'date_lancement' => 'Date du lancement', 'date_besoin' => 'Date du besoin', 'status' => 'Status', 'login' => 'Utilisateur en charge', 'product' => 'Produit', 'client' => 'Client', 'nb_product_to_make' => 'Nb produits à fabriquer', 'total_cost' => 'Coût réel', 'total_estimated_cost' => 'Coût prévu', 'printTicket' => 'impression<br />étiquette', 'fk_project' => 'Projet'), 'orderBy' => array('rowid' => 'DESC'), 'eval' => array('ordre' => 'TAssetOF::ordre(@val@)', 'status' => 'TAssetOF::status(@val@)', 'product' => 'get_format_libelle_produit("@fk_product@")', 'client' => 'get_format_libelle_societe(@fk_soc@)', 'fk_commande' => 'get_format_libelle_commande(@fk_commande@)', 'fk_project' => 'get_format_libelle_projet(@fk_project@)'), 'search' => array('numero' => array('recherche' => true, 'table' => 'ofe'), 'date_lancement' => array('recherche' => 'calendars', 'table' => 'ofe'), 'date_besoin' => array('recherche' => 'calendars', 'table' => 'ofe'), 'status' => array('recherche' => TAssetOF::$TStatus, 'table' => 'ofe'))));
    if ($conf->global->OF_NB_TICKET_PER_PAGE != -1) {
        echo '<p align="right"><input class="button" type="button" onclick="$(this).closest(\'form\').find(\'input[name=action]\').val(\'printTicket\');  $(this).closest(\'form\').submit(); " name="print" value="' . $langs->trans('ofPrintTicket') . '" /></p>';
    }
    $form->end();
    // On n'affiche pas le bouton de création d'OF si on est sur la liste OF depuis l'onglet "OF" de la fiche commande
    if ($fk_commande) {
        $commande = new Commande($db);
        $commande->fetch($fk_commande);
        $r2 = new TSSRenderControler($assetOf);
        $sql = "SELECT c.rowid as fk_commandedet, p.rowid as rowid, p.ref as refProd, p.label as nomProd, c.qty as qteCommandee, c.description, c.product_type";
        $sql .= " FROM " . MAIN_DB_PREFIX . "commandedet c LEFT JOIN " . MAIN_DB_PREFIX . "product p";
        $sql .= " ON (c.fk_product = p.rowid)";
        $sql .= " WHERE c.product_type IN (0,9) AND  c.fk_commande = " . $fk_commande;
        $resql = $db->query($sql);
        //var_dump($db);
        $num = $db->num_rows($resql);
        print_barre_liste($langs->trans('ListOrderProducts'), $page, "liste.php", $param, $sortfield, $sortorder, '', $num);
        $i = 0;
        $form = new TFormCore($_SERVER['PHP_SELF'], 'formMakeOk', 'post');
        echo $form->hidden('fk_commande', __get('fk_commande', 0, 'int'));
        echo $form->hidden('action', 'createOFCommande');
        echo $form->hidden('fk_soc', $commande->socid);
        echo $form->hidden('token', $_SESSION['newtoken']);
        print '<table class="noborder" width="100%">';
        print '<tr class="liste_titre">';
        print_liste_field_titre("#");
        print_liste_field_titre($langs->trans("Ref"), "liste_of.php", "ref", "", $param, '', $sortfield, $sortorder);
        print_liste_field_titre($langs->trans("Label"), "liste_of.php", "label", "", $param, 'align="left"', $sortfield, $sortorder);
        print_liste_field_titre($langs->trans("Quantité à produire"), "liste_of.php", "", "", $param, '', $sortfield, $sortorder);
        print_liste_field_titre($langs->trans("Produits à ajouter à un OF"), "liste_of.php", "", "", $param, '', $sortfield, $sortorder);
        print "</tr>\n";
        $var = 1;
        $bc = array(1 => 'class="pair"', -1 => 'class="impair"');
        while ($prod = $db->fetch_object($resql)) {
            $var = !$var;
            //print "<tr ".$bc[$var].">";
            if ($prod->product_type == 9) {
                print "<tr>";
                print "<td>&nbsp;</td>";
                print "<td colspan=\"4\"><strong>";
                print $prod->description;
                print '</strong></td>';
            } else {
                if (empty($prod->rowid)) {
                    // ligne libre
                    print "<tr>";
                    print "<td>&nbsp;</td>";
                    print "<td colspan=\"4\">";
                    print $prod->description;
                    print '</td>';
                } else {
                    print "<tr " . $bc[$var] . ">";
                    print "<td>" . ($i + 1) . "</td>";
                    print "<td>";
                    $p_static = new Product($db);
                    $p_static->ref = $prod->refProd;
                    $p_static->id = $prod->rowid;
                    print $p_static->getNomUrl(1);
                    print "</td>\n";
                    print '<td>';
                    print $prod->nomProd;
                    print '</td>';
                    print "<td>";
                    print $form->texte('', 'TQuantites[' . $prod->fk_commandedet . ']', $prod->qteCommandee, 3, 255);
                    print "</td>";
                    print "<td>" . $form->checkbox1('', 'TProducts[' . $prod->fk_commandedet . '][' . (int) $prod->rowid . ']', false, true, '', 'checkOF');
                    print "</td>";
                    print "</tr>\n";
                    $i++;
                }
            }
        }
        print '<tr class="liste_titre">';
        echo '<th class="liste_titre" colspan="2">&nbsp;</th><th class="liste_titre">&nbsp;</th><th class="liste_titre">&nbsp;</th>
		<th class="liste_titre"><input type="checkbox" id="checkall" checked="checked" value="1"></th>
		';
        print '</tr>';
        print "</table>";
        ?>
<script type="text/javascript">
			$('input#checkall').change(function() {
				
				$('input.checkOF').prop('checked',$(this).is(':checked'));	
				
			});
			
		</script>
		
		<?php 
        echo '<p align="right">' . $form->btsubmit('Créer OFs', 'subForm') . ' ' . $form->btsubmit('Créer un seul OF', 'subFormAlone') . '</p>';
        $form->end();
        echo '</div>';
        $db->free($resql);
    } else {
        if (!empty($fk_product)) {
            $sql = "SELECT ofe.rowid, ofe.numero, ofe.fk_soc, s.nom as client, SUM(IF(ofel.qty>0,ofel.qty,ofel.qty_needed) ) as nb_product_needed, ofel.fk_product, p.label as product, ofe.ordre, ofe.date_lancement , ofe.date_besoin\n            , ofe.status, ofe.fk_user, ofe.total_cost\n              FROM " . MAIN_DB_PREFIX . "assetOf as ofe \n              LEFT JOIN " . MAIN_DB_PREFIX . "assetOf_line ofel ON (ofel.fk_assetOf=ofe.rowid AND ofel.type = 'NEEDED')\n              LEFT JOIN " . MAIN_DB_PREFIX . "product p ON p.rowid = ofel.fk_product\n              LEFT JOIN " . MAIN_DB_PREFIX . "societe s ON s.rowid = ofe.fk_soc\n              WHERE ofe.entity=" . $conf->entity . " AND ofel.fk_product=" . $fk_product . " AND ofe.status!='CLOSE'";
            $sql .= " GROUP BY ofe.rowid ";
            if ($conf->global->ASSET_OF_LIST_BY_ROWID_DESC) {
                $orderBy['ofe.rowid'] = 'DESC';
            } else {
                $orderBy['ofe.date_cre'] = 'DESC';
            }
            $TMath = array();
            $THide = array('rowid', 'fk_user', 'fk_product', 'fk_soc');
            if (empty($user->rights->asset->of->price)) {
                $THide[] = 'total_cost';
            } else {
                $TMath['total_cost'] = 'sum';
            }
            $TMath['nb_product_needed'] = 'sum';
            $l = new TListviewTBS('listeofproductneeded');
            echo $langs->trans('ofListProductNeeded');
            echo $l->render($PDOdb, $sql, array('limit' => array('nbLine' => $conf->liste_limit), 'orderBy' => $orderBy, 'subQuery' => array(), 'link' => array('Utilisateur en charge' => '<a href="' . dol_buildpath('/user/card.php?id=@fk_user@', 2) . '">' . img_picto('', 'object_user.png', '', 0) . ' @val@</a>', 'numero' => '<a href="' . dol_buildpath('/of/fiche_of.php?id=@rowid@', 2) . '">' . img_picto('', 'object_list.png', '', 0) . ' @val@</a>', 'product' => '<a href="' . dol_buildpath('/product/card.php?id=@fk_product@', 2) . '">' . img_picto('', 'object_product.png', '', 0) . ' @val@</a>', 'client' => '<a href="' . dol_buildpath('/societe/soc.php?id=@fk_soc@', 2) . '">' . img_picto('', 'object_company.png', '', 0) . ' @val@</a>'), 'translate' => array(), 'hide' => $THide, 'type' => array('date_lancement' => 'date', 'date_besoin' => 'date', 'total_cost' => 'money', 'nb_product_needed' => 'number'), 'math' => $TMath, 'liste' => array('titre' => $langs->trans('ListOFAsset'), 'image' => img_picto('', 'title.png', '', 0), 'picto_precedent' => img_picto('', 'back.png', '', 0), 'picto_suivant' => img_picto('', 'next.png', '', 0), 'noheader' => (int) isset($_REQUEST['fk_soc']) | (int) isset($_REQUEST['fk_product']), 'messa geNothing' => "Il n'y a aucun " . $langs->trans('OFAsset') . " à afficher", 'picto_search' => img_picto('', 'search.png', '', 0)), 'title' => array('numero' => 'Numéro', 'ordre' => 'Priorité', 'date_lancement' => 'Date du lancement', 'date_besoin' => 'Date du besoin', 'status' => 'Status', 'login' => 'Utilisateur en charge', 'product' => 'Produit', 'client' => 'Client', 'nb_product_needed' => 'Nb produits nécessaire', 'total_cost' => 'Coût'), 'eval' => array('ordre' => 'TAssetOF::ordre(@val@)', 'status' => 'TAssetOF::status(@val@)', 'product' => 'get_format_libelle_produit(@fk_product@)', 'client' => 'get_format_libelle_societe(@fk_soc@)')));
        }
        echo '<div class="tabsAction">';
        echo '<a id="bt_createOf" class="butAction" href="fiche_of.php?action=new' . (!empty($fk_product) ? '&fk_product=' . $fk_product : '') . '">' . $langs->trans('CreateOFAsset') . '</a>';
        if ($conf->nomenclature->enabled && !empty($fk_product)) {
            dol_include_once('/core/class/html.form.class.php');
            dol_include_once('/asset/lib/asset.lib.php');
            dol_include_once('/nomenclature/class/nomenclature.class.php');
            $doliForm = new Form($db);
            echo $doliForm->selectarray('fk_nomenclature', TNomenclature::get($PDOdb, $fk_product, true));
            echo '<script type="text/javascript">

				    var url_create_of = $("#bt_createOf").attr("href");
	                   	    $("#bt_createOf").attr("href","#");  
                        
					$("#bt_createOf").click(function() {
						var fk_nomenclature = $("select[name=fk_nomenclature]").val();
						var href = url_create_of + "&fk_nomenclature=" + fk_nomenclature;
						$(this).attr("href", href);
					});
			</script>';
        }
        echo '</div>';
    }
    $PDOdb->close();
    llxFooter('');
}
     }
 } else {
     if (!empty($conf->global->IMPORTDEVIS_UPDATE_PRODUCT)) {
         $product->update($product->id, $user);
     }
 }
 //var_dump($product->id);
 $last_line_product = $product->id;
 if ($product->id > 0 && !empty($conf->global->CREATE_PRODUCT_FROM_IMPORT)) {
     $nomenclature = new TNomenclature();
     $nomenclature->loadByObjectId($PDOdb, $product->id, 'product');
     $nomenclature->deleteChildrenNotImported($PDOdb);
 }
 if ($row['fk_propaldet'] > 0) {
     $last_line_id = $row['fk_propaldet'];
     $nomenclature = new TNomenclature();
     $nomenclature->loadByObjectId($PDOdb, $last_line_id, $object->element);
     $nomenclature->deleteChildrenNotImported($PDOdb);
 } else {
     //		var_dump($product->id);
     if ($doliversion >= 3.8) {
         if ($row['fk_unit'] == 'none') {
             $row['fk_unit'] = null;
         }
         if ($object->element == 'facture') {
             $last_line_id = $object->addline($row['label'], $row['price'], $row['qty'], $default_tva, 0, 0, $product->id, 0, '', '', 0, 0, '', 'HT', 0, Facture::TYPE_STANDARD, -1, 0, '', 0, 0, null, 0, '', 0, 100, '', $row['fk_unit']);
         } else {
             if ($object->element == 'propal') {
                 $last_line_id = $object->addline($row['label'], $row['price'], $row['qty'], $default_tva, 0, 0, $product->id, 0, 'HT', 0, 0, 0, -1, 0, 0, 0, 0, '', '', '', 0, $row['fk_unit']);
             } else {
                 if ($object->element == 'commande') {
function _task_from_line_object(&$PDOdb, &$TLine, $type_object)
{
    $TTask = array();
    foreach ($TLine as &$line) {
        $n = new TNomenclature();
        $n->loadByObjectId($PDOdb, $fk_commande, $type_object, true, $line->fk_product, $line->qty);
        foreach ($n->TNomenclatureWorkstation as &$ws) {
            $TTask[] = array('status' => 1, 'id' => 1, 'fk_projet' => 1, 'label' => 'Simul', 'ref' => 'TKSIMUL', 'grid_col' => 0, 'grid_row' => 999999, 'fk_workstation' => $ws->fk_workstation, 'fk_product' => $line->fk_product, 'fk_task_parent' => 0, 'needed_ressource' => 1, 'planned_workload' => $ws->nb_hour, 'progress' => 0, 'fk_soc' => 0, 'TUser' => array(), 'date_start' => time(), 'date_end' => 0, 'date_estimated_end' => 0);
        }
    }
    //var_dump($TTask);
    return $TTask;
}
function _fiche_ligne(&$form, &$of, $type)
{
    global $db, $conf, $langs, $hookmanager;
    //TODO rules guys ! To Facto ! AA
    $formProduct = new FormProduct($db);
    $PDOdb = new TPDOdb();
    $TRes = array();
    foreach ($of->TAssetOFLine as $k => &$TAssetOFLine) {
        $product =& $TAssetOFLine->product;
        if (is_null($product)) {
            $product = new Product($db);
            $product->fetch($TAssetOFLine->fk_product);
            $product->fetch_optionals();
        }
        $conditionnement = $TAssetOFLine->conditionnement;
        if (!empty($conf->asset->enabled)) {
            $TAssetType = new TAsset_type();
            $TAssetType->load($PDOdb, $product->array_options['options_type_asset']);
            $conditionnement_unit = $TAssetType->measuring_units == 'unit' || $TAssetType->gestion_stock == 'UNIT' ? 'unité(s)' : $TAssetOFLine->libUnite();
        } else {
            $conditionnement_unit = 'unité(s)';
            // TODO translate
        }
        //$conditionnement_unit = $TAssetOFLine->libUnite();
        if ($TAssetOFLine->measuring_units != 'unit' && !empty($TAssetOFLine->measuring_units)) {
            $conditionnement_label = ' / ' . $conditionnement . " " . $conditionnement_unit;
            $conditionnement_label_edit = ' par ' . $form->texte('', 'TAssetOFLine[' . $k . '][conditionnement]', $conditionnement, 5, 5, '', '') . $conditionnement_unit;
        } else {
            $conditionnement_label = $conditionnement_label_edit = '';
        }
        if ($TAssetOFLine->type == "NEEDED" && $type == "NEEDED") {
            $stock_needed = TAssetOF::getProductStock($product->id);
            $TLine = array('id' => $TAssetOFLine->getId(), 'idprod' => $form->hidden('TAssetOFLine[' . $k . '][fk_product]', $product->id), 'lot_number' => $of->status == 'DRAFT' ? $form->texte('', 'TAssetOFLine[' . $k . '][lot_number]', $TAssetOFLine->lot_number, 15, 50, 'type_product="NEEDED" fk_product="' . $product->id . '" rel="lot-' . $TAssetOFLine->getId() . '" ', 'TAssetOFLineLot') : $TAssetOFLine->lot_number, 'libelle' => $product->getNomUrl(1) . ' ' . $product->label . ' - ' . ($stock_needed > 0 ? $langs->trans("Stock") . " : " . $stock_needed : '<span style="color:red;font-weight:bold;">' . $langs->trans("Stock") . " : " . $stock_needed . '</span>') . _fiche_ligne_asset($PDOdb, $form, $of, $TAssetOFLine, 'NEEDED'), 'qty_needed' => $TAssetOFLine->qty_needed . $conditionnement_label, 'qty' => $of->status == 'DRAFT' ? $form->texte('', 'TAssetOFLine[' . $k . '][qty]', $TAssetOFLine->qty, 5, 50) : $TAssetOFLine->qty, 'qty_used' => $of->status == 'OPEN' || $of->status == 'CLOSE' ? $form->texte('', 'TAssetOFLine[' . $k . '][qty_used]', $TAssetOFLine->qty_used, 5, 50) : $TAssetOFLine->qty_used, 'qty_toadd' => $TAssetOFLine->qty - $TAssetOFLine->qty_used, 'workstations' => $conf->workstation->enabled ? $TAssetOFLine->visu_checkbox_workstation($db, $of, $form, 'TAssetOFLine[' . $k . '][fk_workstation][]') : '', 'delete' => $form->type_aff == 'edit' && ($of->status == 'DRAFT' || !empty($conf->global->OF_USE_DESTOCKAGE_PARTIEL) && $of->status != 'CLOSE' && empty($TAssetOFLine->qty_used)) ? '<a href="javascript:deleteLine(' . $TAssetOFLine->getId() . ',\'NEEDED\');">' . img_picto('Supprimer', 'delete.png') . '</a>' : '', 'fk_entrepot' => !empty($conf->global->ASSET_MANUAL_WAREHOUSE) && ($of->status == 'DRAFT' || $of->status == 'VALID') && $form->type_aff == 'edit' ? $formProduct->selectWarehouses($TAssetOFLine->fk_entrepot, 'TAssetOFLine[' . $k . '][fk_entrepot]', '', 0, 0, $TAssetOFLine->fk_product) : $TAssetOFLine->getLibelleEntrepot($PDOdb), 'note_private' => $of->status == 'DRAFT' ? $form->zonetexte('', 'TAssetOFLine[' . $k . '][note_private]', $TAssetOFLine->note_private, 50, 1) : $TAssetOFLine->note_private);
            $action = $form->type_aff;
            $parameter = array('of' => &$of, 'line' => &$TLine, 'type' => 'NEEDED');
            $res = $hookmanager->executeHooks('lineObjectOptions', $parameter, $TAssetOFLine, $action);
            if ($res > 0 && !empty($hookmanager->resArray)) {
                $TLine = $hookmanager->resArray;
            }
            $TRes[] = $TLine;
        } elseif ($TAssetOFLine->type == "TO_MAKE" && $type == "TO_MAKE") {
            if (empty($TAssetOFLine->TFournisseurPrice)) {
                $TAssetOFLine->loadFournisseurPrice($PDOdb);
            }
            // Permet de sélectionner par défaut "(Fournisseur "Interne" => Fabrication interne)" si le produit TO_MAKE n'a pas de stock lorsqu'on est en mode edit et que la ligne TO_MAKE n'a pas encore de prix fournisseur enregistré
            dol_include_once('/product/class/product.class.php');
            $p = new Product($db);
            $selected = 0;
            if ($p->fetch($TAssetOFLine->fk_product)) {
                $p->load_stock();
                $p->stock_reel;
                if ($TAssetOFLine->type === 'TO_MAKE' && $p->stock_reel <= 0 && $_REQUEST['action'] === 'edit') {
                    $selected = -2;
                }
            }
            // *************************************************************
            $Tab = array();
            foreach ($TAssetOFLine->TFournisseurPrice as &$objPrice) {
                $label = "";
                //Si on a un prix fournisseur pour le produit
                if ($objPrice->price > 0) {
                    $unit = $objPrice->quantity == 1 ? 'Unité' : 'Unités';
                    $label .= floatval($objPrice->price) . ' ' . $conf->currency . ' - ' . $objPrice->quantity . ' ' . $unit . ' -';
                }
                //Affiche le nom du fournisseur
                $label .= ' (Fournisseur "' . utf8_encode($objPrice->name) . '"';
                //Prix unitaire minimum si renseigné dans le PF
                if ($objPrice->quantity > 0) {
                    ' ' . $objPrice->quantity . ' pièce(s) min,';
                }
                //Affiche le type du PF :
                if ($objPrice->compose_fourni) {
                    //			soit on fabrique les composants
                    $label .= ' => Fabrication interne';
                } elseif ($objPrice->quantity <= 0) {
                    //			soit on a le produit finis déjà en stock
                    $label .= ' => Sortie de stock';
                }
                if ($objPrice->quantity > 0) {
                    //				soit on commande a un fournisseur
                    $label .= ' => Commande fournisseur';
                }
                $label .= ")";
                $Tab[$objPrice->rowid] = array('label' => $label, 'compose_fourni' => $objPrice->compose_fourni ? $objPrice->compose_fourni : 0);
            }
            if ($conf->nomenclature->enabled) {
                dol_include_once('/nomenclature/class/nomenclature.class.php');
                if ($of->status == 'DRAFT' && !$TAssetOFLine->nomenclature_valide) {
                    $TNomenclature = TNomenclature::get($PDOdb, $TAssetOFLine->fk_product, true);
                    if (count($TNomenclature) > 0) {
                        $nomenclature = '<div>' . $form->combo('', 'TAssetOFLine[' . $k . '][fk_nomenclature]', $TNomenclature, $TAssetOFLine->fk_nomenclature);
                        if ($form->type_aff == 'edit') {
                            $nomenclature .= '<a href="#" class="valider_nomenclature" data-id_of="' . $of->getId() . '" data-product="' . $TAssetOFLine->fk_product . '" data-of_line="' . $TAssetOFLine->rowid . '">Valider</a>';
                        } else {
                            $nomenclature .= " - Nomenclature à sélectionner";
                        }
                        $nomenclature .= '</div>';
                    } else {
                        $nomenclature = '';
                    }
                } else {
                    $n = new TNomenclature();
                    $n->load($PDOdb, $TAssetOFLine->fk_nomenclature);
                    $nomenclature = '<div>' . (string) $n;
                    $picture = $TAssetOFLine->nomenclature_valide ? 'ok.png' : 'no.png';
                    $nomenclature .= ' <img src="img/' . $picture . '" style="padding-left: 2px; vertical-align: middle;" /></div>';
                }
            }
            //($of->status=='DRAFT') ? $form->combo('', 'TAssetOFLine['.$k.'][fk_nomenclature]', _getArrayNomenclature($PDOdb, $TAssetOFLine), $TAssetOFLine->fk_nomenclature) : _getTitleNomenclature($PDOdb, $TAssetOFLine->fk_nomenclature)
            $stock_tomake = TAssetOF::getProductStock($product->id);
            $TLine = array('id' => $TAssetOFLine->getId(), 'idprod' => $form->hidden('TAssetOFLine[' . $k . '][fk_product]', $product->id), 'lot_number' => $of->status == 'DRAFT' ? $form->texte('', 'TAssetOFLine[' . $k . '][lot_number]', $TAssetOFLine->lot_number, 15, 50, 'type_product="TO_MAKE" fk_product="' . $product->id . '"', 'TAssetOFLineLot') : $TAssetOFLine->lot_number, 'libelle' => $product->getNomUrl(1) . ' ' . $product->label . ' - ' . $langs->trans("Stock") . " : " . $stock_tomake . _fiche_ligne_asset($PDOdb, $form, $of, $TAssetOFLine, false), 'nomenclature' => $nomenclature, 'addneeded' => $form->type_aff == 'edit' && $of->status == 'DRAFT' ? '<a href="#null" statut="' . $of->status . '" onclick="addAllLines(' . $of->getId() . ',' . $TAssetOFLine->getId() . ',this);">' . img_picto('Mettre à jour les produits nécessaires', 'object_technic.png') . '</a>' : '', 'qty' => $of->status == 'DRAFT' ? $form->texte('', 'TAssetOFLine[' . $k . '][qty]', $TAssetOFLine->qty, 5, 5, '', '') . $conditionnement_label_edit : $TAssetOFLine->qty . $conditionnement_label, 'qty_used' => $of->status == 'OPEN' || $of->status == 'CLOSE' ? $form->texte('', 'TAssetOFLine[' . $k . '][qty_used]', $TAssetOFLine->qty_used, 5, 5, '', '') . $conditionnement_label_edit : $TAssetOFLine->qty_used . $conditionnement_label, 'fk_product_fournisseur_price' => $form->combo('', 'TAssetOFLine[' . $k . '][fk_product_fournisseur_price]', $Tab, $TAssetOFLine->fk_product_fournisseur_price != 0 ? $TAssetOFLine->fk_product_fournisseur_price : $selected, 1, '', 'style="max-width:250px;"'), 'delete' => $form->type_aff == 'edit' && $of->status == 'DRAFT' ? '<a href="#null" onclick="deleteLine(' . $TAssetOFLine->getId() . ',\'TO_MAKE\');">' . img_picto('Supprimer', 'delete.png') . '</a>' : '', 'fk_entrepot' => !empty($conf->global->ASSET_MANUAL_WAREHOUSE) && ($of->status == 'DRAFT' || $of->status == 'VALID' || $of->status == 'NEEDOFFER' || $of->status == 'ONORDER' || $of->status == 'OPEN') && $form->type_aff == 'edit' ? $formProduct->selectWarehouses($TAssetOFLine->fk_entrepot, 'TAssetOFLine[' . $k . '][fk_entrepot]', '', 0, 0, $TAssetOFLine->fk_product) : $TAssetOFLine->getLibelleEntrepot($PDOdb));
            $action = $form->type_aff;
            $parameter = array('of' => &$of, 'line' => &$TLine, 'type' => 'TO_MAKE');
            $res = $hookmanager->executeHooks('lineObjectOptions', $parameter, $TAssetOFLine, $action);
            if ($res > 0 && !empty($hookmanager->resArray)) {
                $TLine = $hookmanager->resArray;
            }
            $TRes[] = $TLine;
        }
    }
    return $TRes;
}
function _getArrayNomenclature(&$PDOdb, $TAssetOFLine = false, $fk_product = false)
{
    global $conf;
    $TRes = array();
    if (!$conf->nomenclature->enabled) {
        return $TRes;
    }
    include_once DOL_DOCUMENT_ROOT . '/custom/nomenclature/class/nomenclature.class.php';
    $fk_product = $TAssetOFLine->fk_product ? $TAssetOFLine->fk_product : $fk_product;
    $TNomen = TNomenclature::get($PDOdb, $fk_product);
    foreach ($TNomen as $TNomenclature) {
        $TRes[$TNomenclature->getId()] = !empty($TNomenclature->title) ? $TNomenclature->title : '(sans titre)';
    }
    return $TRes;
}
 function addWorkStation(&$PDOdb, $fk_product, $fk_nomenclature = 0, $qty_needed = 1)
 {
     global $conf;
     if (!empty($conf->workstation->enabled)) {
         if ($conf->nomenclature->enabled) {
             if ($fk_nomenclature > 0) {
                 dol_include_once('/nomenclature/class/nomenclature.class.php');
                 $n = new TNomenclature();
                 if ($n->load($PDOdb, $fk_nomenclature, true)) {
                     foreach ($n->TNomenclatureWorkstation as &$nws) {
                         if ($nws->nb_hour_manufacture > 0 || $nws->nb_hour_prepare > 0 || $conf->global->ASSET_AUTHORIZE_ADD_WORKSTATION_TIME_0_ON_OF) {
                             $k = $this->addofworkstation($PDOdb, $nws->fk_workstation, $nws->nb_hour_prepare + $nws->nb_hour_manufacture * ($qty_needed / $n->qty_reference), $nws->nb_hour_prepare, $nws->nb_hour_manufacture * ($qty_needed / $n->qty_reference), $nws->rang, $nws->note_private, $nws->nb_days_before_beginning);
                             $this->TAssetWorkstationOF[$k]->ws = $nws->workstation;
                         }
                     }
                 }
             }
         } else {
             $sql = "SELECT fk_workstation as fk_asset_workstation, nb_hour";
             $sql .= " FROM " . MAIN_DB_PREFIX . "workstation_product";
             $sql .= " WHERE fk_product = " . $fk_product;
             $PDOdb->Execute($sql);
             while ($res = $PDOdb->Get_line()) {
                 $k = $this->addofworkstation($PDOdb, $nws->fk_workstation, $res->nb_hour);
                 $this->TAssetWorkstationOF[$k]->ws = $ws;
             }
         }
     }
 }