* Copyright (C) 2010-2014 Laurent Destailleur * Copyright (C) 2012-2013 Christophe Battarel * Copyright (C) 2012 Cédric Salvador * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Raphaël Doursenaud * Copyright (C) 2015-2016 Marcos García * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2022 OpenDSI * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Need to have the following variables defined: * $object (invoice, order, ...) * $conf * $langs * $dateSelector * $forceall (0 by default, 1 for supplier invoices/orders) * $senderissupplier (0 by default, 1 or 2 for supplier invoices/orders) * $inputalsopricewithtax (0 by default, 1 to also show column with unit price including tax) */ // Protection to avoid direct call of template if (empty($object) || !is_object($object)) { print "Error: this template page cannot be called directly as an URL"; exit; } '@phan-var-force CommonObject $this @phan-var-force CommonObject $object'; $usemargins = 0; if (isModEnabled('margin') && !empty($object->element) && in_array($object->element, array('facture', 'facturerec', 'propal', 'commande'))) { $usemargins = 1; } if (!isset($dateSelector)) { global $dateSelector; // Take global var only if not already defined into function calling (for example formAddObjectLine) } global $forceall, $forcetoshowtitlelines, $senderissupplier, $inputalsopricewithtax; global $mysoc; if (!isset($dateSelector)) { $dateSelector = 1; // For backward compatibility } elseif (empty($dateSelector)) { $dateSelector = 0; } if (empty($forceall)) { $forceall = 0; } if (empty($senderissupplier)) { $senderissupplier = 0; } if (empty($inputalsopricewithtax)) { $inputalsopricewithtax = 0; } // Define colspan for the button 'Add' $colspan = 3; // Columns: total ht + col edit + col delete if (isModEnabled("multicurrency") && $this->multicurrency_code != $conf->currency) { $colspan++; //Add column for Total (currency) if required } if (in_array($object->element, array('propal', 'commande', 'order', 'facture', 'facturerec', 'invoice', 'supplier_proposal', 'order_supplier', 'invoice_supplier', 'invoice_supplier_rec'))) { $colspan++; // With this, there is a column move button } if (isModEnabled('asset') && $object->element == 'invoice_supplier') { $colspan++; } //print $object->element; // Lines for extrafield $objectline = null; if (!empty($extrafields)) { if ($this->table_element_line == 'commandedet') { $objectline = new OrderLine($this->db); } elseif ($this->table_element_line == 'propaldet') { $objectline = new PropaleLigne($this->db); } elseif ($this->table_element_line == 'supplier_proposaldet') { $objectline = new SupplierProposalLine($this->db); } elseif ($this->table_element_line == 'facturedet') { $objectline = new FactureLigne($this->db); } elseif ($this->table_element_line == 'contratdet') { $objectline = new ContratLigne($this->db); } elseif ($this->table_element_line == 'commande_fournisseurdet') { $objectline = new CommandeFournisseurLigne($this->db); } elseif ($this->table_element_line == 'facture_fourn_det') { $objectline = new SupplierInvoiceLine($this->db); } elseif ($this->table_element_line == 'facturedet_rec') { $objectline = new FactureLigneRec($this->db); } elseif ($this->table_element_line == 'facture_fourn_det_rec') { $objectline = new FactureFournisseurLigneRec($this->db); } } print "\n"; $nolinesbefore = (count($this->lines) == 0 || $forcetoshowtitlelines); if ($nolinesbefore) { ?>
trans('AddNewLine'); ?> element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier' || $object->element == 'invoice_supplier_rec') { // We must have same test in printObjectLines ?> trans('SupplierRef'); ?> trans('VAT'); ?> trans('PriceUHT'); ?> multicurrency_code != $conf->currency) { ?> trans('PriceUHTCurrency'); ?> trans('PriceUTTC'); ?> trans('Qty'); ?> '; print ''; print $langs->trans('Unit'); print ''; } ?> trans('ReductionShort'); ?> situation_cycle_ref) && $this->situation_cycle_ref) { print ''.$langs->trans('Progress').''; if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) { print ''; } print ''; } if (!empty($usemargins)) { if (!$user->hasRight('margins', 'creer')) { $colspan++; } else { print ''; if (getDolGlobalString('MARGIN_TYPE') == "1") { echo $langs->trans('BuyingPrice'); } else { echo $langs->trans('CostPrice'); } echo ''; if (getDolGlobalString('DISPLAY_MARGIN_RATES')) { echo ''.$langs->trans('MarginRate').''; } if (getDolGlobalString('DISPLAY_MARK_RATES')) { echo ''.$langs->trans('MarkRate').''; } } } ?>   '; } $coldisplay++; ?> element == 'contrat') { if (!isModEnabled('product') && !isModEnabled('service') && !getDolGlobalString('CONTRACT_SUPPORT_PRODUCTS')) { $forceall = -1; // With contract, by default, no choice at all, except if CONTRACT_SUPPORT_PRODUCTS is set } elseif (!getDolGlobalString('CONTRACT_SUPPORT_PRODUCTS')) { $forceall = 3; } } // Free line echo ''; // Show radio free line if ($forceall >= 0 && (isModEnabled("product") || isModEnabled("service"))) { echo ''; echo ' '; } else { echo ''; // Show type selector if ($forceall >= 0) { if (!isModEnabled('product') || !isModEnabled('service')) { echo $langs->trans("Type"); } else { echo $langs->trans("FreeLineOfType"); } echo ' '; } } $form->select_type_of_lines(GETPOSTISSET("type") ? GETPOST("type", 'alpha', 2) : -1, 'type', 1, 1, $forceall, ''); echo ''; } // Predefined product/service if (isModEnabled("product") || isModEnabled("service")) { if ($forceall >= 0 && $freelines) { echo '
'; } else { echo ''; } echo ''; echo ' '; $filtertype = ''; if (!empty($object->element) && $object->element == 'contrat' && !getDolGlobalString('CONTRACT_SUPPORT_PRODUCTS')) { $filtertype = '1'; } if (empty($senderissupplier)) { $statustoshow = 1; $statuswarehouse = 'warehouseopen,warehouseinternal'; if (getDolGlobalString('ENTREPOT_WAREHOUSEINTERNAL_NOT_SELL')) { $statuswarehouse = 'warehouseopen'; } if (getDolGlobalString('ENTREPOT_EXTRA_STATUS')) { // hide products in closed warehouse, but show products for internal transfer $form->select_produits(GETPOST('idprod'), 'idprod', $filtertype, getDolGlobalInt('PRODUIT_LIMIT_SIZE'), $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500 widthcentpercentminusx', 0, $statuswarehouse, GETPOST('combinations', 'array')); } else { $form->select_produits(GETPOST('idprod'), 'idprod', $filtertype, getDolGlobalInt('PRODUIT_LIMIT_SIZE'), $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500 widthcentpercentminusx', 0, '', GETPOST('combinations', 'array')); } if (getDolGlobalString('MAIN_AUTO_OPEN_SELECT2_ON_FOCUS_FOR_CUSTOMER_PRODUCTS')) { ?> array('qty' => 'qty', 'remise_percent' => 'discount', 'idprod' => 'idprod'), // html id tags that will be edited with each ajax json response key 'option_disabled' => 'idthatdoesnotexists', // html id to disable once select is done 'warning' => $langs->trans("NoPriceDefinedForThisSupplier") // translation of an error saved into var 'warning' (for example shown we select a disabled option into combo) ); $alsoproductwithnosupplierprice = 0; } else { $ajaxoptions = array( // Disabled: This is useless because setting discount and price_ht after a selection is already managed // by this page itself with a .change on the combolist '#idprodfournprice' //'update' => array('remise_percent' => 'discount', 'price_ht' => 'price_ht') // html id tags that will be edited with each ajax json response key ); $alsoproductwithnosupplierprice = 1; } $form->select_produits_fournisseurs($object->socid, GETPOST('idprodfournprice'), 'idprodfournprice', '', '', $ajaxoptions, 1, $alsoproductwithnosupplierprice, 'minwidth100 maxwidth500 widthcentpercentminusx'); if (getDolGlobalString('MAIN_AUTO_OPEN_SELECT2_ON_FOCUS_FOR_SUPPLIER_PRODUCTS')) { ?> hasRight('produit', 'creer')); $addserviceon = (isModEnabled('service') && $user->hasRight('service', 'creer')); if ($addproducton || $addserviceon) { if ($addproducton && $addserviceon) { echo ''; } else { if ($addproducton) { $url = '/product/card.php?leftmenu=product&action=create&type=0&backtopage='.urlencode($_SERVER["PHP_SELF"]); $newbutton = ''; if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // @FIXME Not working yet $tmpbacktopagejsfields = 'addproduct:id,search_id'; // @phan-suppress-next-line PhanPluginSuspiciousParamOrder print dolButtonToOpenUrlInDialogPopup('addproduct', $langs->transnoentitiesnoconv('AddProduct'), $newbutton, $url, '', '', $tmpbacktopagejsfields); } else { print ''; } } if ($addserviceon) { $url = '/product/card.php?leftmenu=product&action=create&type=1&backtopage='.urlencode($_SERVER["PHP_SELF"]); $newbutton = ''; if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // @FIXME Not working yet $tmpbacktopagejsfields = 'addproduct:id,search_id'; // @phan-suppress-next-line PhanPluginSuspiciousParamOrder print dolButtonToOpenUrlInDialogPopup('addproduct', $langs->transnoentitiesnoconv('AddService'), $newbutton, $url, '', '', $tmpbacktopagejsfields); } else { print ''; } } } } ?> '; echo ''; } if (getDolGlobalString('MAIN_ADD_LINE_AT_POSITION')) { echo '
'.$langs->trans('AddLineOnPosition').' : '; } if (is_object($hookmanager) && empty($senderissupplier)) { $parameters = array('fk_parent_line' => GETPOSTINT('fk_parent_line')); $reshook = $hookmanager->executeHooks('formCreateProductOptions', $parameters, $object, $action); if (!empty($hookmanager->resPrint)) { print $hookmanager->resPrint; } } if (is_object($hookmanager) && !empty($senderissupplier)) { $parameters = array('htmlname' => 'addproduct'); $reshook = $hookmanager->executeHooks('formCreateProductSupplierOptions', $parameters, $object, $action); if (!empty($hookmanager->resPrint)) { print $hookmanager->resPrint; } } if (isModEnabled("product") || isModEnabled("service")) { echo '
'; if (isModEnabled('variants')) { echo '
'; } } // Editor wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $nbrows = ROWS_2; $enabled = (getDolGlobalString('FCKEDITOR_ENABLE_DETAILS') ? $conf->global->FCKEDITOR_ENABLE_DETAILS : 0); if (getDolGlobalString('MAIN_INPUT_DESC_HEIGHT')) { $nbrows = getDolGlobalString('MAIN_INPUT_DESC_HEIGHT'); } $toolbarname = 'dolibarr_details'; if (getDolGlobalString('FCKEDITOR_ENABLE_DETAILS_FULL')) { $toolbarname = 'dolibarr_notes'; } $doleditor = new DolEditor('dp_desc', GETPOST('dp_desc', 'restricthtml'), '', (!getDolGlobalString('MAIN_DOLEDITOR_HEIGHT') ? 100 : $conf->global->MAIN_DOLEDITOR_HEIGHT), $toolbarname, '', false, true, $enabled, $nbrows, '98%'); $doleditor->Create(); // Show autofill date for recurring invoices if (isModEnabled("service") && ($object->element == 'facturerec' || $object->element == 'invoice_supplier_rec')) { echo '

'; echo $langs->trans('AutoFillDateFrom').' '; if (getDolGlobalString('INVOICE_REC_DATE_TO_YES')) { $line->date_start_fill = 1; $line->date_end_fill = 1; } echo $form->selectyesno('date_start_fill', $line->date_start_fill, 1); echo ' - '; echo $langs->trans('AutoFillDateTo').' '; echo $form->selectyesno('date_end_fill', $line->date_end_fill, 1); echo '
'; } if (is_object($objectline)) { $temps = $objectline->showOptionals($extrafields, 'create', array(), '', '', 1, 'line'); if (!empty($temps)) { print '
'; print $temps; print '
'; } } echo ''; if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier' || $object->element == 'invoice_supplier_rec') { // We must have same test in printObjectLines $coldisplay++; ?> "> '; $coldisplay++; if ($object->element == 'propal' || $object->element == 'commande' || $object->element == 'facture' || $object->element == 'facturerec') { $type_tva = 1; } elseif ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier' || $object->element == 'invoice_supplier_rec') { $type_tva = 2; } if ($seller->tva_assuj == "0") { echo ''.vatrate('0', true); } else { echo $form->load_tva('tva_tx', (GETPOSTISSET("tva_tx") ? GETPOST("tva_tx", 'alpha', 2) : -1), $seller, $buyer, 0, 0, '', false, 1, $type_tva); } ?> "> multicurrency_code != $conf->currency) { $coldisplay++; ?> "> "> "> '; print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, "units"); print ''; } $remise_percent = $buyer->remise_percent; if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') { $remise_percent = $seller->remise_supplier_percent; } $coldisplay++; ?> ">% situation_cycle_ref) && $this->situation_cycle_ref) { $coldisplay++; print '%'; if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) { $coldisplay++; print ''; } $coldisplay++; print ''; } if (!empty($usemargins)) { if ($user->hasRight('margins', 'creer')) { $coldisplay++; ?> "> %'; $coldisplay++; } if (getDolGlobalString('DISPLAY_MARK_RATES')) { echo '%'; $coldisplay++; } } } $coldisplay += $colspan; ?> element == 'contrat')) && $dateSelector && GETPOST('type') != '0') { // We show date field if required print ''."\n"; if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) { print ''; } print ''; $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); $prefillDates = false; if (getDolGlobalString('MAIN_FILL_SERVICE_DATES_FROM_LAST_SERVICE_LINE') && !empty($object->lines)) { for ($i = count($object->lines) - 1; $i >= 0; $i--) { $lastline = $object->lines[$i]; if ($lastline->product_type == Product::TYPE_SERVICE && (!empty($lastline->date_start) || !empty($lastline->date_end))) { $date_start_prefill = $lastline->date_start; $date_end_prefill = $lastline->date_end; $prefillDates = true; break; } } } if (!empty($object->element) && $object->element == 'contrat') { print $langs->trans("DateStartPlanned").' '; print $form->selectDate($date_start, "date_start", $usehm, $usehm, 1, "addproduct"); print '   '.$langs->trans("DateEndPlanned").' '; print $form->selectDate($date_end, "date_end", $usehm, $usehm, 1, "addproduct"); } else { print $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; print $form->selectDate($date_start, 'date_start', !getDolGlobalString('MAIN_USE_HOURMIN_IN_DATE_RANGE') ? 0 : 1, !getDolGlobalString('MAIN_USE_HOURMIN_IN_DATE_RANGE') ? 0 : 1, 1, "addproduct", 1, 0); print ' '.$langs->trans('to').' '; print $form->selectDate($date_end, 'date_end', !getDolGlobalString('MAIN_USE_HOURMIN_IN_DATE_RANGE') ? 0 : 1, !getDolGlobalString('MAIN_USE_HOURMIN_IN_DATE_RANGE') ? 0 : 1, 1, "addproduct", 1, 0); } if ($prefillDates) { echo ' '.$langs->trans('FillWithLastServiceDates').''; } print ''; print ''; print ''."\n"; } print "'; print "\n";