diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index 9f9a65f8fcb..7f7a1be2fa7 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -221,6 +221,18 @@ if ($_POST['action'] == 'set_ref_client' && $user->rights->propale->creer)
$propal->set_ref_client($user, $_POST['ref_client']);
}
+// Add milestone
+if ($_POST['action'] == 'addmilestone')
+{
+ $milestone_error=0;
+
+ if ($_POST['milestone_label'] == $langs->trans('Label') || $_POST['milestone_desc'] == $langs->trans('Description'))
+ {
+ $milestone_error++;
+ $mesg = '
'.$langs->trans("ErrorMilestone").'
';
+ }
+}
+
/*
* Creation propale
*/
@@ -631,13 +643,13 @@ if ($_POST['action'] == "addline" && $user->rights->propale->creer)
$mesg=''.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")).'
';
$result = -1 ;
}
- if (empty($_POST['idprod']) && (! isset($_POST["np_price"]) || $_POST["np_price"]=='')) // Unit price can be 0 but not ''
+ if ((empty($_POST['idprod']) && $_POST["type"] < 2) && (! isset($_POST["np_price"]) || $_POST["np_price"]=='')) // Unit price can be 0 but not ''
{
$mesg=''.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")).'
';
$result = -1 ;
}
- if ($result >= 0 && isset($_POST['qty']) && (($_POST['np_price']!='' && ($_POST['np_desc'] || $_POST['dp_desc'])) || $_POST['idprod']))
+ if ($result >= 0)
{
$ret=$propal->fetch($_POST['propalid']);
if ($ret < 0)
@@ -646,110 +658,133 @@ if ($_POST['action'] == "addline" && $user->rights->propale->creer)
exit;
}
$ret=$propal->fetch_client();
-
- $price_base_type = 'HT';
-
- // Ecrase $pu par celui du produit
- // Ecrase $desc par celui du produit
- // Ecrase $txtva par celui du produit
- if ($_POST['idprod'])
+
+ if ($_POST["type"] < 2 && isset($_POST['qty']) && (($_POST['np_price']!='' && ($_POST['np_desc'] || $_POST['dp_desc'])) || $_POST['idprod']))
{
- $prod = new Product($db, $_POST['idprod']);
- $prod->fetch($_POST['idprod']);
-
- $tva_tx = get_default_tva($mysoc,$propal->client,$prod->tva_tx);
- $tva_npr = get_default_npr($mysoc,$propal->client,$prod->tva_tx);
-
- // On defini prix unitaire
- if ($conf->global->PRODUIT_MULTIPRICES && $propal->client->price_level)
+ $price_base_type = 'HT';
+
+ // Ecrase $pu par celui du produit
+ // Ecrase $desc par celui du produit
+ // Ecrase $txtva par celui du produit
+ if ($_POST['idprod'])
{
- $pu_ht = $prod->multiprices[$propal->client->price_level];
- $pu_ttc = $prod->multiprices_ttc[$propal->client->price_level];
- $price_base_type = $prod->multiprices_base_type[$propal->client->price_level];
- }
- else
- {
- $pu_ht = $prod->price;
- $pu_ttc = $prod->price_ttc;
- $price_base_type = $prod->price_base_type;
- }
-
- // 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).
- if ($tva_tx != $prod->tva_tx)
- {
- if ($price_base_type != 'HT')
+ $prod = new Product($db, $_POST['idprod']);
+ $prod->fetch($_POST['idprod']);
+
+ $tva_tx = get_default_tva($mysoc,$propal->client,$prod->tva_tx);
+ $tva_npr = get_default_npr($mysoc,$propal->client,$prod->tva_tx);
+
+ // On defini prix unitaire
+ if ($conf->global->PRODUIT_MULTIPRICES && $propal->client->price_level)
{
- $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU');
+ $pu_ht = $prod->multiprices[$propal->client->price_level];
+ $pu_ttc = $prod->multiprices_ttc[$propal->client->price_level];
+ $price_base_type = $prod->multiprices_base_type[$propal->client->price_level];
}
else
{
- $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU');
+ $pu_ht = $prod->price;
+ $pu_ttc = $prod->price_ttc;
+ $price_base_type = $prod->price_base_type;
}
+
+ // 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).
+ if ($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 = $prod->description;
+ $desc.= ($prod->description && $_POST['np_desc']) ? "\n" : "";
+ $desc.= $_POST['np_desc'];
+ $type = $prod->type;
+ }
+ else
+ {
+ $pu_ht=$_POST['np_price'];
+ $tva_tx=str_replace('*','',$_POST['np_tva_tx']);
+ $tva_npr=preg_match('/\*/',$_POST['np_tva_tx'])?1:0;
+ $desc=$_POST['dp_desc'];
+ $type=$_POST["type"];
+ }
+
+ $info_bits=0;
+ if ($tva_npr) $info_bits |= 0x01;
+
+ if ($prod->price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($prod->price_min)))
+ {
+ $mesg = ''.$langs->trans("CantBeLessThanMinPrice",price2num($prod->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ;
+ }
+ else
+ {
+ // Insert line
+ $result=$propal->addline(
+ $_POST['propalid'],
+ $desc,
+ $pu_ht,
+ $_POST['qty'],
+ $tva_tx,
+ $_POST['idprod'],
+ $_POST['remise_percent'],
+ $price_base_type,
+ $pu_ttc,
+ $info_bits,
+ $type
+ );
}
-
- $desc = $prod->description;
- $desc.= ($prod->description && $_POST['np_desc']) ? "\n" : "";
- $desc.= $_POST['np_desc'];
- $type = $prod->type;
}
- else
+ else if($_POST["type"] == 9 && $_POST['dp_desc'])
{
- $pu_ht=$_POST['np_price'];
- $tva_tx=str_replace('*','',$_POST['np_tva_tx']);
- $tva_npr=preg_match('/\*/',$_POST['np_tva_tx'])?1:0;
$desc=$_POST['dp_desc'];
$type=$_POST["type"];
- }
-
- $info_bits=0;
- if ($tva_npr) $info_bits |= 0x01;
-
- if ($prod->price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($prod->price_min)))
- {
- $mesg = ''.$langs->trans("CantBeLessThanMinPrice",price2num($prod->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ;
- }
- else
- {
+
// Insert line
$result=$propal->addline(
$_POST['propalid'],
$desc,
- $pu_ht,
- $_POST['qty'],
- $tva_tx,
- $_POST['idprod'],
- $_POST['remise_percent'],
- $price_base_type,
- $pu_ttc,
- $info_bits,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 'HT',
+ 0,
+ 0,
$type
);
-
- if ($result > 0)
+ }
+
+ if ($result > 0)
+ {
+ // Define output language
+ $outputlangs = $langs;
+ $newlang='';
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$propal->client->default_lang;
+ if (! empty($newlang))
{
- // Define output language
- $outputlangs = $langs;
- $newlang='';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
- if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$propal->client->default_lang;
- if (! empty($newlang))
- {
- $outputlangs = new Translate("",$conf);
- $outputlangs->setDefaultLang($newlang);
- }
- propale_pdf_create($db, $propal->id, $propal->modelpdf, $outputlangs);
-
- unset($_POST['qty']);
- unset($_POST['type']);
- unset($_POST['np_price']);
- unset($_POST['dp_desc']);
- unset($_POST['np_tva_tx']);
- }
- else
- {
- $mesg=''.$propal->error.'
';
+ $outputlangs = new Translate("",$conf);
+ $outputlangs->setDefaultLang($newlang);
}
+ propale_pdf_create($db, $propal->id, $propal->modelpdf, $outputlangs);
+
+ unset($_POST['qty']);
+ unset($_POST['type']);
+ unset($_POST['np_price']);
+ unset($_POST['dp_desc']);
+ unset($_POST['np_tva_tx']);
+ }
+ else
+ {
+ $mesg=''.$propal->error.'
';
}
}
}
@@ -759,6 +794,8 @@ if ($_POST['action'] == "addline" && $user->rights->propale->creer)
*/
if ($_POST['action'] == 'updateligne' && $user->rights->propale->creer && $_POST["save"] == $langs->trans("Save"))
{
+ $error=0;
+
$propal = new Propal($db);
if (! $propal->fetch($_POST['propalid']) > 0)
{
@@ -766,37 +803,53 @@ if ($_POST['action'] == 'updateligne' && $user->rights->propale->creer && $_POST
exit;
}
$propal->fetch_client();
-
- // Define info_bits
- $info_bits=0;
- if (preg_match('/\*/',$_POST['tva_tx'])) $info_bits |= 0x01;
-
- // Define vat_rate
- $vat_rate=$_POST['tva_tx'];
- $vat_rate=str_replace('*','',$vat_rate);
-
- // On verifie que le prix minimum est respecte
- $productid = $_POST['productid'] ;
- if ($productid)
+
+ if ($_POST['type'] < 2)
{
- $pruduct = new Product($db) ;
- $res=$pruduct->fetch($productid) ;
+ // Define info_bits
+ $info_bits=0;
+ if (preg_match('/\*/',$_POST['tva_tx'])) $info_bits |= 0x01;
+
+ // Define vat_rate
+ $vat_rate=$_POST['tva_tx'];
+ $vat_rate=str_replace('*','',$vat_rate);
+
+ // On verifie que le prix minimum est respecte
+ $productid = $_POST['productid'] ;
+ if ($productid)
+ {
+ $product = new Product($db);
+ $res=$product->fetch($productid);
+ }
+ if ($productid && $product->price_min && ( price2num($_POST['subprice'])*(1-price2num($_POST['remise_percent'])/100) < price2num($product->price_min)))
+ {
+ $mesg = ''.$langs->trans("CantBeLessThanMinPrice",price2num($product->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ;
+ $error++;
+ }
+ else
+ {
+ $result = $propal->updateline($_POST['lineid'],
+ $_POST['subprice'],
+ $_POST['qty'],
+ $_POST['remise_percent'],
+ $vat_rate,
+ $_POST['desc'],
+ 'HT',
+ $info_bits);
+ }
}
- if ($productid && $pruduct->price_min && ( price2num($_POST['subprice'])*(1-price2num($_POST['remise_percent'])/100) < price2num($pruduct->price_min)))
- {
- $mesg = ''.$langs->trans("CantBeLessThanMinPrice",price2num($pruduct->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ;
- }
- else
+ else if ($_POST['type'] == 9 && $_POST['desc'])
{
$result = $propal->updateline($_POST['lineid'],
- $_POST['subprice'],
- $_POST['qty'],
- $_POST['remise_percent'],
- $vat_rate,
- $_POST['desc'],
- 'HT',
- $info_bits);
-
+ 0,
+ 0,
+ 0,
+ 0,
+ $_POST['desc']);
+ }
+
+ if (!$error)
+ {
// Define output language
$outputlangs = $langs;
$newlang='';
@@ -1462,6 +1515,7 @@ if ($id > 0 || ! empty($ref))
else
{
if ($type==1) $text = img_object($langs->trans('Service'),'service');
+ else if ($type==9) $text = img_object($langs->trans('Notes'),'generic');
else $text = img_object($langs->trans('Product'),'product');
print $text.' '.nl2br($objp->description);
@@ -1524,41 +1578,48 @@ if ($id > 0 || ! empty($ref))
print '';
print '';
}
-
- // VAT Rate
- print ''.vatrate($objp->tva_tx,'%',$objp->info_bits).' ';
-
- // U.P HT
- print ''.price($objp->subprice)." \n";
-
- // Qty
- print '';
- if ((($objp->info_bits & 2) != 2) && $objp->special_code != 3)
+
+ if ($objp->product_type < 2)
{
- print $objp->qty;
- }
- else print ' ';
- print ' ';
-
- // Remise percent (negative or positive)
- if (!empty($objp->remise_percent) && $objp->special_code != 3)
- {
- print ''.dol_print_reduction($objp->remise_percent,$langs)." \n";
+ // VAT Rate
+ print ''.vatrate($objp->tva_tx,'%',$objp->info_bits).' ';
+
+ // U.P HT
+ print ''.price($objp->subprice)." \n";
+
+ // Qty
+ print '';
+ if ((($objp->info_bits & 2) != 2) && $objp->special_code != 3)
+ {
+ print $objp->qty;
+ }
+ else print ' ';
+ print ' ';
+
+ // Remise percent (negative or positive)
+ if (!empty($objp->remise_percent) && $objp->special_code != 3)
+ {
+ print ''.dol_print_reduction($objp->remise_percent,$langs)." \n";
+ }
+ else
+ {
+ print ' ';
+ }
+
+ // Montant total HT
+ if ($objp->special_code == 3)
+ {
+ // Si ligne en option
+ print ''.$langs->trans('Option').' ';
+ }
+ else
+ {
+ print ''.price($objp->total_ht)." \n";
+ }
}
else
{
- print ' ';
- }
-
- // Montant total HT
- if ($objp->special_code == 3)
- {
- // Si ligne en option
- print ''.$langs->trans('Option').' ';
- }
- else
- {
- print ''.price($objp->total_ht)." \n";
+ print ' ';
}
// Icone d'edition et suppression
@@ -1614,6 +1675,7 @@ if ($id > 0 || ! empty($ref))
print ' ';
print ' ';
print ' ';
+ print ' ';
print '';
print '';
print ' '; // ancre pour retourner sur la ligne
@@ -1621,51 +1683,56 @@ if ($id > 0 || ! empty($ref))
{
print ' ';
print '';
- if ($objp->fk_product_type==1) print img_object($langs->trans('ShowService'),'service');
+ if ($objp->product_type==1) print img_object($langs->trans('ShowService'),'service');
else print img_object($langs->trans('ShowProduct'),'product');
print ' '.$objp->ref.' ';
print ' - '.nl2br($objp->product_label);
print ' ';
}
- if ($_GET["action"] == 'editline')
+ // editeur wysiwyg
+ if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_DETAILS)
{
- // editeur wysiwyg
- if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_DETAILS)
+ require_once(DOL_DOCUMENT_ROOT."/lib/doleditor.class.php");
+ $doleditor=new DolEditor('desc',$objp->description,164,'dolibarr_details');
+ $doleditor->Create();
+ }
+ else
+ {
+ $nbrows=ROWS_2;
+ if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT;
+ print '';
+ }
+ print ' ';
+ if ($objp->product_type < 2)
+ {
+ if ($conf->global->PRODUIT_USE_MARKUP)
{
- require_once(DOL_DOCUMENT_ROOT."/lib/doleditor.class.php");
- $doleditor=new DolEditor('desc',$objp->description,164,'dolibarr_details');
- $doleditor->Create();
+ print ''.vatrate($objp->marge_tx).'% ';
}
- else
+ print '';
+ print $html->select_tva('tva_tx',$objp->tva_tx,$mysoc,$societe,'',$objp->info_bits);
+ print ' ';
+ print ' ';
+ print '';
+ if (($objp->info_bits & 2) != 2)
{
- $nbrows=ROWS_2;
- if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT;
- print '';
+ print ' ';
}
+ else print ' ';
+ print ' ';
+ print '';
+ if (($objp->info_bits & 2) != 2)
+ {
+ print ' %';
+ }
+ else print ' ';
+ print ' ';
}
- print '';
- if ($conf->global->PRODUIT_USE_MARKUP)
+ else
{
- print ''.vatrate($objp->marge_tx).'% ';
+ print ' ';
}
- print '';
- print $html->select_tva('tva_tx',$objp->tva_tx,$mysoc,$societe,'',$objp->info_bits);
- print ' ';
- print ' ';
- print '';
- if (($objp->info_bits & 2) != 2)
- {
- print ' ';
- }
- else print ' ';
- print ' ';
- print '';
- if (($objp->info_bits & 2) != 2)
- {
- print ' %';
- }
- else print ' ';
- print ' ';
+
print ' ';
print ' ';
print ' ' . "\n";
@@ -1688,6 +1755,61 @@ if ($id > 0 || ! empty($ref))
*/
if ($propal->statut == 0 && $user->rights->propale->creer && $_GET["action"] <> 'editline')
{
+ $var=true;
+
+ if ($conf->milestone->enabled)
+ {
+ $langs->load('@milestone');
+
+ print '';
+ print '';
+ print $langs->trans('AddMilestone').' ';
+ print ' ';
+ print " \n";
+
+ // Add milestone form
+ print '';
+
+ $var=!$var;
+ }
+
if ($conf->global->PRODUIT_USE_MARKUP) $colspan = 'colspan="2"';
print '';
print '';
@@ -1706,7 +1828,6 @@ if ($id > 0 || ! empty($ref))
print ' ';
print ' ';
- $var=true;
print ' \n";
print '';
@@ -1727,6 +1848,7 @@ if ($id > 0 || ! empty($ref))
print ''.$_POST["dp_desc"].' ';
}
print ' ';
+
print '';
if ($societe->tva_assuj == "0")
print ' 0';
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index fc021fca1ca..74f14588fdf 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -478,6 +478,10 @@ class Form
print ''.$langs->trans("Service");
+
+ print ' '.$langs->trans("Notes");
print '';
//if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionnarySetup"),1);
diff --git a/htdocs/includes/modules/propale/pdf_propale_azur.modules.php b/htdocs/includes/modules/propale/pdf_propale_azur.modules.php
index 5e0feb985f3..85cd912abcb 100644
--- a/htdocs/includes/modules/propale/pdf_propale_azur.modules.php
+++ b/htdocs/includes/modules/propale/pdf_propale_azur.modules.php
@@ -1,7 +1,7 @@
- * Copyright (C) 2005-2009 Regis Houssin
- * Copyright (C) 2008 Raphael Bertrand (Resultic)
+/* Copyright (C) 2004-2009 Laurent Destailleur
+ * Copyright (C) 2005-2010 Regis Houssin
+ * Copyright (C) 2008 Raphael Bertrand (Resultic)
*
* 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
@@ -250,40 +250,43 @@ class pdf_propale_azur extends ModelePDFPropales
$pdf->SetFont('Arial','', 9); // On repositionne la police par defaut
$nexY = $pdf->GetY();
-
- // TVA
- if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
+
+ if ($propale->lignes[$i]->product_type < 2)
{
- $pdf->SetXY ($this->posxtva, $curY);
- $pdf->MultiCell($this->posxup-$this->posxtva-1, 4, vatrate($propale->lignes[$i]->tva_tx,1,$propale->lignes[$i]->info_bits), 0, 'R');
- }
-
- // Prix unitaire HT avant remise
- $pdf->SetXY ($this->posxup, $curY);
- $pdf->MultiCell($this->posxqty-$this->posxup-1, 4, price($propale->lignes[$i]->subprice), 0, 'R', 0);
-
- // Quantity
- $pdf->SetXY ($this->posxqty, $curY);
- if ($propale->lignes[$i]->special_code != 3) $pdf->MultiCell($this->posxdiscount-$this->posxqty-1, 4, $propale->lignes[$i]->qty, 0, 'R');
-
- // Remise sur ligne
- $pdf->SetXY ($this->posxdiscount, $curY);
- if ($propale->lignes[$i]->remise_percent && $propale->lignes[$i]->special_code != 3)
- {
- $pdf->MultiCell($this->postotalht-$this->posxdiscount-1, 4, dol_print_reduction($propale->lignes[$i]->remise_percent,$outputlangs), 0, 'R');
- }
-
- // Total HT ligne
- $pdf->SetXY ($this->postotalht, $curY);
- if ($propale->lignes[$i]->special_code == 3)
- {
- // Ligne produit en option
- $pdf->MultiCell(26, 4, $outputlangs->transnoentities("Option"), 0, 'R', 0);
- }
- else
- {
- $total = price($propale->lignes[$i]->total_ht);
- $pdf->MultiCell(26, 4, $total, 0, 'R', 0);
+ // TVA
+ if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
+ {
+ $pdf->SetXY ($this->posxtva, $curY);
+ $pdf->MultiCell($this->posxup-$this->posxtva-1, 4, vatrate($propale->lignes[$i]->tva_tx,1,$propale->lignes[$i]->info_bits), 0, 'R');
+ }
+
+ // Prix unitaire HT avant remise
+ $pdf->SetXY ($this->posxup, $curY);
+ $pdf->MultiCell($this->posxqty-$this->posxup-1, 4, price($propale->lignes[$i]->subprice), 0, 'R', 0);
+
+ // Quantity
+ $pdf->SetXY ($this->posxqty, $curY);
+ if ($propale->lignes[$i]->special_code != 3) $pdf->MultiCell($this->posxdiscount-$this->posxqty-1, 4, $propale->lignes[$i]->qty, 0, 'R');
+
+ // Remise sur ligne
+ $pdf->SetXY ($this->posxdiscount, $curY);
+ if ($propale->lignes[$i]->remise_percent && $propale->lignes[$i]->special_code != 3)
+ {
+ $pdf->MultiCell($this->postotalht-$this->posxdiscount-1, 4, dol_print_reduction($propale->lignes[$i]->remise_percent,$outputlangs), 0, 'R');
+ }
+
+ // Total HT ligne
+ $pdf->SetXY ($this->postotalht, $curY);
+ if ($propale->lignes[$i]->special_code == 3)
+ {
+ // Ligne produit en option
+ $pdf->MultiCell(26, 4, $outputlangs->transnoentities("Option"), 0, 'R', 0);
+ }
+ else
+ {
+ $total = price($propale->lignes[$i]->total_ht);
+ $pdf->MultiCell(26, 4, $total, 0, 'R', 0);
+ }
}
// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva