This commit is contained in:
Laurent Destailleur 2016-09-11 16:05:38 +02:00
parent 08dc7ade3b
commit 1bb278a587
7 changed files with 227 additions and 367 deletions

View File

@ -2060,9 +2060,10 @@ class Form
* @param string $filtre For a SQL filter
* @param array $ajaxoptions Options for ajax_autocompleter
* @param int $hidelabel Hide label (0=no, 1=yes)
* @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices
* @return void
*/
function select_produits_fournisseurs($socid, $selected='', $htmlname='productid', $filtertype='', $filtre='', $ajaxoptions=array(), $hidelabel=0)
function select_produits_fournisseurs($socid, $selected='', $htmlname='productid', $filtertype='', $filtre='', $ajaxoptions=array(), $hidelabel=0, $alsoproductwithnosupplierprice=0)
{
global $langs,$conf;
global $price_level, $status, $finished;
@ -2084,7 +2085,7 @@ class Form
print '<input type="hidden" id="idprod" name="idprod" value="0" />';
}
// mode=2 means suppliers products
$urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished;
$urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished.'&alsoproductwithnosupplierprice='.$alsoproductwithnosupplierprice;
print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'">';
}
@ -2095,7 +2096,7 @@ class Form
print '<input type="hidden" id="idprod" name="idprod" value="0" />';
print '<script type="text/javascript">$("#'.$htmlname.'").change(function() { $("#idprod").val($(this).val());});</script>';
}
print $this->select_produits_fournisseurs_list($socid,$selected,$htmlname,$filtertype,$filtre,'',-1,0);
print $this->select_produits_fournisseurs_list($socid,$selected,$htmlname,$filtertype,$filtre,'',-1,0,0,$alsoproductwithnosupplierprice);
}
}
@ -2111,9 +2112,10 @@ class Form
* @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request)
* @param int $outputmode 0=HTML select string, 1=Array
* @param int $limit Limit of line number
* @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices
* @return array Array of keys for json
*/
function select_produits_fournisseurs_list($socid,$selected='',$htmlname='productid',$filtertype='',$filtre='',$filterkey='',$statut=-1,$outputmode=0,$limit=100)
function select_produits_fournisseurs_list($socid,$selected='',$htmlname='productid',$filtertype='',$filtre='',$filterkey='',$statut=-1,$outputmode=0,$limit=100,$alsoproductwithnosupplierprice=0)
{
global $langs,$conf,$db;
@ -2167,7 +2169,7 @@ class Form
$num = $this->db->num_rows($result);
//$out.='<select class="flat" id="select'.$htmlname.'" name="'.$htmlname.'">'; // remove select to have id same with combo and ajax
$out.='<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'">';
$out.='<select class="flat maxwidthonsmartphone" id="'.$htmlname.'" name="'.$htmlname.'">';
if (! $selected) $out.='<option value="0" selected>&nbsp;</option>';
else $out.='<option value="0">&nbsp;</option>';
@ -2176,7 +2178,9 @@ class Form
{
$objp = $this->db->fetch_object($result);
$outkey=$objp->idprodfournprice;
$outkey=$objp->idprodfournprice; // id in table of price
if (! $outkey && $alsoproductwithnosupplierprice) $outkey='idprod_'.$objp->rowid; // id of product
$outref=$objp->ref;
$outval='';
$outqty=1;
@ -2185,9 +2189,9 @@ class Form
$outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):'';
$outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):'';
$opt = '<option value="'.$objp->idprodfournprice.'"';
$opt = '<option value="'.$outkey.'"';
if ($selected && $selected == $objp->idprodfournprice) $opt.= ' selected';
if (empty($objp->idprodfournprice)) $opt.=' disabled';
if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt.=' disabled';
$opt.= '>';
$objRef = $objp->ref;
@ -2266,18 +2270,25 @@ class Form
}
if ($objp->supplier_reputation)
{
//TODO dictionnary
$reputations=array(''=>$langs->trans('Standard'),'FAVORITE'=>$langs->trans('Favorite'),'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier'));
//TODO dictionnary
$reputations=array(''=>$langs->trans('Standard'),'FAVORITE'=>$langs->trans('Favorite'),'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier'));
$opt .= " - ".$reputations[$objp->supplier_reputation];
$outval.=" - ".$reputations[$objp->supplier_reputation];
}
}
else
{
$opt.= $langs->trans("NoPriceDefinedForThisSupplier");
$outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier");
if (empty($alsoproductwithnosupplierprice)) // No supplier price defined for couple product/supplier
{
$opt.= $langs->trans("NoPriceDefinedForThisSupplier");
$outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier");
}
else // No supplier price defined for product, even on other suppliers
{
$opt.= $langs->trans("NoPriceDefinedForThisSupplier");
$outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier");
}
}
$opt .= "</option>\n";

View File

@ -37,7 +37,7 @@ if (! empty($conf->margin->enabled) && ! empty($object->element) && in_array($ob
$usemargins=1;
}
global $forceall, $senderissupplier, $inputalsopricewithtax;
global $dateSelector, $forceall, $senderissupplier, $inputalsopricewithtax;
if (empty($dateSelector)) $dateSelector=0;
if (empty($forceall)) $forceall=0;
if (empty($senderissupplier)) $senderissupplier=0;
@ -182,12 +182,21 @@ else {
}
else
{
$ajaxoptions=array(
'update' => array('qty'=>'qty','remise_percent' => 'discount','idprod' => 'idprod'), // html id tags that will be edited with which ajax json response key
'option_disabled' => 'addPredefinedProductButton', // html id to disable once select is done
'warning' => $langs->trans("NoPriceDefinedForThisSupplier") // translation of an error saved into var 'error'
);
$form->select_produits_fournisseurs($object->socid, GETPOST('idprodfournprice'), 'idprodfournprice', '', '', $ajaxoptions, 1);
if ($senderissupplier != 2)
{
$ajaxoptions=array(
'update' => array('qty'=>'qty','remise_percent' => 'discount','idprod' => 'idprod'), // html id tags that will be edited with which ajax json response key
'option_disabled' => 'addPredefinedProductButton', // html id to disable once select is done
'warning' => $langs->trans("NoPriceDefinedForThisSupplier") // translation of an error saved into var 'error'
);
$alsoproductwithnosupplierprice=0;
}
else
{
$ajaxoptions = array();
$alsoproductwithnosupplierprice=1;
}
$form->select_produits_fournisseurs($object->socid, GETPOST('idprodfournprice'), 'idprodfournprice', '', '', $ajaxoptions, 1, $alsoproductwithnosupplierprice);
}
echo '</span>';
}
@ -225,7 +234,7 @@ else {
</td>
<?php if ($object->element == 'supplier_proposal') { ?>
<td class="nobottom linecolresupplier" align="right"><input id="fourn_ref" name="fourn_ref" class="flat" value="" size="12"></td>
<td class="nobottom linecolresupplier" align="right"><input id="fourn_ref" name="fourn_ref" class="flat" size="10" value=""></td>
<?php } ?>
<td class="nobottom linecolvat" align="right"><?php

View File

@ -1293,7 +1293,7 @@ class CommandeFournisseur extends CommonOrder
* @param float $txtva Taux tva
* @param float $txlocaltax1 Localtax1 tax
* @param float $txlocaltax2 Localtax2 tax
* @param int $fk_product Id produit
* @param int $fk_product Id product
* @param int $fk_prod_fourn_price Id supplier price
* @param string $fourn_ref Supplier reference
* @param float $remise_percent Remise

View File

@ -272,9 +272,7 @@ if (empty($reshook))
}
}
/*
* Add a line into product
*/
// Add a product line
if ($action == 'addline' && $user->rights->fournisseur->commande->creer)
{
$langs->load('errors');
@ -426,8 +424,8 @@ if (empty($reshook))
$tva_tx = price2num($tva_tx); // When vat is text input field
// Local Taxes
$localtax1_tx= get_localtax($tva_tx, 1,$mysoc,$object->thirdparty);
$localtax2_tx= get_localtax($tva_tx, 2,$mysoc,$object->thirdparty);
$localtax1_tx= get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
$localtax2_tx= get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
if (GETPOST('price_ht')!=='')
{
@ -2080,184 +2078,6 @@ elseif (! empty($object->id))
$num = count($object->lines);
/*
$i = 0; $total = 0;
if ($num)
{
print '<tr class="liste_titre">';
print '<td>'.$langs->trans('Label').'</td>';
print '<td align="right" width="50">'.$langs->trans('VAT').'</td>';
print '<td align="right" width="80">'.$langs->trans('PriceUHT').'</td>';
print '<td align="right" width="50">'.$langs->trans('Qty').'</td>';
print '<td align="right" width="50">'.$langs->trans('ReductionShort').'</td>';
print '<td align="right" width="50">'.$langs->trans('TotalHTShort').'</td>';
print '<td width="48" colspan="3">&nbsp;</td>';
print "</tr>\n";
}
$var=true;
while ($i < $num)
{
$line = $object->lines[$i];
$var=!$var;
// Show product and description
$type=(! empty($line->product_type)?$line->product_type:(! empty($line->fk_product_type)?$line->fk_product_type:0));
// Try to enhance type detection using date_start and date_end for free lines where type
// was not saved.
$date_start='';
$date_end='';
if (! empty($line->date_start))
{
$date_start=$line->date_start;
$type=1;
}
if (! empty($line->date_end))
{
$date_end=$line->date_end;
$type=1;
}
// Edit line
if ($action != 'editline' || $_GET['rowid'] != $line->id)
{
print '<tr id="row-'.$line->id.'" '.$bc[$var].'>';
// Show product and description
print '<td>';
if ($line->fk_product > 0)
{
print '<a name="'.$line->id.'"></a>'; // ancre pour retourner sur la ligne
$product_static=new ProductFournisseur($db);
$product_static->fetch($line->fk_product);
$text=$product_static->getNomUrl(1,'supplier');
$text.= ' - '.$product_static->libelle;
$description=($conf->global->PRODUIT_DESC_IN_FORM?'':dol_htmlentitiesbr($line->description));
print $form->textwithtooltip($text,$description,3,'','',$i);
// Show range
print_date_range($date_start,$date_end);
// Add description in form
if (! empty($conf->global->PRODUIT_DESC_IN_FORM)) print ($line->description && $line->description!=$product_static->libelle)?'<br>'.dol_htmlentitiesbr($line->description):'';
}
// Description - Editor wysiwyg
if (! $line->fk_product)
{
if ($type==1) $text = img_object($langs->trans('Service'),'service');
else $text = img_object($langs->trans('Product'),'product');
print $text.' '.nl2br($line->description);
// Show range
print_date_range($date_start,$date_end);
}
print '</td>';
print '<td align="right" class="nowrap">'.vatrate($line->tva_tx).'%</td>';
print '<td align="right" class="nowrap">'.price($line->subprice)."</td>\n";
print '<td align="right" class="nowrap">'.$line->qty.'</td>';
if ($line->remise_percent > 0)
{
print '<td align="right" class="nowrap">'.dol_print_reduction($line->remise_percent,$langs)."</td>\n";
}
else
{
print '<td>&nbsp;</td>';
}
print '<td align="right" class="nowrap">'.price($line->total_ht).'</td>';
if (is_object($hookmanager))
{
$parameters=array('line'=>$line,'num'=>$num,'i'=>$i);
$reshook=$hookmanager->executeHooks('printObjectLine',$parameters,$object,$action);
}
if ($object->statut == 0 && $user->rights->fournisseur->commande->creer)
{
print '<td align="center" width="16"><a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=editline&amp;rowid='.$line->id.'#'.$line->id.'">';
print img_edit();
print '</a></td>';
$actiondelete='delete_product_line';
print '<td align="center" width="16"><a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action='.$actiondelete.'&amp;lineid='.$line->id.'">';
print img_delete();
print '</a></td>';
}
else
{
print '<td>&nbsp;</td><td>&nbsp;</td>';
}
print "</tr>";
}
// Edit line
if ($action == 'editline' && $user->rights->fournisseur->commande->creer && ($_GET["rowid"] == $line->id))
{
print "\n";
print '<tr '.$bc[$var].'>';
print '<td>';
print '<input type="hidden" name="elrowid" value="'.$_GET['rowid'].'">';
print '<a name="'.$line->id.'"></a>'; // ancre pour retourner sur la ligne
if ((! empty($conf->product->enabled) || ! empty($conf->service->enabled)) && $line->fk_product > 0)
{
$product_static=new ProductFournisseur($db);
$product_static->fetch($line->fk_product);
$text=$product_static->getNomUrl(1,'supplier');
$text.= ' - '.$product_static->libelle;
$description=($conf->global->PRODUIT_DESC_IN_FORM?'':dol_htmlentitiesbr($line->description));
print $form->textwithtooltip($text,$description,3,'','',$i);
// Show range
print_date_range($date_start,$date_end);
print '<br>';
}
else
{
$forceall=1; // For suppliers, we always show all types
print $form->select_type_of_lines($line->product_type,'type',1,0,$forceall);
if ($forceall || (! empty($conf->product->enabled) && ! empty($conf->service->enabled))
|| (empty($conf->product->enabled) && empty($conf->service->enabled))) print '<br>';
}
if (is_object($hookmanager))
{
$parameters=array('fk_parent_line'=>$line->fk_parent_line, 'line'=>$line,'var'=>$var,'num'=>$num,'i'=>$i);
$reshook=$hookmanager->executeHooks('formEditProductOptions',$parameters,$object,$action);
}
$nbrows=ROWS_2;
if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT;
$doleditor=new DolEditor('eldesc',$line->description,'',200,'dolibarr_details','',false,true,$conf->global->FCKEDITOR_ENABLE_DETAILS,$nbrows,70);
$doleditor->Create();
print '<br>';
print $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' ';
print $form->select_date($date_start,'date_start'.$date_pf,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,'',1,0,1);
print ' '.$langs->trans('to').' ';
print $form->select_date($date_end,'date_end'.$date_pf,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,'',1,0,1);
print '</td>';
print '<td>';
print $form->load_tva('tva_tx',$line->tva_tx,$object->thirdparty,$mysoc);
print '</td>';
print '<td align="right"><input size="5" type="text" name="pu" value="'.price($line->subprice).'"></td>';
print '<td align="right"><input size="2" type="text" name="qty" value="'.$line->qty.'"></td>';
print '<td align="right" class="nowrap"><input size="1" type="text" name="remise_percent" value="'.$line->remise_percent.'"><span class="hideonsmartphone">%</span></td>';
print '<td align="center" colspan="4"><input type="submit" class="button" name="save" value="'.$langs->trans("Save").'">';
print '<br><input type="submit" class="button" name="cancel" value="'.$langs->trans('Cancel').'"></td>';
print '</tr>' . "\n";
}
$i++;
}
*/
// Form to add new line
if ($object->statut == 0 && $user->rights->fournisseur->commande->creer)
{

View File

@ -49,6 +49,8 @@ $action = GETPOST('action', 'alpha');
$id = GETPOST('id', 'int');
$price_by_qty_rowid = GETPOST('pbq', 'int');
$finished = GETPOST('finished', 'int');
$alsoproductwithnosupplierprice = GETPOST('alsoproductwithnosupplierprice', 'int');
/*
* View
@ -157,7 +159,9 @@ if (! empty($action) && $action == 'fetch' && ! empty($id))
}
echo json_encode($outjson);
} else {
}
else
{
require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
$langs->load("products");
@ -181,9 +185,9 @@ if (! empty($action) && $action == 'fetch' && ! empty($id))
$form = new Form($db);
if (empty($mode) || $mode == 1) { // mode=1: customer
$arrayresult = $form->select_produits_list("", $htmlname, $type, "", $price_level, $searchkey, $status, $finished, $outjson, $socid);
$arrayresult = $form->select_produits_list("", $htmlname, $type, 0, $price_level, $searchkey, $status, $finished, $outjson, $socid);
} elseif ($mode == 2) { // mode=2: supplier
$arrayresult = $form->select_produits_fournisseurs_list($socid, "", $htmlname, $type, "", $searchkey, $status, $outjson);
$arrayresult = $form->select_produits_fournisseurs_list($socid, "", $htmlname, $type, "", $searchkey, $status, $outjson, 0, $alsoproductwithnosupplierprice);
}
$db->close();

View File

@ -1309,16 +1309,17 @@ class Product extends CommonObject
/**
* Read price used by a provider
* We enter as input couple prodfournprice/qty or triplet qty/product_id/fourn_ref
* Read price used by a provider.
* We enter as input couple prodfournprice/qty or triplet qty/product_id/fourn_ref.
* This also set some properties on product like ->buyprice, ->fourn_pu, ...
*
* @param int $prodfournprice Id du tarif = rowid table product_fournisseur_price
* @param double $qty Quantity asked
* @param int $product_id Filter on a particular product id
* @param string $fourn_ref Filter on a supplier ref
* @param string $fourn_ref Filter on a supplier ref. 'none' to exclude ref in search.
* @return int <-1 if KO, -1 if qty not enough, 0 if OK but nothing found, id_product if OK and found. May also initialize some properties like (->ref_supplier, buyprice, fourn_pu, vatrate_supplier...)
*/
function get_buyprice($prodfournprice,$qty,$product_id=0,$fourn_ref=0)
function get_buyprice($prodfournprice, $qty, $product_id=0, $fourn_ref='')
{
global $conf;
$result = 0;
@ -1328,8 +1329,9 @@ class Product extends CommonObject
$sql.= " pfp.fk_product, pfp.ref_fourn, pfp.fk_soc, pfp.tva_tx, pfp.fk_supplier_price_expression";
$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
$sql.= " WHERE pfp.rowid = ".$prodfournprice;
if ($qty) $sql.= " AND pfp.quantity <= ".$qty;
if ($qty > 0) $sql.= " AND pfp.quantity <= ".$qty;
$sql.= " ORDER BY pfp.quantity DESC";
dol_syslog(get_class($this)."::get_buyprice first search by prodfournprice/qty", LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
@ -1362,13 +1364,13 @@ class Product extends CommonObject
}
else // If not found
{
// We do a second search by doing a select again but searching with qty, ref and id product
// We do a second search by doing a select again but searching with qty and id product
$sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.fk_soc,";
$sql.= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.tva_tx, pfp.fk_supplier_price_expression";
$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
$sql.= " WHERE pfp.ref_fourn = '".$fourn_ref."'";
$sql.= " AND pfp.fk_product = ".$product_id;
$sql.= " AND pfp.quantity <= ".$qty;
$sql.= " WHERE pfp.fk_product = ".$product_id;
if ($fourn_ref != 'none') $sql.= " AND pfp.ref_fourn = '".$fourn_ref."'";
if ($qty > 0) $sql.= " AND pfp.quantity <= ".$qty;
$sql.= " ORDER BY pfp.quantity DESC";
$sql.= " LIMIT 1";
@ -1405,7 +1407,7 @@ class Product extends CommonObject
}
else
{
return -1; // Ce produit n'existe pas avec cette ref fournisseur ou existe mais qte insuffisante
return -1; // Ce produit n'existe pas avec cet id tarif fournisseur ou existe mais qte insuffisante, ni pour le couple produit/ref fournisseur dans la quantité.
}
}
else

View File

@ -25,6 +25,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/supplier_proposal/card.php
* \ingroup supplier_proposal
* \brief Card supplier proposal
*/
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
@ -96,6 +102,8 @@ if ($id > 0 || ! empty($ref)) {
$hookmanager->initHooks(array('supplier_proposalcard','globalcard'));
$permissionnote = $user->rights->supplier_proposal->creer; // Used by the include of actions_setnotes.inc.php
$permissiondellink=$user->rights->supplier_proposal->creer; // Used by the include of actions_dellink.inc.php
$permissiontoedit=$user->rights->supplier_proposal->creer; // Used by the include of actions_lineupdown.inc.php
/*
@ -354,10 +362,10 @@ if (empty($reshook))
// Extrafields
if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) {
$lines[$i]->fetch_optionals($lines[$i]->rowid);
$array_option = $lines[$i]->array_options;
$array_options = $lines[$i]->array_options;
}
$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option);
$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_options);
if ($result > 0) {
$lineid = $result;
@ -511,22 +519,28 @@ if (empty($reshook))
}
}
// Add line
else if ($action == 'addline' && $user->rights->supplier_proposal->creer) {
// Add a product line
if ($action == 'addline' && $user->rights->supplier_proposal->creer)
{
$langs->load('errors');
$error = 0;
// Set if we used free entry or predefined product
$predef='';
$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
$price_ht = GETPOST('price_ht');
$date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
$date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year'));
if (GETPOST('prod_entry_mode') == 'free')
{
$idprod=0;
$price_ht = GETPOST('price_ht');
$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
}
else
{
$idprod=GETPOST('idprod', 'int');
$price_ht = '';
$tva_tx = '';
}
@ -536,7 +550,7 @@ if (empty($reshook))
// Extrafields
$extrafieldsline = new ExtraFields($db);
$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
$array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
// Unset extrafield
if (is_array($extralabelsline)) {
// Get extra fields
@ -559,8 +573,7 @@ if (empty($reshook))
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors');
$error ++;
}
if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
if (! $error && ($qty >= 0)) {
$pu_ht = 0;
$pu_ttc = 0;
$price_min = 0;
@ -571,150 +584,140 @@ if (empty($reshook))
// Ecrase $pu par celui du produit
// Ecrase $desc par celui du produit
// Ecrase $txtva par celui du produit
if (! empty($idprod)) {
$prod = new Product($db);
$prod->fetch($idprod);
if ((GETPOST('prod_entry_mode') != 'free') && empty($error)) // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
{
$productsupplier = new ProductFournisseur($db);
if (empty($conf->global->SUPPLIER_PROPOSAL_WITH_NOPRICEDEFINED))
{
$idprod=0;
if (GETPOST('idprodfournprice') == -1 || GETPOST('idprodfournprice') == '') $idprod=-99; // Same behaviour than with combolist. When not select idprodfournprice is now -99 (to avoid conflict with next action that may return -1, -2, ...)
}
if (preg_match('/^idprod_([0-9]+)$/',GETPOST('idprodfournprice'), $reg))
{
$idprod=$reg[1];
// Call to init properties of $productsupplier
// So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
$productsupplier->get_buyprice(0, -1, $idprod, 'none'); // We force qty to -1 to be sure to find if a supplier price exist
}
elseif (GETPOST('idprodfournprice') > 0)
{
//$idprod=$productsupplier->get_buyprice(GETPOST('idprodfournprice'), $qty); // Just to see if a price exists for the quantity. Not used to found vat.
$idprod=$productsupplier->get_buyprice(GETPOST('idprodfournprice'), -1); // We force qty to -1 to be sure to find if a supplier price exist
}
if ($idprod > 0)
{
$res=$productsupplier->fetch($idprod);
$label = $productsupplier->label;
$desc = $productsupplier->description;
if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc);
$type = $productsupplier->type;
$tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice'));
$tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice'));
if (empty($tva_tx)) $tva_npr=0;
$localtax1_tx= get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
$localtax2_tx= get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
$result=$object->addline(
$desc,
$productsupplier->fourn_pu,
$qty,
$tva_tx,
$localtax1_tx,
$localtax2_tx,
$productsupplier->id,
$remise_percent,
$type,
$productsupplier->price_ttc,
$tva_npr,
$type,
-1,
0,
GETPOST('fk_parent_line'),
$fournprice,
$buyingprice,
$label,
$array_options,
$ref_fourn
);
}
if ($idprod == -99 || $idprod == 0)
{
// Product not selected
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")).' '.$langs->trans("or").' '.$langs->trans("NoPriceDefinedForThisSupplier"), null, 'errors');
}
if ($idprod == -1)
{
// Quantity too low
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
}
}
else if((GETPOST('price_ht')!=='' || GETPOST('price_ttc')!=='') && empty($error)) // Free product
{
$pu_ht = price2num($price_ht, 'MU');
$pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
$tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
$tva_tx = str_replace('*', '', $tva_tx);
$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
$desc = $product_desc;
$type = GETPOST('type');
$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
// If prices fields are update
$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
if (empty($tva_tx)) $tva_npr=0;
//On garde le prix indiqué dans l'input pour la demande de prix fournisseur
//$pu_ht = $prod->price;
$pu_ht = price2num($price_ht, 'MU');
//$pu_ttc = $prod->price_ttc;
$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
$price_min = $prod->price_min;
$price_base_type = $prod->price_base_type;
// On defini prix unitaire
if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level)
{
$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
}
elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
{
require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
$prodcustprice = new Productcustomerprice($db);
$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
if ($result) {
if (count($prodcustprice->lines) > 0) {
$pu_ht = price($prodcustprice->lines [0]->price);
$pu_ttc = price($prodcustprice->lines [0]->price_ttc);
$price_base_type = $prodcustprice->lines [0]->price_base_type;
$prod->tva_tx = $prodcustprice->lines [0]->tva_tx;
}
}
}
// if price ht is forced (ie: calculated by margin rate and cost price)
if (! empty($price_ht)) {
$pu_ht = price2num($price_ht, 'MU');
$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
}
// On reevalue prix selon taux tva car taux tva transaction peut etre different
// de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
elseif ($tva_tx != $prod->tva_tx) {
if ($price_base_type != 'HT') {
$pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU');
} else {
$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
}
}
$desc = '';
// Define output language
if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
$outputlangs = $langs;
$newlang = '';
if (empty($newlang) && GETPOST('lang_id'))
$newlang = GETPOST('lang_id');
if (empty($newlang))
$newlang = $object->thirdparty->default_lang;
if (! empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
}
$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
} else {
$desc = $prod->description;
}
$desc = dol_concatdesc($desc, $product_desc);
// Add custom code and origin country into description
if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) {
$tmptxt = '(';
if (! empty($prod->customcode))
$tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode;
if (! empty($prod->customcode) && ! empty($prod->country_code))
$tmptxt .= ' - ';
if (! empty($prod->country_code))
$tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0);
$tmptxt .= ')';
$desc = dol_concatdesc($desc, $tmptxt);
}
$type = $prod->type;
} else {
$pu_ht = price2num($price_ht, 'MU');
$pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
$tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
$tva_tx = str_replace('*', '', $tva_tx);
$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
$desc = $product_desc;
$type = GETPOST('type');
$fk_unit= GETPOST('units', 'alpha');
$tva_tx = price2num($tva_tx); // When vat is text input field
// Local Taxes
$localtax1_tx= get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
$localtax2_tx= get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
if (GETPOST('price_ht')!=='')
{
$price_base_type = 'HT';
$ht = price2num(GETPOST('price_ht'));
$ttc = 0;
}
else
{
$ttc = price2num(GETPOST('price_ttc'));
$ht = $ttc / (1 + ($tva_tx / 100));
$price_base_type = 'HT';
}
$result = $object->addline($desc, $ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $ref_fourn);
//$result = $object->addline($desc, $ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', $remise_percent, $price_base_type, $ttc, $type,'','', $date_start, $date_end, $array_options, $fk_unit);
}
// Margin
$fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
$buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
// Local Taxes
$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty);
$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
$info_bits = 0;
if ($tva_npr)
$info_bits |= 0x01;
if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
setEventMessages($mesg, null, 'errors');
} else {
// Insert line
$ref_fourn = GETPOST('fourn_ref');
$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option, $ref_fourn);
if ($result > 0) {
if (! $error && $result > 0)
{
$db->commit();
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
// Define output language
// Define output language
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
{
$outputlangs = $langs;
if (! empty($conf->global->MAIN_MULTILANGS)) {
$newlang = '';
if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha');
if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
if (! empty($newlang)) {
$outputlangs = new Translate("", $conf);
$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang);
$outputlangs->setDefaultLang($newlang);
}
$model=$object->modelpdf;
$ret = $object->fetch($id); // Reload to get new records
$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
$result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
if ($result < 0) dol_print_error($db,$result);
}
unset($_POST['prod_entry_mode']);
@ -722,18 +725,23 @@ if (empty($reshook))
unset($_POST['qty']);
unset($_POST['type']);
unset($_POST['remise_percent']);
unset($_POST['pu']);
unset($_POST['price_ht']);
unset($_POST['multicurrency_price_ht']);
unset($_POST['price_ttc']);
unset($_POST['tva_tx']);
unset($_POST['label']);
unset($_POST['product_ref']);
unset($_POST['product_label']);
unset($_POST['product_desc']);
unset($_POST['fournprice']);
unset($_POST['buying_price']);
unset($localtax1_tx);
unset($localtax2_tx);
unset($_POST['np_marginRate']);
unset($_POST['np_markRate']);
unset($_POST['dp_desc']);
unset($_POST['idprodfournprice']);
unset($_POST['idprod']);
unset($_POST['date_starthour']);
@ -748,12 +756,14 @@ if (empty($reshook))
unset($_POST['date_endday']);
unset($_POST['date_endmonth']);
unset($_POST['date_endyear']);
} else {
$db->rollback();
}
else
{
$db->rollback();
setEventMessages($object->error, $object->errors, 'errors');
}
setEventMessages($object->error, $object->errors, 'errors');
}
//}
}
}
@ -781,7 +791,7 @@ if (empty($reshook))
// Extrafields
$extrafieldsline = new ExtraFields($db);
$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline);
$array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline);
// Unset extrafield
if (is_array($extralabelsline)) {
// Get extra fields
@ -826,7 +836,7 @@ if (empty($reshook))
if (! $error) {
$db->begin();
$ref_fourn = GETPOST('fourn_ref');
$result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $array_option, $ref_fourn);
$result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $array_options, $ref_fourn);
if ($result >= 0) {
$db->commit();
@ -1658,6 +1668,10 @@ if ($action == 'create')
print '<table id="tablelines" class="noborder noshadow" width="100%">';
// Add free products/services form
global $forceall, $senderissupplier, $dateSelector;
$forceall=1; $senderissupplier=2; $dateSelector=0; // $senderissupplier=2 is same than 1 but disable test on minimum qty.
if (! empty($object->lines))
$ret = $object->printObjectLines($action, $soc, $mysoc, $lineid, 1);