From 37cec358cbea383a5300c6bda4b385774d700e6b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 2 Apr 2007 23:45:50 +0000 Subject: [PATCH] =?UTF-8?q?Gros=20pas=20en=20avant=20sur=20la=20gestion=20?= =?UTF-8?q?des=20avoir.=20Le=20cycle=20de=20vie=20d'une=20facture=20en=20e?= =?UTF-8?q?rreur=20peut=20etre=20boucl=E9e.=20Avoir=20cr=E9e=20puis=20pass?= =?UTF-8?q?=E9=20en=20remise=20et=20applicable=20sur=20la=20facture=20suiv?= =?UTF-8?q?ante.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/comm/propal.php | 32 ++- htdocs/comm/remx.php | 104 ++++++-- htdocs/compta/facture.php | 97 ++++++-- htdocs/discount.class.php | 52 +++- htdocs/facture.class.php | 226 +++++++----------- htdocs/html.form.class.php | 16 +- htdocs/langs/fr_FR/bills.lang | 2 +- htdocs/propal.class.php | 14 +- htdocs/societe.class.php | 5 +- mysql/migration/2.0.0-2.1.0.sql | 11 + .../tables/llx_societe_remise_except.key.sql | 5 +- mysql/tables/llx_societe_remise_except.sql | 10 +- 12 files changed, 358 insertions(+), 216 deletions(-) diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index a0d1032a255..45988e1a2d4 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -509,6 +509,10 @@ if ($_POST['action'] == "setabsolutediscount" && $user->rights->propale->creer) if ($ret > 0) { $propal->insert_discount($_POST["remise_id"]); + if ($result < 0) + { + $mesg='
'.$propal->error.'
'; + } } else { @@ -1136,7 +1140,18 @@ if ($_GET['propalid'] > 0) print ''; print img_object($langs->trans("ShowReduc"),'reduc').' '.$langs->trans("Discount"); print ''; - if ($objp->description) print ' - '.nl2br($objp->description); + if ($objp->description) + { + if ($objp->description == '(CREDIT_NOTE)') + { + print ' - '.$langs->trans("CreditNote"); + // \TODO Mettre ici lien sur ref avoir + } + else + { + print ' - '.nl2br($objp->description); + } + } } else { @@ -1178,9 +1193,18 @@ if ($_GET['propalid'] > 0) // Icone d'edition et suppression if ($propal->statut == 0 && $user->rights->propale->creer) { - print 'rowid.'#'.$objp->rowid.'">'; - print img_edit(); - print ''; + print ''; + if (($objp->info_bits & 2) == 2) + { + // Ligne remise prédéfinie, on permet pas modif + } + else + { + print 'rowid.'#'.$objp->rowid.'">'; + print img_edit(); + print ''; + } + print ''; if ($conf->global->PRODUIT_CONFIRM_DELETE_LINE) { print 'rowid.'">'; diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index c4e3b50f585..32fd5f48f05 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2006 Laurent Destailleur + * Copyright (C) 2004-2007 Laurent Destailleur * * 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 @@ -22,13 +22,14 @@ /** \file htdocs/comm/remx.php - \ingroup commercial + \ingroup commercial, invoice \brief Onglet de définition des avoirs \version $Revision$ */ require_once("./pre.inc.php"); require_once(DOL_DOCUMENT_ROOT."/lib/company.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/facture.class.php"); $user->getrights('propale'); $user->getrights('commande'); @@ -52,7 +53,7 @@ if ($user->societe_id > 0) if ($_POST["action"] == 'setremise') { - if (! price2num($_POST["remise"]) > 0) + if (! price2num($_POST["amount_ht"]) > 0) { $mesg='
'.$langs->trans("ErrorFieldFormat",$langs->trans("NewGlobalDiscount")).'
'; } @@ -64,7 +65,7 @@ if ($_POST["action"] == 'setremise') { $soc = New Societe($db); $soc->fetch($_GET["id"]); - $soc->set_remise_except($_POST["remise"],$user,$_POST["desc"]); + $soc->set_remise_except($_POST["amount_ht"],$user,$_POST["desc"],$_POST["tva_tx"]); if ($result > 0) { @@ -97,9 +98,12 @@ if ($_GET["action"] == 'remove') /* - * Fiche des remises fixes + * Affichage fiche des remises fixes */ +$form=new Form($db); +$facturestatic=new Facture($db); + llxHeader(); if ($_socid > 0) @@ -158,7 +162,11 @@ if ($_socid > 0) print ''; print ''; - print ''; + print ''; + print ''; + print ''; print ''; print ''; @@ -175,10 +183,14 @@ if ($_socid > 0) /* * Liste remises fixes restant en cours */ - $sql = "SELECT rc.rowid, rc.amount_ht,".$db->pdate("rc.datec")." as dc, rc.description,"; - $sql.= " u.login, u.rowid as user_id"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc, ".MAIN_DB_PREFIX."user as u"; - $sql.= " WHERE rc.fk_soc =". $objsoc->id; + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql.= $db->pdate("rc.datec")." as dc, rc.description,"; + $sql.= " rc.fk_facture_source,"; + $sql.= " u.login, u.rowid as user_id,"; + $sql.= " fa.facnumber as ref, fa.type as type"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u, ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as fa ON rc.fk_facture_source = fa.rowid"; + $sql.= " WHERE rc.fk_soc =". $objsoc->id; $sql.= " AND u.rowid = rc.fk_user AND rc.fk_facture IS NULL"; $sql.= " ORDER BY rc.datec DESC"; @@ -187,9 +199,11 @@ if ($_socid > 0) { print_titre($langs->trans("DiscountStillRemaining")); print '
'.$langs->trans("NewGlobalDiscount").' '.$langs->trans("Currency".$conf->monnaie).'
 '.$langs->trans("Currency".$conf->monnaie).'
'.$langs->trans("VAT").''; + $form->select_tva('tva_tx','0','',$mysoc,''); + print '
'.$langs->trans("NoteReason").'
'; - print ''; + print ''; print ''; - print ''; + print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -202,10 +216,26 @@ if ($_socid > 0) $obj = $db->fetch_object($resql); $var = !$var; print ""; - print ''; - print ''; + print ''; + print ''; print ''; - print ''; + print ''; + print ''; + print ''; if ($obj->user_id == $user->id) print ''; else print ''; print ''; @@ -224,13 +254,17 @@ if ($_socid > 0) /* * Liste ristournes appliquées */ - $sql = "SELECT rc.rowid, rc.amount_ht,".$db->pdate("rc.datec")." as dc, rc.description, rc.fk_facture,"; - $sql.= " u.login, u.rowid as user_id,"; - $sql.= " f.rowid, f.facnumber"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql.= $db->pdate("rc.datec")." as dc, rc.description, rc.fk_facture,"; + $sql.= " rc.fk_facture_source,"; + $sql.= " u.login, u.rowid as user_id,"; + $sql.= " f.rowid, f.facnumber,"; + $sql.= " fa.facnumber as ref, fa.type as type"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql.= " , ".MAIN_DB_PREFIX."user as u"; $sql.= " , ".MAIN_DB_PREFIX."facturedet as fc"; - $sql.= " , ".MAIN_DB_PREFIX."facture as f"; + $sql.= " , ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as fa ON rc.fk_facture_source = fa.rowid"; $sql.= " WHERE rc.fk_soc =". $objsoc->id; $sql.= " AND rc.fk_facture = fc.rowid"; $sql.= " AND fc.fk_facture = f.rowid"; @@ -242,10 +276,12 @@ if ($_socid > 0) { print_titre($langs->trans("DiscountAlreadyCounted")); print '
'.$langs->trans("Date").'
'.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("Amount").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").''.$langs->trans("AmountTTC").''.$langs->trans("DiscountOfferedBy").' 
'.dolibarr_print_date($obj->dc).''.$obj->description.''.dolibarr_print_date($obj->dc,'dayhour').''; + if ($obj->description == '(CREDIT_NOTE)') + { + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print $langs->trans("CreditNote").' '.$facturestatic->getNomURl(1); + } + else + { + print $obj->description; + } + print ''.price($obj->amount_ht).''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''.price($obj->tva_tx).'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login; + print 'rowid.'">'.img_delete($langs->trans("RemoveDiscount")).' 
'; - print ''; - print ''; + print ''; print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -258,11 +294,27 @@ if ($_socid > 0) $obj = $db->fetch_object($resql); $var = !$var; print ""; - print ''; + print ''; + print ''; print ''; - print ''; print ''; - print ''; + print ''; + print ''; + print ''; print ''; print ''; $i++; diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index f6d05865aab..2393884c04d 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -321,17 +321,64 @@ if ($_POST['action'] == 'confirm_converttoreduc' && $_POST['confirm'] == 'yes' & $fac = new Facture($db); $fac->fetch($_GET['facid']); $fac->fetch_client(); + $fac->fetch_lines(); - $result=$fac->set_payed($user); - - // TODO A completer - $discount = new DiscountAbsolute($db); - $result=$discount->create($user); + if (! $fac->paye) // protection against multiple submit + { + // Boucle sur chaque taux de tva + $i=0; + foreach($fac->lignes as $ligne) + { + $amount_ht[$ligne->tva_tx]+=$ligne->total_ht; + $amount_tva[$ligne->tva_tx]+=$ligne->total_tva; + $amount_ttc[$ligne->tva_tx]+=$ligne->total_ttc; + $i++; + } + + // Insère une remise par famille de taux tva + $discount = new DiscountAbsolute($db); + $discount->desc='(CREDIT_NOTE)'; + $discount->tva_tx=abs($fac->total_ttc); + $discount->fk_soc=$fac->socid; + $discount->fk_facture_source=$fac->id; - $langs->load("other"); - $mesg=$langs->trans("FeatureNotYetAvailable"); - - $db->rollback(); + $error=0; + foreach($amount_ht as $tva_tx => $xxx) + { + $discount->amount_ht=abs($amount_ht[$tva_tx]); + $discount->amount_tva=abs($amount_tva[$tva_tx]); + $discount->amount_ttc=abs($amount_ttc[$tva_tx]); + $discount->tva_tx=abs($tva_tx); + + $result=$discount->create($user); + if ($result < 0) + { + $error++; + break; + } + } + + if (! $error) + { + // Classe facture + $result=$fac->set_payed($user); + if ($result > 0) + { + //$mesg='OK'.$discount->id; + $db->commit(); + } + else + { + $mesg='
'.$fac->error.'
'; + $db->rollback(); + } + } + else + { + $mesg='
'.$discount->error.'
'; + $db->rollback(); + } + } } @@ -2147,8 +2194,8 @@ else /* - * Lignes de factures - */ + * Lignes de factures + */ $sql = 'SELECT l.fk_product, l.description, l.price, l.qty, l.rowid, l.tva_taux,'; $sql.= ' l.remise_percent, l.subprice, l.info_bits,'; $sql.= ' '.$db->pdate('l.date_start').' as date_start,'; @@ -2223,7 +2270,18 @@ else print ''; print img_object($langs->trans("ShowReduc"),'reduc').' '.$langs->trans("Discount"); print ''; - if ($objp->description) print ' - '.nl2br($objp->description); + if ($objp->description) + { + if ($objp->description == '(CREDIT_NOTE)') + { + print ' - '.$langs->trans("CreditNote"); + // \TODO Mettre ici lien sur ref avoir + } + else + { + print ' - '.nl2br($objp->description); + } + } } else { @@ -2254,9 +2312,18 @@ else // Icone d'edition et suppression if ($fac->statut == 0 && $user->rights->facture->creer) { - print ''; + print ''; if ($conf->global->PRODUIT_CONFIRM_DELETE_LINE) { print '
'.$langs->trans("Date").''.$langs->trans("Bill").'
'.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("Amount").''.$langs->trans("Invoice").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").''.$langs->trans("AmountTTC").''.$langs->trans("Author").' 
'.dolibarr_print_date($obj->dc).''.dolibarr_print_date($obj->dc,'dayhour').''; + if ($obj->description == '(CREDIT_NOTE)') + { + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print $langs->trans("CreditNote").' '.$facturestatic->getNomURl(1); + } + else + { + print $obj->description; + } + print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''.$obj->description.''.price($obj->amount_ht).''.$obj->login.''.price($obj->tva_tx).'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login; + print ' 
rowid.'#'.$objp->rowid.'">'; - print img_edit(); - print ''; + if (($objp->info_bits & 2) == 2) + { + // Ligne remise prédéfinie, on permet pas modif + } + else + { + print 'rowid.'#'.$objp->rowid.'">'; + print img_edit(); + print ''; + } + print 'rowid.'">'; diff --git a/htdocs/discount.class.php b/htdocs/discount.class.php index 174820ecd53..4b8a429bdd9 100644 --- a/htdocs/discount.class.php +++ b/htdocs/discount.class.php @@ -35,10 +35,21 @@ class DiscountAbsolute { - var $id; var $db; + var $error; + + var $id; // Id remise + var $amount_ht; // + var $amount_tva; // + var $amount_ttc; // + var $tva_tx; // + var $fk_user; // Id utilisateur qui accorde la remise + var $description; // Description libre + var $datec; // Date creation + var $fk_facture; // Id facture qd une remise a été utilisé + var $fk_facture_source; // Id facture avoir a l'origine de la remise - + /** * \brief Constructeur de la classe * \param DB handler accès base de données @@ -56,7 +67,10 @@ class DiscountAbsolute */ function fetch($rowid) { - $sql = "SELECT fk_soc, amount_ht, fk_user, fk_facture, description,"; + $sql = "SELECT fk_soc,"; + $sql.= " fk_user,"; + $sql.= " amount_ht, amount_tva, amount_ttc, tva_tx,"; + $sql.= " fk_facture, fk_facture_source, description,"; $sql.= " ".$this->db->pdate("datec")." as datec"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except"; $sql.= " WHERE rowid=".$rowid; @@ -72,8 +86,12 @@ class DiscountAbsolute $this->id = $rowid; $this->fk_soc = $obj->fk_soc; $this->amount_ht = $obj->amount_ht; + $this->amount_tva = $obj->amount_tva; + $this->amount_ttc = $obj->amount_ttc; + $this->tva_tx = $obj->tva_tx; $this->fk_user = $obj->fk_user; $this->fk_facture = $obj->fk_facture; + $this->fk_facture_source = $obj->fk_facture_source; $this->description = $obj->description; $this->datec = $obj->datec; @@ -92,7 +110,7 @@ class DiscountAbsolute return -1; } } - + /** * \brief Create in database @@ -103,22 +121,34 @@ class DiscountAbsolute { global $conf, $langs; + // Nettoyage parametres + $this->amount_ht=price2num($this->amount_ht); + $this->amount_tva=price2num($this->amount_tva); + $this->amount_ttc=price2num($this->amount_ttc); + $this->tva_tx=price2num($this->tva_tx); + // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_except "; - $sql .= " (datec, fk_soc, amount_ht, fk_user, description)"; - $sql .= " VALUES (now(),".$this->fk_soc.",'".$this->amount_ht."',".$user->id.",'".addslashes($this->desc)."')"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_except"; + $sql.= " (datec, fk_soc, fk_user, description,"; + $sql.= " amount_ht, amount_tva, amount_ttc, tva_tx,"; + $sql.= " fk_facture_source"; + $sql.= ")"; + $sql.= " VALUES (now(),".$this->fk_soc.",".$user->id.",'".addslashes($this->desc)."',"; + $sql.= " '".$this->amount_ht."','".$this->amount_tva."','".$this->amount_ttc."','".$this->tva_tx."',"; + $sql.= " ".($this->fk_facture_source?"'".$this->fk_facture_source."'":"null"); + $sql.= ")"; dolibarr_syslog("DiscountAbsolute::create sql=".$sql); $resql=$this->db->query($sql); if ($resql) { - $rowid=$this->db->last_insert_id(MAIN_DB_PREFIX."societe_remise_except"); - return $rowid; + $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX."societe_remise_except"); + return $this->id; } else { - $this->error=$this->db->lasterror(); - dolibarr_syslog("Skeleton_class::create ".$this->error); + $this->error=$this->db->lasterror().' - sql='.$sql; + dolibarr_syslog("DiscountAbsolute::create ".$this->error); return -1; } } diff --git a/htdocs/facture.class.php b/htdocs/facture.class.php index 6b1a80c77d5..1bdd77cfc69 100644 --- a/htdocs/facture.class.php +++ b/htdocs/facture.class.php @@ -570,90 +570,90 @@ class Facture extends CommonObject } } - /** - * \brief Ajout en base d'une ligne remise fixe en ligne de facture - * \param idremise Id de la remise fixe - * \return int >0 si ok, <0 si ko - */ - function insert_discount($idremise) - { - global $langs; + /** + * \brief Ajout en base d'une ligne remise fixe en ligne de facture + * \param idremise Id de la remise fixe + * \return int >0 si ok, <0 si ko + */ + function insert_discount($idremise) + { + global $langs; - include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); - include_once(DOL_DOCUMENT_ROOT.'/discount.class.php'); + include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); + include_once(DOL_DOCUMENT_ROOT.'/discount.class.php'); - $this->db->begin(); + $this->db->begin(); - $remise=new DiscountAbsolute($this->db); - $result=$remise->fetch($idremise); - if ($result > 0) - { - if ($remise->fk_facture) - { - $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); - $this->db->rollback(); - return -5; - } + $remise=new DiscountAbsolute($this->db); + $result=$remise->fetch($idremise); + + if ($result > 0) + { + if ($remise->fk_facture) // Protection against multiple submission + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); + $this->db->rollback(); + return -5; + } - $facligne=new FactureLigne($this->db); - $facligne->fk_facture=$this->id; - $facligne->fk_remise_except=$remise->id; - $facligne->desc=$remise->description; // Description ligne - $facligne->tva_tx=$remise->tva_tx; - $facligne->subprice=-$remise->amount_ht; - $facligne->fk_product=0; // Id produit prédéfini - $facligne->qty=1; - $facligne->remise_percent=0; - $facligne->rang=-1; - $facligne->info_bits=2; + $facligne=new FactureLigne($this->db); + $facligne->fk_facture=$this->id; + $facligne->fk_remise_except=$remise->id; + $facligne->desc=$remise->description; // Description ligne + $facligne->tva_tx=$remise->tva_tx; + $facligne->subprice=-$remise->amount_ht; + $facligne->fk_product=0; // Id produit prédéfini + $facligne->qty=1; + $facligne->remise_percent=0; + $facligne->rang=-1; + $facligne->info_bits=2; - // Ne plus utiliser - $facligne->price=-$remise->amount_ht; - $facligne->remise=0; + // Ne plus utiliser + $facligne->price=-$remise->amount_ht; + $facligne->remise=0; - $tabprice=calcul_price_total($facligne->qty, $facligne->subprice, 0,$facligne->tva_tx); - $facligne->total_ht = $tabprice[0]; - $facligne->total_tva = $tabprice[1]; - $facligne->total_ttc = $tabprice[2]; + $facligne->total_ht = $remise->amount_ht; + $facligne->total_tva = $remise->amount_tva; + $facligne->total_ttc = $remise->amount_ttc; - $lineid=$facligne->insert(); - if ($lineid > 0) - { - $result=$this->update_price($this->id); - if ($result > 0) - { - // Crée lien entre remise et ligne de facture - $result=$remise->link_to_invoice($lineid); - if ($result < 0) - { - $this->error=$remise->error; - $this->db->rollback(); - return -4; - } + $lineid=$facligne->insert(); + if ($lineid > 0) + { + $result=$this->update_price($this->id); + if ($result > 0) + { + // Crée lien entre remise et ligne de facture + $result=$remise->link_to_invoice($lineid); + if ($result < 0) + { + $this->error=$remise->error; + $this->db->rollback(); + return -4; + } - $this->db->commit(); - return 1; - } - else - { - $this->error=$facligne->error; - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$facligne->error; - $this->db->rollback(); - return -2; - } - } - else - { - $this->db->rollback(); - return -3; - } - } + $this->db->commit(); + return 1; + } + else + { + $this->error=$facligne->error; + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$facligne->error; + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + return -3; + } + } /** @@ -1106,68 +1106,6 @@ class Facture extends CommonObject } } - - /* - * Tope les lignes de remises fixes avec id des lignes de facture de remise - */ - // Plus necessaire car deja topé des état brouillon - /* - foreach($this->lignes as $i => $line) - { - if (($this->lignes[$i]->info_bits & 2) == 2 && $this->lignes[$i]->fk_remise_except) - { - // Ligne de remise - dolibarr_syslog("Facture.class::set_valid: recherche si remise ".$this->lignes[$i]->fk_remise_except." toujours dispo"); - - // On recherche si ligne de remise pas deja attribuée - $sql = 'SELECT fk_facture'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' WHERE fk_facture IS NULL AND rowid ='.$this->lignes[$i]->fk_remise_except; - $sql.= ' FOR UPDATE'; - $resql=$this->db->query($sql); - if ($resql) - { - $num=$this->db->num_rows($resql); - if ($num >= 1) - { - dolibarr_syslog("Facture.class::set_valid: top ligne de remise ".$this->lignes[$i]->fk_remise_except." pour ligne de facture ".$this->lignes[$i]->rowid); - - // On met à jour ligne de remise comme utilisée - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' SET fk_facture = '.$this->lignes[$i]->rowid; - $sql.= ' WHERE fk_facture IS NULL AND rowid ='.$this->lignes[$i]->fk_remise_except; - $resql=$this->db->query($sql); - if ($resql) - { - - } - else - { - $this->error=$this->db->error().' sql='.$sql; - dolibarr_syslog("Facture.class::set_valid: Error ".$this->error); - $error++; - break; - } - } - else - { - $error++; - $this->error=$langs->trans("InvoiceDiscountNotAvailable"); - dolibarr_syslog("Facture.class::set_valid: Error ".$this->error); - break; - } - } - else - { - $this->error=$this->db->error().' sql='.$sql; - dolibarr_syslog("Facture.class::set_valid: Error ".$this->error); - $error++; - break; - } - } - } - */ - // On vérifie si la facture était une provisoire if (! $error && $facref == 'PROV') { @@ -1388,7 +1326,7 @@ class Facture extends CommonObject $ligne->fk_facture=$facid; $ligne->desc=$desc; $ligne->qty=$qty; - $ligne->txtva=$txtva; + $ligne->tva_tx=$txtva; $ligne->fk_product=$fk_product; $ligne->remise_percent=$remise_percent; $ligne->subprice=$pu; @@ -2311,8 +2249,8 @@ class Facture extends CommonObject /** - * \brief Renvoi liste des factures qualifiables pour avoir - * Statut >= validée + classée payée completement ou classée payée partiellement + pas deja remplacée + * \brief Renvoi liste des factures qualifiables pour correction par avoir + * Statut >= validée + classée payée completement ou classée payée partiellement + pas deja remplacée + pas deja avoir * \param socid Id societe * \return array Tableau des factures ($id => $ref) */ @@ -2330,7 +2268,8 @@ class Facture extends CommonObject $sql.= " AND (f.paye = 1"; // Classée payée complètement $sql.= " OR f.close_code IS NOT NULL)"; // Classée payée partiellement $sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement - if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; + $sql.= " AND f.type != 2"; // Facture non avoir + if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; $sql.= " ORDER BY f.facnumber"; dolibarr_syslog("Facture.class::list_qualified_avoir_invoices sql=$sql"); @@ -2848,7 +2787,7 @@ class FactureLigne $sql.= " VALUES (".$this->fk_facture.","; $sql.= " '".addslashes($this->desc)."',"; $sql.= " '".price2num($this->qty)."',"; - $sql.= " '".price2num($this->txtva)."',"; + $sql.= " '".price2num($this->tva_tx)."',"; if ($this->fk_product) { $sql.= "'".$this->fk_product."',"; } else { $sql.='null,'; } $sql.= " '".price2num($this->remise_percent)."',"; @@ -2870,6 +2809,7 @@ class FactureLigne $sql.= " '".price2num($this->total_ttc)."'"; $sql.= ')'; + dolibarr_syslog("FactureLigne::insert sql=".$sql); $resql=$this->db->query($sql); if ($resql) { diff --git a/htdocs/html.form.class.php b/htdocs/html.form.class.php index 31b063e2b35..d9e297e579d 100644 --- a/htdocs/html.form.class.php +++ b/htdocs/html.form.class.php @@ -555,10 +555,11 @@ class Form global $langs,$conf; // On recherche les societes - $sql = "SELECT re.rowid, re.amount_ht as amount, re.description FROM"; - $sql.= " ".MAIN_DB_PREFIX ."societe_remise_except as re"; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql.= " re.description"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; $sql.= " WHERE fk_soc = ".$socid; - if ($filter) $sql.= " AND $filter"; + if ($filter) $sql.= " AND ".$filter; $sql.= " ORDER BY re.description ASC"; $resql=$this->db->query($sql); @@ -573,13 +574,16 @@ class Form while ($i < $num) { $obj = $this->db->fetch_object($resql); - if ($selected > 0 && $selected == $obj->rowid) + $desc=dolibarr_trunc($obj->description,40); + if ($desc=='(CREDIT_NOTE)') $desc=$langs->trans("CreditNote"); + + if ($selected > 0 && $selected == $obj->rowid) { - print ''; + print ''; } else { - print ''; + print ''; } $i++; } diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang index 2d74ccdcbfa..9ed4608d9db 100644 --- a/htdocs/langs/fr_FR/bills.lang +++ b/htdocs/langs/fr_FR/bills.lang @@ -16,7 +16,7 @@ InvoiceReplacementAsk=Facture de remplacement de la facture InvoiceReplacementDesc=La facture de remplacement sert à annuler et remplacer une facture existante sur laquelle aucun paiement n'a encore eu lieu.

Rem: Seule une facture sans aucun paiement peut être remplacée. Si cette dernière n'est pas fermée, elle le sera automatiquement au statut 'abandonnée'. InvoiceAvoir=Facture avoir InvoiceAvoirAsk=Facture avoir pour correction de la facture -InvoiceAvoirDesc=La facture d'avoir est une facture négative destinée à compenser un montant de facture qui diffère du montant réellement versé (suite à une trop versé par le client par erreur ou un manque non versé par le client suite à une retour produit par exemple).

Rem: Notons que la facture originale à corriger doit avoir fermé ('payée' ou 'payée partiellement') pour pouvoir faire l'avoir. +InvoiceAvoirDesc=La facture d'avoir est une facture négative destinée à compenser un montant de facture qui diffère du montant réellement versé (suite à une trop versé par le client par erreur ou un manque non versé par le client suite à une retour produit par exemple).

Rem: Notons que la facture originale à corriger doit avoir été fermée ('payée' ou 'payée partiellement') pour pouvoir faire l'avoir. ReplaceInvoice=Remplace la facture %s ReplacementInvoice=Remplacement facture ReplacedByInvoice=Remplacée par la facture %s diff --git a/htdocs/propal.class.php b/htdocs/propal.class.php index b4aaa0d0c1c..ca2e9e9c817 100644 --- a/htdocs/propal.class.php +++ b/htdocs/propal.class.php @@ -198,6 +198,13 @@ class Propal extends CommonObject if ($result > 0) { + if ($remise->fk_facture) // Protection against multiple submission + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); + $this->db->rollback(); + return -5; + } + $propalligne=new PropaleLigne($this->db); $propalligne->fk_propal=$this->id; $propalligne->fk_remise_except=$remise->id; @@ -212,10 +219,9 @@ class Propal extends CommonObject $propalligne->rang=-1; $propalligne->info_bits=2; - $tabprice=calcul_price_total($propalligne->qty, $propalligne->subprice, 0,$propalligne->tva_tx); - $propalligne->total_ht = $tabprice[0]; - $propalligne->total_tva = $tabprice[1]; - $propalligne->total_ttc = $tabprice[2]; + $propalligne->total_ht = $remise->amount_ht; + $propalligne->total_tva = $remise->amount_tva; + $propalligne->total_ttc = $remise->amount_ttc; $result=$propalligne->insert(); if ($result > 0) diff --git a/htdocs/societe.class.php b/htdocs/societe.class.php index bd4f69eb155..b3618024153 100644 --- a/htdocs/societe.class.php +++ b/htdocs/societe.class.php @@ -942,7 +942,7 @@ class Societe * \param desc Motif de l'avoir * \return int <0 si ko, id de la ligne de remise si ok */ - function set_remise_except($remise, $user, $desc) + function set_remise_except($remise, $user, $desc, $tva_tx=0) { global $langs; @@ -966,6 +966,9 @@ class Societe $discount = new DiscountAbsolute($this->db); $discount->fk_soc=$this->id; $discount->amount_ht=$remise; + $discount->amount_tva=($remise*$tva_tx/100); + $discount->amount_ttc=$discount->amount_ht+$discount->amount_tva; + $discount->tva_tx=$tva_tx; $discount->desc=$desc; $result=$discount->create($user); if ($result > 0) diff --git a/mysql/migration/2.0.0-2.1.0.sql b/mysql/migration/2.0.0-2.1.0.sql index eed942072f8..c7d7b494d9a 100644 --- a/mysql/migration/2.0.0-2.1.0.sql +++ b/mysql/migration/2.0.0-2.1.0.sql @@ -689,17 +689,28 @@ create table llx_societe_remise_except description varchar(255) NOT NULL )type=innodb; +alter table llx_societe_remise_except ADD COLUMN amount_tva real DEFAULT 0 NOT NULL after amount_ht; +alter table llx_societe_remise_except ADD COLUMN amount_ttc real DEFAULT 0 NOT NULL after amount_tva; +alter table llx_societe_remise_except ADD COLUMN tva_tx real DEFAULT 0 NOT NULL after amount_ttc; +alter table llx_societe_remise_except ADD COLUMN fk_facture_source integer after fk_user; + +update llx_societe_remise_except set amount_tva=0, tva_tx=0, amount_ttc = amount_ht where amount_ttc = 0; +delete from llx_societe_remise_except WHERE amount_ht=0; + -- Supprimme orphelins pour permettre montée de la clé -- V4 DELETE llx_societe_remise_except FROM llx_societe_remise_except LEFT JOIN llx_facturedet ON llx_societe_remise_except.fk_facture = llx_facturedet.rowid WHERE llx_facturedet.rowid IS NULL; ALTER TABLE llx_societe_remise_except DROP FOREIGN KEY fk_societe_remise_fk_facture; +ALTER TABLE llx_societe_remise_except DROP FOREIGN KEY fk_societe_remise_fk_facture_source; ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_user (fk_user); ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_soc (fk_soc); ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture (fk_facture); +ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_source (fk_facture_source); ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid); ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_facture FOREIGN KEY (fk_facture) REFERENCES llx_facturedet (rowid); +ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_facture_source FOREIGN KEY (fk_facture_source) REFERENCES llx_facture (rowid); update llx_societe_remise_except set description='Remise sans description' where description is NULL or description =''; alter table llx_societe_remise_except modify description varchar(255) NOT NULL; diff --git a/mysql/tables/llx_societe_remise_except.key.sql b/mysql/tables/llx_societe_remise_except.key.sql index 840b00352e5..af5a311d8fe 100644 --- a/mysql/tables/llx_societe_remise_except.key.sql +++ b/mysql/tables/llx_societe_remise_except.key.sql @@ -1,6 +1,6 @@ -- ============================================================================ -- Copyright (C) 2004 Rodolphe Quiedeville --- Copyright (C) 2005 Laurent Destailleur +-- Copyright (C) 2005-2007 Laurent Destailleur -- -- 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 @@ -21,18 +21,19 @@ -- -- Remises exceptionnelles -- --- -- ============================================================================ ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_user (fk_user); ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_soc (fk_soc); ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture (fk_facture); +ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_source (fk_facture_source); ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid); ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_facture FOREIGN KEY (fk_facture) REFERENCES llx_facturedet (rowid); +ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_facture_source FOREIGN KEY (fk_facture_source) REFERENCES llx_facture (rowid); diff --git a/mysql/tables/llx_societe_remise_except.sql b/mysql/tables/llx_societe_remise_except.sql index 1b96ee431d5..dc823247d85 100644 --- a/mysql/tables/llx_societe_remise_except.sql +++ b/mysql/tables/llx_societe_remise_except.sql @@ -1,6 +1,6 @@ -- ============================================================================ --- Copyright (C) 2004 Rodolphe Quiedeville --- Copyright (C) 2006 Laurent Destailleur +-- Copyright (C) 2004 Rodolphe Quiedeville +-- Copyright (C) 2006-2007 Laurent Destailleur -- -- 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 @@ -28,7 +28,11 @@ create table llx_societe_remise_except fk_soc integer NOT NULL, -- client datec datetime, amount_ht real NOT NULL, + amount_tva real DEFAULT 0 NOT NULL, + amount_ttc real DEFAULT 0 NOT NULL, + tva_tx real DEFAULT 0 NOT NULL, fk_user integer NOT NULL, - fk_facture integer, + fk_facture integer, + fk_facture_source integer, description varchar(255) NOT NULL )type=innodb;