Fix: bug #27197 : Fix discount applied twice

This commit is contained in:
Laurent Destailleur 2009-08-22 03:09:52 +00:00
parent c7e3ffbadb
commit 76f25a038f
14 changed files with 304 additions and 121 deletions

View File

@ -74,7 +74,8 @@ print "<br>\n";
// Php // Php
print '<table class="noborder" width="100%">'; print '<table class="noborder" width="100%">';
print "<tr class=\"liste_titre\"><td colspan=\"2\">".$langs->trans("Php")."</td></tr>\n"; print "<tr class=\"liste_titre\"><td colspan=\"2\">".$langs->trans("Php")."</td></tr>\n";
print "<tr $bc[0]><td width=\"280\">".$langs->trans("Version")."</td><td>".version_php()."</td></tr>\n"; $phpversion=version_php();
print "<tr $bc[0]><td width=\"280\">".$langs->trans("Version")."</td><td>".$phpversion."</td></tr>\n";
print "<tr $bc[1]><td>".$langs->trans("PhpWebLink")."</td><td>".php_sapi_name()."</td></tr>\n"; print "<tr $bc[1]><td>".$langs->trans("PhpWebLink")."</td><td>".php_sapi_name()."</td></tr>\n";
print '</table>'; print '</table>';
@ -83,7 +84,8 @@ print "<br>\n";
// Database // Database
print '<table class="noborder" width="100%">'; print '<table class="noborder" width="100%">';
print "<tr class=\"liste_titre\"><td colspan=\"2\">".$langs->trans("Database")."</td></tr>\n"; print "<tr class=\"liste_titre\"><td colspan=\"2\">".$langs->trans("Database")."</td></tr>\n";
print "<tr $bc[0]><td width=\"280\">".$langs->trans("Version")."</td><td>" . $db->getVersion() . "</td></tr>\n"; $dbversion=$db->getVersion();
print "<tr $bc[0]><td width=\"280\">".$langs->trans("Version")."</td><td>" .$dbversion. "</td></tr>\n";
print '</table>'; print '</table>';
print '<br>'; print '<br>';

View File

@ -294,7 +294,7 @@ if ($_socid > 0)
print_titre($langs->trans("DiscountStillRemaining")); print_titre($langs->trans("DiscountStillRemaining"));
print '<table width="100%" class="noborder">'; print '<table width="100%" class="noborder">';
print '<tr class="liste_titre">'; print '<tr class="liste_titre">';
print '<td width="110" align="left">'.$langs->trans("Date").'</td>'; print '<td width="120" align="left">'.$langs->trans("Date").'</td>'; // Need 120+ for format with AM/PM
print '<td width="150" align="left">'.$langs->trans("ReasonDiscount").'</td>'; print '<td width="150" align="left">'.$langs->trans("ReasonDiscount").'</td>';
print '<td align="left" nowrap="nowrap">'.$langs->trans("ConsumedBy").'</td>'; print '<td align="left" nowrap="nowrap">'.$langs->trans("ConsumedBy").'</td>';
print '<td width="120" align="right">'.$langs->trans("AmountHT").'</td>'; print '<td width="120" align="right">'.$langs->trans("AmountHT").'</td>';
@ -430,7 +430,7 @@ if ($_socid > 0)
print_titre($langs->trans("DiscountAlreadyCounted")); print_titre($langs->trans("DiscountAlreadyCounted"));
print '<table class="noborder" width="100%">'; print '<table class="noborder" width="100%">';
print '<tr class="liste_titre">'; print '<tr class="liste_titre">';
print '<td width="110" align="left">'.$langs->trans("Date").'</td>'; print '<td width="120" align="left">'.$langs->trans("Date").'</td>'; // Need 120+ for format with AM/PM
print '<td width="150" align="left">'.$langs->trans("ReasonDiscount").'</td>'; print '<td width="150" align="left">'.$langs->trans("ReasonDiscount").'</td>';
print '<td align="left" nowrap="nowrap">'.$langs->trans("ConsumedBy").'</td>'; print '<td align="left" nowrap="nowrap">'.$langs->trans("ConsumedBy").'</td>';
print '<td width="120" align="right">'.$langs->trans("AmountHT").'</td>'; print '<td width="120" align="right">'.$langs->trans("AmountHT").'</td>';

View File

@ -77,12 +77,12 @@ class Facture extends CommonObject
//! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null), //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null),
//! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' ou 'replaced') //! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' ou 'replaced')
var $statut; var $statut;
//! 1 si facture payée COMPLETEMENT, 0 sinon (ce champ ne devrait plus servir car insuffisant) //! 1 if invoice paid COMPLETELY, 0 otherwise (ce champ ne devrait plus servir car insuffisant)
var $paye; var $paye;
//! id of source invoice if replacement invoice or credit note //! id of source invoice if replacement invoice or credit note
var $fk_facture_source; var $fk_facture_source;
//! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon
//! Fermeture alors que aucun paiement: replaced (si remplacé), abandon //! Fermeture alors que aucun paiement: replaced (si remplac<EFBFBD>), abandon
var $close_code; var $close_code;
//! Commentaire si mis a paye sans paiement complet //! Commentaire si mis a paye sans paiement complet
var $close_note; var $close_note;
@ -100,12 +100,12 @@ class Facture extends CommonObject
var $nbtodo; var $nbtodo;
var $nbtodolate; var $nbtodolate;
var $specimen; var $specimen;
//! Numero d'erreur de 512 à 1023 //! Numero d'erreur de 512 <EFBFBD> 1023
var $errno = 0; var $errno = 0;
/** /**
\brief Constructeur de la classe \brief Constructeur de la classe
\param DB handler accès base de données \param DB handler acc<EFBFBD>s base de donn<EFBFBD>es
\param socid id societe ('' par defaut) \param socid id societe ('' par defaut)
\param facid id facture ('' par defaut) \param facid id facture ('' par defaut)
*/ */
@ -260,7 +260,7 @@ class Facture extends CommonObject
* Insert lines of invoices in database * Insert lines of invoices in database
*/ */
//dol_syslog("There is ".sizeof($this->lignes)." lines"); //dol_syslog("There is ".sizeof($this->lignes)." lines");
for ($i = 0 ; $i < sizeof($this->lignes) ; $i++) foreach ($this->lignes as $i => $val)
{ {
$newinvoiceline=new FactureLigne($this->db); $newinvoiceline=new FactureLigne($this->db);
$newinvoiceline=$this->lignes[$i]; $newinvoiceline=$this->lignes[$i];
@ -281,7 +281,7 @@ class Facture extends CommonObject
*/ */
if (! $error && $this->fac_rec > 0) if (! $error && $this->fac_rec > 0)
{ {
for ($i = 0 ; $i < sizeof($_facrec->lignes) ; $i++) foreach ($_facrec->lignes as $i => $val)
{ {
if ($_facrec->lignes[$i]->produit_id) if ($_facrec->lignes[$i]->produit_id)
{ {
@ -376,11 +376,12 @@ class Facture extends CommonObject
$facture->remise_percent = $this->remise_percent; $facture->remise_percent = $this->remise_percent;
$facture->lignes = $this->lignes; // Tableau des lignes de factures $facture->lignes = $this->lignes; // Tableau des lignes de factures
$facture->products = $this->lignes; // Tant que products encore utilisé $facture->products = $this->lignes; // Tant que products encore utilise
if ($invertdetail) // Loop on each line of new invoice
{
foreach($facture->lignes as $i => $line) foreach($facture->lignes as $i => $line)
{
if ($invertdetail)
{ {
$facture->lignes[$i]->subprice = -$facture->lignes[$i]->subprice; $facture->lignes[$i]->subprice = -$facture->lignes[$i]->subprice;
$facture->lignes[$i]->price = -$facture->lignes[$i]->price; $facture->lignes[$i]->price = -$facture->lignes[$i]->price;
@ -428,7 +429,17 @@ class Facture extends CommonObject
$object->ref_client = ''; $object->ref_client = '';
$object->close_code = ''; $object->close_code = '';
$object->close_note = ''; $object->close_note = '';
$object->products = $object->lignes; // Tant que products encore utilisé $object->products = $object->lignes; // Tant que products encore utilise
// Loop on each line of new invoice
foreach($object->lignes as $i => $line)
{
if (($object->lignes[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts
{
unset($object->lignes[$i]);
unset($object->products[$i]); // Tant que products encore utilise
}
}
// Create clone // Create clone
$result=$object->create($user); $result=$object->create($user);
@ -849,7 +860,7 @@ class Facture extends CommonObject
$facligne->desc=$remise->description; // Description ligne $facligne->desc=$remise->description; // Description ligne
$facligne->tva_tx=$remise->tva_tx; $facligne->tva_tx=$remise->tva_tx;
$facligne->subprice=-$remise->amount_ht; $facligne->subprice=-$remise->amount_ht;
$facligne->fk_product=0; // Id produit prédéfini $facligne->fk_product=0; // Id produit pr<EFBFBD>d<EFBFBD>fini
$facligne->qty=1; $facligne->qty=1;
$facligne->remise_percent=0; $facligne->remise_percent=0;
$facligne->rang=-1; $facligne->rang=-1;
@ -869,7 +880,7 @@ class Facture extends CommonObject
$result=$this->update_price(); $result=$this->update_price();
if ($result > 0) if ($result > 0)
{ {
// Crée lien entre remise et ligne de facture // Cr<EFBFBD>e lien entre remise et ligne de facture
$result=$remise->link_to_invoice($lineid,0); $result=$remise->link_to_invoice($lineid,0);
if ($result < 0) if ($result < 0)
{ {
@ -925,7 +936,7 @@ class Facture extends CommonObject
/** /**
* \brief Delete invoice * \brief Delete invoice
* \param rowid Id de la facture à supprimer * \param rowid Id de la facture <EFBFBD> supprimer
* \return int <0 si ko, >0 si ok * \return int <0 si ko, >0 si ok
*/ */
function delete($rowid=0) function delete($rowid=0)
@ -956,7 +967,7 @@ class Facture extends CommonObject
$list_rowid_det[]=$obj->rowid; $list_rowid_det[]=$obj->rowid;
} }
// On désaffecte de la facture les remises liées // On d<EFBFBD>saffecte de la facture les remises li<6C>es
if (sizeof($list_rowid_det)) if (sizeof($list_rowid_det))
{ {
$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
@ -1027,8 +1038,8 @@ class Facture extends CommonObject
/** /**
\brief Renvoi une date limite de reglement de facture en fonction des \brief Renvoi une date limite de reglement de facture en fonction des
conditions de reglements de la facture et date de facturation conditions de reglements de la facture et date de facturation
\param cond_reglement_id Condition de reglement à utiliser, 0=Condition actuelle de la facture \param cond_reglement_id Condition de reglement <EFBFBD> utiliser, 0=Condition actuelle de la facture
\return date Date limite de réglement si ok, <0 si ko \return date Date limite de r<EFBFBD>glement si ok, <0 si ko
*/ */
function calculate_date_lim_reglement($cond_reglement_id=0) function calculate_date_lim_reglement($cond_reglement_id=0)
{ {
@ -1060,7 +1071,7 @@ class Facture extends CommonObject
// 1 : ajout du nombre de jours // 1 : ajout du nombre de jours
$datelim = $this->date + ( $cdr_nbjour * 3600 * 24 ); $datelim = $this->date + ( $cdr_nbjour * 3600 * 24 );
// 2 : application de la règle "fin de mois" // 2 : application de la r<EFBFBD>gle "fin de mois"
if ($cdr_fdm) if ($cdr_fdm)
{ {
$mois=date('m', $datelim); $mois=date('m', $datelim);
@ -1074,22 +1085,22 @@ class Facture extends CommonObject
{ {
$mois += 1; $mois += 1;
} }
// On se déplace au début du mois suivant, et on retire un jour // On se d<EFBFBD>place au d<>but du mois suivant, et on retire un jour
$datelim=dol_mktime(12,0,0,$mois,1,$annee); $datelim=dol_mktime(12,0,0,$mois,1,$annee);
$datelim -= (3600 * 24); $datelim -= (3600 * 24);
} }
// 3 : application du décalage // 3 : application du d<EFBFBD>calage
$datelim += ( $cdr_decalage * 3600 * 24); $datelim += ( $cdr_decalage * 3600 * 24);
return $datelim; return $datelim;
} }
/** /**
* \brief Tag la facture comme payée complètement (close_code non renseigné) ou partiellement (close_code renseigné) + appel trigger BILL_PAYED * \brief Tag la facture comme pay<EFBFBD>e compl<EFBFBD>tement (close_code non renseign<EFBFBD>) ou partiellement (close_code renseign<EFBFBD>) + appel trigger BILL_PAYED
* \param user Objet utilisateur qui modifie * \param user Objet utilisateur qui modifie
* \param close_code Code renseigné si on classe à payée complètement alors que paiement incomplet (cas ecompte par exemple) * \param close_code Code renseign<EFBFBD> si on classe <EFBFBD> pay<EFBFBD>e compl<EFBFBD>tement alors que paiement incomplet (cas ecompte par exemple)
* \param close_note Commentaire renseigné si on classe à payée alors que paiement incomplet (cas ecompte par exemple) * \param close_note Commentaire renseign<EFBFBD> si on classe <EFBFBD> pay<EFBFBD>e alors que paiement incomplet (cas ecompte par exemple)
* \return int <0 si ok, >0 si ok * \return int <0 si ok, >0 si ok
*/ */
function set_paid($user,$close_code='',$close_note='') function set_paid($user,$close_code='',$close_note='')
@ -1129,9 +1140,9 @@ class Facture extends CommonObject
/** /**
* \brief Tag la facture comme non payée complètement + appel trigger BILL_UNPAYED * \brief Tag la facture comme non pay<EFBFBD>e compl<EFBFBD>tement + appel trigger BILL_UNPAYED
* Fonction utilisée quand un paiement prélevement est refusé, * Fonction utilis<EFBFBD>e quand un paiement pr<EFBFBD>levement est refus<EFBFBD>,
* ou quand une facture annulée et réouverte. * ou quand une facture annul<EFBFBD>e et r<EFBFBD>ouverte.
* \param user Object user that change status * \param user Object user that change status
* \return int <0 si ok, >0 si ok * \return int <0 si ok, >0 si ok
*/ */
@ -1163,7 +1174,7 @@ class Facture extends CommonObject
/** /**
\brief Tag la facture comme abandonnée, sans paiement dessus (exemple car facture de remplacement) + appel trigger BILL_CANCEL \brief Tag la facture comme abandonn<EFBFBD>e, sans paiement dessus (exemple car facture de remplacement) + appel trigger BILL_CANCEL
\param user Objet utilisateur qui modifie \param user Objet utilisateur qui modifie
\param close_code Code de fermeture \param close_code Code de fermeture
\param close_note Commentaire de fermeture \param close_note Commentaire de fermeture
@ -1186,8 +1197,8 @@ class Facture extends CommonObject
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) if ($resql)
{ {
// On désaffecte de la facture les remises liées // On d<EFBFBD>saffecte de la facture les remises li<6C>es
// car elles n'ont pas été utilisées vu que la facture est abandonnée. // car elles n'ont pas <EFBFBD>t<EFBFBD> utilis<69>es vu que la facture est abandonn<6E>e.
$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
$sql.= ' SET fk_facture = NULL'; $sql.= ' SET fk_facture = NULL';
$sql.= ' WHERE fk_facture = '.$this->id; $sql.= ' WHERE fk_facture = '.$this->id;
@ -1223,10 +1234,10 @@ class Facture extends CommonObject
} }
/** /**
* \brief Tag la facture comme validée + appel trigger BILL_VALIDATE * \brief Tag la facture comme valid<EFBFBD>e + appel trigger BILL_VALIDATE
* \param user Utilisateur qui valide la facture * \param user Utilisateur qui valide la facture
* \param soc Ne sert plus. \\TODO A virer * \param soc Ne sert plus. \\TODO A virer
* \param force_number Référence à forcer de la facture * \param force_number R<EFBFBD>f<EFBFBD>rence <EFBFBD> forcer de la facture
* \return int <0 si ko, >0 si ok * \return int <0 si ko, >0 si ok
*/ */
function set_valid($user, $soc='', $force_number='') function set_valid($user, $soc='', $force_number='')
@ -1335,10 +1346,10 @@ class Facture extends CommonObject
$error++; $error++;
} }
// On vérifie si la facture était une provisoire // On v<EFBFBD>rifie si la facture <20>tait une provisoire
if (! $error && (eregi('^\(PROV', $this->ref) || eregi('^PROV', $this->ref))) if (! $error && (eregi('^\(PROV', $this->ref) || eregi('^PROV', $this->ref)))
{ {
// La vérif qu'une remise n'est pas utilisée 2 fois est faite au moment de l'insertion de ligne // La v<EFBFBD>rif qu'une remise n'est pas utilis<69>e 2 fois est faite au moment de l'insertion de ligne
} }
if (! $error) if (! $error)
@ -1346,7 +1357,7 @@ class Facture extends CommonObject
// Define third party as a customer // Define third party as a customer
$result=$this->client->set_as_client(); $result=$this->client->set_as_client();
// Si activé on décrémente le produit principal et ses composants à la validation de facture // Si activ<EFBFBD> on d<>cr<63>mente le produit principal et ses composants <20> la validation de facture
if ($result >= 0 && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_BILL) if ($result >= 0 && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_BILL)
{ {
require_once(DOL_DOCUMENT_ROOT."/product/stock/mouvementstock.class.php"); require_once(DOL_DOCUMENT_ROOT."/product/stock/mouvementstock.class.php");
@ -1358,7 +1369,7 @@ class Facture extends CommonObject
{ {
$mouvP = new MouvementStock($this->db); $mouvP = new MouvementStock($this->db);
// We decrease stock for product // We decrease stock for product
$entrepot_id = "1"; // TODO ajouter possibilité de choisir l'entrepot $entrepot_id = "1"; // TODO ajouter possibilit<EFBFBD> de choisir l'entrepot
$result=$mouvP->livraison($user, $this->lignes[$i]->fk_product, $entrepot_id, $this->lignes[$i]->qty, $this->lignes[$i]->subprice); $result=$mouvP->livraison($user, $this->lignes[$i]->fk_product, $entrepot_id, $this->lignes[$i]->qty, $this->lignes[$i]->subprice);
if ($result < 0) { $error++; } if ($result < 0) { $error++; }
} }
@ -1372,7 +1383,7 @@ class Facture extends CommonObject
if (eregi('^\(PROV', $this->ref) || eregi('^PROV', $this->ref)) if (eregi('^\(PROV', $this->ref) || eregi('^PROV', $this->ref))
{ {
// On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref) // On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref)
// afin de ne pas perdre les fichiers attachés // afin de ne pas perdre les fichiers attach<EFBFBD>s
$facref = dol_sanitizeFileName($this->ref); $facref = dol_sanitizeFileName($this->ref);
$snumfa = dol_sanitizeFileName($num); $snumfa = dol_sanitizeFileName($num);
$dirsource = $conf->facture->dir_output.'/'.$facref; $dirsource = $conf->facture->dir_output.'/'.$facref;
@ -1442,7 +1453,7 @@ class Facture extends CommonObject
dol_syslog("Facture::set_draft sql=".$sql, LOG_DEBUG); dol_syslog("Facture::set_draft sql=".$sql, LOG_DEBUG);
if ($this->db->query($sql)) if ($this->db->query($sql))
{ {
// Si activé on décrémente le produit principal et ses composants à la validation de facture // Si activ<EFBFBD> on d<>cr<63>mente le produit principal et ses composants <20> la validation de facture
if ($result >= 0 && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_BILL) if ($result >= 0 && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_BILL)
{ {
require_once(DOL_DOCUMENT_ROOT."/product/stock/mouvementstock.class.php"); require_once(DOL_DOCUMENT_ROOT."/product/stock/mouvementstock.class.php");
@ -1453,7 +1464,7 @@ class Facture extends CommonObject
{ {
$mouvP = new MouvementStock($this->db); $mouvP = new MouvementStock($this->db);
// We decrease stock for product // We decrease stock for product
$entrepot_id = "1"; // TODO ajouter possibilité de choisir l'entrepot $entrepot_id = "1"; // TODO ajouter possibilit<EFBFBD> de choisir l'entrepot
$result=$mouvP->reception($user, $this->lignes[$i]->fk_product, $entrepot_id, $this->lignes[$i]->qty, $this->lignes[$i]->subprice); $result=$mouvP->reception($user, $this->lignes[$i]->fk_product, $entrepot_id, $this->lignes[$i]->qty, $this->lignes[$i]->subprice);
} }
} }
@ -1479,12 +1490,12 @@ class Facture extends CommonObject
* \param facid Id de la facture * \param facid Id de la facture
* \param desc Description de la ligne * \param desc Description de la ligne
* \param pu_ht Prix unitaire HT * \param pu_ht Prix unitaire HT
* \param qty Quantité * \param qty Quantit<EFBFBD>
* \param txtva Taux de tva forcé, sinon -1 * \param txtva Taux de tva forc<EFBFBD>, sinon -1
* \param fk_product Id du produit/service predéfini * \param fk_product Id du produit/service pred<EFBFBD>fini
* \param remise_percent Pourcentage de remise de la ligne * \param remise_percent Pourcentage de remise de la ligne
* \param date_start Date de debut de validité du service * \param date_start Date de debut de validit<EFBFBD> du service
* \param date_end Date de fin de validité du service * \param date_end Date de fin de validit<EFBFBD> du service
* \param ventil Code de ventilation comptable * \param ventil Code de ventilation comptable
* \param info_bits Bits de type de lignes * \param info_bits Bits de type de lignes
* \param fk_remise_except Id remise * \param fk_remise_except Id remise
@ -1492,8 +1503,8 @@ class Facture extends CommonObject
* \param pu_ttc Prix unitaire TTC * \param pu_ttc Prix unitaire TTC
* \param type Type of line (0=product, 1=service) * \param type Type of line (0=product, 1=service)
* \return int >0 if OK, <0 if KO * \return int >0 if OK, <0 if KO
* \remarks Les parametres sont deja censé etre juste et avec valeurs finales a l'appel * \remarks Les parametres sont deja cens<EFBFBD> etre juste et avec valeurs finales a l'appel
* de cette methode. Aussi, pour le taux tva, il doit deja avoir ete défini * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete d<EFBFBD>fini
* par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,taux_produit) * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,taux_produit)
* et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue) * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
*/ */
@ -1614,8 +1625,8 @@ class Facture extends CommonObject
* \param pu Prix unitaire (HT ou TTC selon price_base_type) * \param pu Prix unitaire (HT ou TTC selon price_base_type)
* \param qty Quantity * \param qty Quantity
* \param remise_percent Pourcentage de remise de la ligne * \param remise_percent Pourcentage de remise de la ligne
* \param date_start Date de debut de validité du service * \param date_start Date de debut de validit<EFBFBD> du service
* \param date_end Date de fin de validité du service * \param date_end Date de fin de validit<EFBFBD> du service
* \param tva_tx VAT Rate * \param tva_tx VAT Rate
* \param price_base_type HT or TTC * \param price_base_type HT or TTC
* \param info_bits Miscellanous informations * \param info_bits Miscellanous informations
@ -1958,10 +1969,10 @@ class Facture extends CommonObject
$sql.= ' AND type < 2'; $sql.= ' AND type < 2';
if ($option == 'validated') $sql.= ' AND fk_statut = 1'; if ($option == 'validated') $sql.= ' AND fk_statut = 1';
// PROTECTION BAD DATA // PROTECTION BAD DATA
// Au cas ou base corrompue et qu'il y a une facture de remplacement validée // Au cas ou base corrompue et qu'il y a une facture de remplacement valid<EFBFBD>e
// et une autre non, on donne priorité à la validée. // et une autre non, on donne priorit<EFBFBD> <20> la valid<69>e.
// Ne devrait pas arriver (sauf si accès concurrentiel et que 2 personnes // Ne devrait pas arriver (sauf si acc<EFBFBD>s concurrentiel et que 2 personnes
// ont créé en meme temps une facture de remplacement pour la meme facture) // ont cr<EFBFBD><EFBFBD> en meme temps une facture de remplacement pour la meme facture)
$sql.= ' ORDER BY fk_statut DESC'; $sql.= ' ORDER BY fk_statut DESC';
$resql=$this->db->query($sql); $resql=$this->db->query($sql);
@ -1986,7 +1997,7 @@ class Facture extends CommonObject
} }
/** /**
* \brief Retourne le libellé du type de facture * \brief Retourne le libell<EFBFBD> du type de facture
* \return string Libelle * \return string Libelle
*/ */
function getLibType() function getLibType()
@ -2001,8 +2012,8 @@ class Facture extends CommonObject
/** /**
* \brief Retourne le libellé du statut d'une facture (brouillon, validée, abandonnée, payée) * \brief Retourne le libell<EFBFBD> du statut d'une facture (brouillon, valid<EFBFBD>e, abandonn<EFBFBD>e, pay<EFBFBD>e)
* \param mode 0=libellé long, 1=libellé court, 2=Picto + Libellé court, 3=Picto, 4=Picto + Libellé lon * \param mode 0=libell<EFBFBD> long, 1=libell<EFBFBD> court, 2=Picto + Libell<EFBFBD> court, 3=Picto, 4=Picto + Libell<EFBFBD> lon
* \param alreadypaid 0=Not payment already done, 1=Some payments already done * \param alreadypaid 0=Not payment already done, 1=Some payments already done
* \return string Libelle * \return string Libelle
*/ */
@ -2012,13 +2023,13 @@ class Facture extends CommonObject
} }
/** /**
* \brief Renvoi le libellé d'un statut donné * \brief Renvoi le libell<EFBFBD> d'un statut donn<EFBFBD>
* \param paye Etat paye * \param paye Etat paye
* \param statut Id statut * \param statut Id statut
* \param mode 0=libellé long, 1=libellé court, 2=Picto + Libellé court, 3=Picto, 4=Picto + Libellé long, 5=Libellé court + Pict * \param mode 0=libell<EFBFBD> long, 1=libell<EFBFBD> court, 2=Picto + Libell<EFBFBD> court, 3=Picto, 4=Picto + Libell<EFBFBD> long, 5=Libell<EFBFBD> court + Pict
* \param alreadypaid Montant deja payé * \param alreadypaid Montant deja pay<EFBFBD>
* \param type Type facture * \param type Type facture
* \return string Libellé du statut * \return string Libell<EFBFBD> du statut
*/ */
function LibStatut($paye,$statut,$mode=0,$alreadypaid=-1,$type=0) function LibStatut($paye,$statut,$mode=0,$alreadypaid=-1,$type=0)
{ {
@ -2136,8 +2147,8 @@ class Facture extends CommonObject
} }
/** /**
* \brief Renvoie la référence de facture suivante non utilisée en fonction du module * \brief Renvoie la r<EFBFBD>f<EFBFBD>rence de facture suivante non utilis<EFBFBD>e en fonction du module
* de numérotation actif défini dans FACTURE_ADDON * de num<EFBFBD>rotation actif d<EFBFBD>fini dans FACTURE_ADDON
* \param soc objet societe * \param soc objet societe
* \return string reference libre pour la facture * \return string reference libre pour la facture
*/ */
@ -2152,7 +2163,7 @@ class Facture extends CommonObject
{ {
$file = FACTURE_ADDON."/".FACTURE_ADDON.".modules.php"; $file = FACTURE_ADDON."/".FACTURE_ADDON.".modules.php";
// Chargement de la classe de numérotation // Chargement de la classe de num<EFBFBD>rotation
$classname = "mod_facture_".FACTURE_ADDON; $classname = "mod_facture_".FACTURE_ADDON;
require_once($dir.$file); require_once($dir.$file);
@ -2221,8 +2232,8 @@ class Facture extends CommonObject
} }
/** /**
* \brief Change les conditions de réglement de la facture * \brief Change les conditions de r<EFBFBD>glement de la facture
* \param cond_reglement_id Id de la nouvelle condition de réglement * \param cond_reglement_id Id de la nouvelle condition de r<EFBFBD>glement
* \param date Date to force payment term * \param date Date to force payment term
* \return int >0 si ok, <0 si ko * \return int >0 si ok, <0 si ko
*/ */
@ -2270,7 +2281,7 @@ class Facture extends CommonObject
/** /**
* \brief Change le mode de réglement * \brief Change le mode de r<EFBFBD>glement
* \param mode Id du nouveau mode * \param mode Id du nouveau mode
* \return int >0 si ok, <0 si ko * \return int >0 si ok, <0 si ko
*/ */
@ -2304,13 +2315,13 @@ class Facture extends CommonObject
/** /**
* \brief Renvoi si les lignes de facture sont ventilées et/ou exportées en compta * \brief Renvoi si les lignes de facture sont ventil<EFBFBD>es et/ou export<EFBFBD>es en compta
* \param user Utilisateur créant la demande * \param user Utilisateur cr<EFBFBD>ant la demande
* \return int <0 si ko, 0=non, 1=oui * \return int <0 si ko, 0=non, 1=oui
*/ */
function getVentilExportCompta() function getVentilExportCompta()
{ {
// On vérifie si les lignes de factures ont été exportées en compta et/ou ventilées // On v<EFBFBD>rifie si les lignes de factures ont <20>t<EFBFBD> export<72>es en compta et/ou ventil<69>es
$ventilExportCompta = 0 ; $ventilExportCompta = 0 ;
for ($i = 0 ; $i < sizeof($this->lignes) ; $i++) for ($i = 0 ; $i < sizeof($this->lignes) ; $i++)
{ {
@ -2332,9 +2343,9 @@ class Facture extends CommonObject
/** /**
* \brief Renvoi si une facture peut etre supprimée complètement. * \brief Renvoi si une facture peut etre supprim<EFBFBD>e compl<EFBFBD>tement.
* La règle est la suivante: * La r<EFBFBD>gle est la suivante:
* Si facture dernière, non provisoire, sans paiement et non exporté en compta -> oui fin de règle * Si facture derni<EFBFBD>re, non provisoire, sans paiement et non export<EFBFBD> en compta -> oui fin de r<EFBFBD>gle
* Si facture brouillon et provisoire -> oui * Si facture brouillon et provisoire -> oui
* \return int <0 si ko, 0=non, 1=oui * \return int <0 si ko, 0=non, 1=oui
*/ */
@ -2342,14 +2353,14 @@ class Facture extends CommonObject
{ {
global $conf; global $conf;
// on vérifie si la facture est en numérotation provisoire // on v<EFBFBD>rifie si la facture est en num<75>rotation provisoire
$facref = substr($this->ref, 1, 4); $facref = substr($this->ref, 1, 4);
// Si facture non brouillon et non provisoire // Si facture non brouillon et non provisoire
if ($facref != 'PROV' && $conf->global->FACTURE_ENABLE_EDITDELETE) if ($facref != 'PROV' && $conf->global->FACTURE_ENABLE_EDITDELETE)
{ {
// On ne peut supprimer que la dernière facture validée // On ne peut supprimer que la derni<EFBFBD>re facture valid<69>e
// pour ne pas avoir de trou dans la numérotation // pour ne pas avoir de trou dans la num<EFBFBD>rotation
$sql = "SELECT MAX(facnumber)"; $sql = "SELECT MAX(facnumber)";
$sql.= " FROM ".MAIN_DB_PREFIX."facture"; $sql.= " FROM ".MAIN_DB_PREFIX."facture";
$sql.= " WHERE entity = ".$conf->entity; $sql.= " WHERE entity = ".$conf->entity;
@ -2362,7 +2373,7 @@ class Facture extends CommonObject
$ventilExportCompta = $this->getVentilExportCompta(); $ventilExportCompta = $this->getVentilExportCompta();
// Si derniere facture et si non ventilée, on peut supprimer // Si derniere facture et si non ventil<EFBFBD>e, on peut supprimer
if ($maxfacnumber[0] == $this->ref && $ventilExportCompta == 0) if ($maxfacnumber[0] == $this->ref && $ventilExportCompta == 0)
{ {
return 1; return 1;
@ -2379,7 +2390,7 @@ class Facture extends CommonObject
/** /**
* \brief Renvoi liste des factures remplacables * \brief Renvoi liste des factures remplacables
* Statut validée ou abandonnée pour raison autre + non payée + aucun paiement + pas deja remplacée * Statut valid<EFBFBD>e ou abandonn<EFBFBD>e pour raison autre + non pay<EFBFBD>e + aucun paiement + pas deja remplac<EFBFBD>e
* \param socid Id societe * \param socid Id societe
* \return array Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) * \return array Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1)
*/ */
@ -2396,7 +2407,7 @@ class Facture extends CommonObject
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source";
$sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))"; $sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))";
$sql.= " AND f.entity = ".$conf->entity; $sql.= " AND f.entity = ".$conf->entity;
$sql.= " AND f.paye = 0"; // Pas classée payée complètement $sql.= " AND f.paye = 0"; // Pas class<EFBFBD>e pay<61>e compl<70>tement
$sql.= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait $sql.= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait
$sql.= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement $sql.= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement
if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
@ -2427,7 +2438,7 @@ class Facture extends CommonObject
/** /**
* \brief Renvoi liste des factures qualifiables pour correction par avoir * \brief Renvoi liste des factures qualifiables pour correction par avoir
* Les factures qui respectent les regles suivantes sont retournees: * Les factures qui respectent les regles suivantes sont retournees:
* (validée + paiement en cours) ou classée (payée completement ou payée partiellement) + pas deja remplacée + pas deja avoi * (valid<EFBFBD>e + paiement en cours) ou class<EFBFBD>e (pay<EFBFBD>e completement ou pay<EFBFBD>e partiellement) + pas deja remplac<EFBFBD>e + pas deja avoi
* \param socid Id societe * \param socid Id societe
* \return array Tableau des factures ($id => $ref) * \return array Tableau des factures ($id => $ref)
*/ */
@ -2444,8 +2455,8 @@ class Facture extends CommonObject
$sql.= " WHERE f.entity = ".$conf->entity; $sql.= " WHERE f.entity = ".$conf->entity;
$sql.= " AND f.fk_statut in (1,2)"; $sql.= " AND f.fk_statut in (1,2)";
// $sql.= " WHERE f.fk_statut >= 1"; // $sql.= " WHERE f.fk_statut >= 1";
// $sql.= " AND (f.paye = 1"; // Classée payée complètement // $sql.= " AND (f.paye = 1"; // Class<EFBFBD>e pay<61>e compl<70>tement
// $sql.= " OR f.close_code IS NOT NULL)"; // Classée payée partiellement // $sql.= " OR f.close_code IS NOT NULL)"; // Class<EFBFBD>e pay<61>e partiellement
$sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement $sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement
$sql.= " AND f.type != 2"; // Type non 2 si facture non avoir $sql.= " AND f.type != 2"; // Type non 2 si facture non avoir
if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
@ -2480,8 +2491,8 @@ class Facture extends CommonObject
/** /**
* \brief Créé une demande de prélèvement * \brief Cr<EFBFBD><EFBFBD> une demande de pr<EFBFBD>l<EFBFBD>vement
* \param user Utilisateur créant la demande * \param user Utilisateur cr<EFBFBD>ant la demande
* \return int <0 si ko, >0 si ok * \return int <0 si ko, >0 si ok
*/ */
function demande_prelevement($user) function demande_prelevement($user)
@ -2526,8 +2537,8 @@ class Facture extends CommonObject
} }
else else
{ {
$this->error="Une demande existe déjà"; $this->error="Une demande existe d<EFBFBD>j<EFBFBD>";
dol_syslog('Facture::DemandePrelevement Impossible de créer une demande, demande déja en cours'); dol_syslog('Facture::DemandePrelevement Impossible de cr<EFBFBD>er une demande, demande d<>ja en cours');
} }
} }
else else
@ -2546,8 +2557,8 @@ class Facture extends CommonObject
} }
/** /**
* \brief Supprime une demande de prélèvement * \brief Supprime une demande de pr<EFBFBD>l<EFBFBD>vement
* \param user utilisateur créant la demande * \param user utilisateur cr<EFBFBD>ant la demande
* \param did id de la demande a supprimer * \param did id de la demande a supprimer
*/ */
function demande_prelevement_delete($user, $did) function demande_prelevement_delete($user, $did)
@ -2635,14 +2646,14 @@ class Facture extends CommonObject
/** /**
* \brief Initialise la facture avec valeurs fictives aléatoire * \brief Initialise la facture avec valeurs fictives al<EFBFBD>atoire
* Sert à générer une facture pour l'aperu des modèles ou dem * Sert <EFBFBD> g<EFBFBD>n<EFBFBD>rer une facture pour l'aperu des mod<EFBFBD>les ou dem
*/ */
function initAsSpecimen() function initAsSpecimen()
{ {
global $user,$langs,$conf; global $user,$langs,$conf;
// Charge tableau des id de société socids // Charge tableau des id de soci<EFBFBD>t<EFBFBD> socids
$socids = array(); $socids = array();
$sql = "SELECT rowid"; $sql = "SELECT rowid";
@ -2790,17 +2801,18 @@ class FactureLigne
var $tva_tx; // Taux tva produit/service (example 19.6) var $tva_tx; // Taux tva produit/service (example 19.6)
var $subprice; // P.U. HT (example 100) var $subprice; // P.U. HT (example 100)
var $remise_percent; // % de la remise ligne (example 20%) var $remise_percent; // % de la remise ligne (example 20%)
var $fk_remise_except; // Link to line into llx_remise_except
var $rang = 0; var $rang = 0;
var $info_bits = 0; // Liste d'options cumulables: var $info_bits = 0; // Liste d'options cumulables:
// Bit 0: 0 si TVA normal - 1 si TVA NPR // Bit 0: 0 si TVA normal - 1 si TVA NPR
// Bit 1: 0 si ligne normal - 1 si bit discount // Bit 1: 0 si ligne normal - 1 si bit discount (link to line into llx_remise_except)
//! Total HT de la ligne toute quantité et incluant la remise ligne //! Total HT de la ligne toute quantite et incluant la remise ligne
var $total_ht; var $total_ht;
//! Total TVA de la ligne toute quantité et incluant la remise ligne //! Total TVA de la ligne toute quantite et incluant la remise ligne
var $total_tva; var $total_tva;
//! Total TTC de la ligne toute quantité et incluant la remise ligne //! Total TTC de la ligne toute quantite et incluant la remise ligne
var $total_ttc; var $total_ttc;
var $fk_code_ventilation = 0; var $fk_code_ventilation = 0;
@ -2811,7 +2823,7 @@ class FactureLigne
// Ne plus utiliser // Ne plus utiliser
var $price; // P.U. HT apres remise % de ligne (exemple 80) var $price; // P.U. HT apres remise % de ligne (exemple 80)
var $remise; // Montant calculé de la remise % sur PU HT (exemple 20) var $remise; // Montant calcul<EFBFBD> de la remise % sur PU HT (exemple 20)
// From llx_product // From llx_product
var $ref; // Reference produit var $ref; // Reference produit
@ -2821,7 +2833,7 @@ class FactureLigne
/** /**
\brief Constructeur d'objets ligne de facture \brief Constructeur d'objets ligne de facture
\param DB handler d'accès base de donnée \param DB handler d'acc<EFBFBD>s base de donn<EFBFBD>e
*/ */
function FactureLigne($DB) function FactureLigne($DB)
{ {
@ -2829,7 +2841,7 @@ class FactureLigne
} }
/** /**
* \brief Recupére l'objet ligne de facture * \brief Recupere l'objet ligne de facture
* \param rowid id de la ligne de facture * \param rowid id de la ligne de facture
*/ */
function fetch($rowid) function fetch($rowid)
@ -2909,7 +2921,7 @@ class FactureLigne
$rangtouse=$this->rang; $rangtouse=$this->rang;
if ($rangtouse == -1) if ($rangtouse == -1)
{ {
// Récupère rang max de la facture dans $rangmax // R<EFBFBD>cup<EFBFBD>re rang max de la facture dans $rangmax
$sql = 'SELECT max(rang) as max FROM '.MAIN_DB_PREFIX.'facturedet'; $sql = 'SELECT max(rang) as max FROM '.MAIN_DB_PREFIX.'facturedet';
$sql.= ' WHERE fk_facture ='.$this->fk_facture; $sql.= ' WHERE fk_facture ='.$this->fk_facture;
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -2965,8 +2977,8 @@ class FactureLigne
{ {
$this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet'); $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet');
// Si fk_remise_except défini, on lie la remise à la facture // Si fk_remise_except d<EFBFBD>fini, on lie la remise <20> la facture
// ce qui la flague comme "consommée". // ce qui la flague comme "consomm<EFBFBD>e".
if ($this->fk_remise_except) if ($this->fk_remise_except)
{ {
$discount=new DiscountAbsolute($this->db); $discount=new DiscountAbsolute($this->db);

View File

@ -152,7 +152,7 @@ class FactureFournisseur extends Facture
if ($resql) if ($resql)
{ {
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn'); $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn');
for ($i = 0 ; $i < sizeof($this->lignes) ; $i++) foreach ($this->lignes as $i => $val)
{ {
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture_fourn_det (fk_facture_fourn)'; $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture_fourn_det (fk_facture_fourn)';
$sql .= ' VALUES ('.$this->id.');'; $sql .= ' VALUES ('.$this->id.');';
@ -894,6 +894,15 @@ class FactureFournisseur extends Facture
$object->close_code = ''; $object->close_code = '';
$object->close_note = ''; $object->close_note = '';
// Loop on each line of new invoice
foreach($object->lignes as $i => $line)
{
if (($object->lignes[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts
{
unset($object->lignes[$i]);
}
}
// Create clone // Create clone
$result=$object->create($user); $result=$object->create($user);

View File

@ -277,7 +277,7 @@ class pdf_einstein extends ModelePDFCommandes
// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
$tvaligne=$com->lignes[$i]->total_tva; $tvaligne=$com->lignes[$i]->total_tva;
$vatrate=(string) $com->lignes[$i]->tva_tx; $vatrate=(string) $com->lignes[$i]->tva_tx;
if ($com->lignes[$i]->info_bits & 0x01 == 0x01) $vatrate.='*'; if (($com->lignes[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
$this->tva[$vatrate] += $tvaligne; $this->tva[$vatrate] += $tvaligne;
$nexY+=2; // Passe espace entre les lignes $nexY+=2; // Passe espace entre les lignes

View File

@ -284,7 +284,7 @@ class pdf_crabe extends ModelePDFFactures
$tvaligne=$fac->lignes[$i]->total_tva; $tvaligne=$fac->lignes[$i]->total_tva;
if ($fac->remise_percent) $tvaligne-=($tvaligne*$fac->remise_percent)/100; if ($fac->remise_percent) $tvaligne-=($tvaligne*$fac->remise_percent)/100;
$vatrate=(string) $fac->lignes[$i]->tva_tx; $vatrate=(string) $fac->lignes[$i]->tva_tx;
if ($fac->lignes[$i]->info_bits & 0x01 == 0x01) $vatrate.='*'; if (($fac->lignes[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
$this->tva[$vatrate] += $tvaligne; $this->tva[$vatrate] += $tvaligne;
$nexY+=2; // Passe espace entre les lignes $nexY+=2; // Passe espace entre les lignes

View File

@ -292,7 +292,7 @@ class pdf_propale_azur extends ModelePDFPropales
$tvaligne=$propale->lignes[$i]->total_tva; $tvaligne=$propale->lignes[$i]->total_tva;
if ($propale->remise_percent) $tvaligne-=($tvaligne*$propale->remise_percent)/100; if ($propale->remise_percent) $tvaligne-=($tvaligne*$propale->remise_percent)/100;
$vatrate=(string) $propale->lignes[$i]->tva_tx; $vatrate=(string) $propale->lignes[$i]->tva_tx;
if ($propale->lignes[$i]->info_bits & 0x01 == 0x01) $vatrate.='*'; if (($propale->lignes[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
$this->tva[$vatrate] += $tvaligne; $this->tva[$vatrate] += $tvaligne;
$nexY+=2; // Passe espace entre les lignes $nexY+=2; // Passe espace entre les lignes

View File

@ -279,7 +279,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
$tvaligne=$com->lignes[$i]->total_tva; $tvaligne=$com->lignes[$i]->total_tva;
if ($com->remise_percent) $tvaligne-=($tvaligne*$com->remise_percent)/100; if ($com->remise_percent) $tvaligne-=($tvaligne*$com->remise_percent)/100;
$vatrate=(string) $com->lignes[$i]->tva_tx; $vatrate=(string) $com->lignes[$i]->tva_tx;
if ($com->lignes[$i]->info_bits & 0x01 == 0x01) $vatrate.='*'; if (($com->lignes[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
$this->tva[$vatrate] += $tvaligne; $this->tva[$vatrate] += $tvaligne;
$nexY+=2; // Passe espace entre les lignes $nexY+=2; // Passe espace entre les lignes

View File

@ -220,6 +220,7 @@ if (isset($_POST['action']) && eregi('upgrade',$_POST["action"]))
migrate_commande_deliveryaddress($db,$langs,$conf); migrate_commande_deliveryaddress($db,$langs,$conf);
migrate_restore_missing_links($db,$langs,$conf);
// On commit dans tous les cas. // On commit dans tous les cas.
// La procedure etant concue pour pouvoir passer plusieurs fois quelquesoit la situation. // La procedure etant concue pour pouvoir passer plusieurs fois quelquesoit la situation.
@ -2184,6 +2185,158 @@ function migrate_commande_deliveryaddress($db,$langs,$conf)
} }
/*
* Migration du champ fk_remise_except dans llx_facturedet doit correspondre a
* lien dans llx_societe_remise_except vers llx_facturedet
*/
function migrate_restore_missing_links($db,$langs,$conf)
{
dolibarr_install_syslog("upgrade2::migrate_restore_missing_links");
if (($db->type == 'mysql' || $db->type == 'mysqli'))
{
if (versioncompare($db->getVersionArray(),array(4,0)) < 0)
{
dolibarr_install_syslog("upgrade2::migrate_restore_missing_links Version of database too old to make this migrate action");
return 0;
}
}
print '<tr><td colspan="4">';
print '<br>';
print '<b>'.$langs->trans('MigrationFixData')."</b> (1)<br>\n";
$error = 0;
// Restore missing link for this cross foreign key (link 1 <=> 1). Direction 1.
$table1='facturedet'; $field1='fk_remise_except';
$table2='societe_remise_except'; $field2='fk_facture_line';
$db->begin();
$sql = "SELECT t1.rowid, t1.".$field1." as field";
$sql.= " FROM ".MAIN_DB_PREFIX.$table1." as t1";
$sql.= " WHERE t1.".$field1." IS NOT NULL AND t1.".$field1." NOT IN";
$sql.= " (SELECT t2.rowid FROM ".MAIN_DB_PREFIX.$table2." as t2";
$sql.= " WHERE t1.rowid = t2.".$field2.")";
dolibarr_install_syslog("upgrade2:migrate_restore_missing_links DIRECTION 1 sql=".$sql);
$resql = $db->query($sql);
if ($resql)
{
$i = 0;
$num = $db->num_rows($resql);
if ($num)
{
while ($i < $num)
{
$obj = $db->fetch_object($resql);
print 'Line '.$obj->rowid.' in '.$table1.' is linked to record '.$obj->field.' in '.$table2.' that has no link to '.$table1.'. We fix this.<br>';
$sql = "UPDATE ".MAIN_DB_PREFIX.$table2." SET";
$sql.= " ".$field2." = '".$obj->rowid."'";
$sql.= " WHERE rowid=".$obj->field;
$resql2=$db->query($sql);
if (! $resql2)
{
$error++;
dol_print_error($db);
}
//print ". ";
$i++;
}
}
else print $langs->trans('AlreadyDone')."<br>\n";
if ($error == 0)
{
$db->commit();
}
else
{
$db->rollback();
}
}
else
{
dol_print_error($db);
$db->rollback();
}
print '</td></tr>';
print '<tr><td colspan="4">';
print '<br>';
print '<b>'.$langs->trans('MigrationFixData')."</b> (2)<br>\n";
// Restore missing link for this cross foreign key (link 1 <=> 1). Direction 2.
$table2='facturedet'; $field2='fk_remise_except';
$table1='societe_remise_except'; $field1='fk_facture_line';
$db->begin();
$sql = "SELECT t1.rowid, t1.".$field1." as field";
$sql.= " FROM ".MAIN_DB_PREFIX.$table1." as t1";
$sql.= " WHERE t1.".$field1." IS NOT NULL AND t1.".$field1." NOT IN";
$sql.= " (SELECT t2.rowid FROM ".MAIN_DB_PREFIX.$table2." as t2";
$sql.= " WHERE t1.rowid = t2.".$field2.")";
dolibarr_install_syslog("upgrade2:migrate_restore_missing_links DIRECTION 2 sql=".$sql);
$resql = $db->query($sql);
if ($resql)
{
$i = 0;
$num = $db->num_rows($resql);
if ($num)
{
while ($i < $num)
{
$obj = $db->fetch_object($resql);
print 'Line '.$obj->rowid.' in '.$table1.' is linked to record '.$obj->field.' in '.$table2.' that has no link to '.$table1.'. We fix this.<br>';
$sql = "UPDATE ".MAIN_DB_PREFIX.$table2." SET";
$sql.= " ".$field2." = '".$obj->rowid."'";
$sql.= " WHERE rowid=".$obj->field;
$resql2=$db->query($sql);
if (! $resql2)
{
$error++;
dol_print_error($db);
}
//print ". ";
$i++;
}
}
else print $langs->trans('AlreadyDone')."<br>\n";
if ($error == 0)
{
$db->commit();
}
else
{
$db->rollback();
}
}
else
{
dol_print_error($db);
$db->rollback();
}
print '</td></tr>';
}
/* A faire egalement: Modif statut paye et fk_facture des factures payes completement /* A faire egalement: Modif statut paye et fk_facture des factures payes completement
On recherche facture incorrecte: On recherche facture incorrecte:

View File

@ -135,6 +135,7 @@ InstallChoiceSuggested=<b>Install choice suggested by installer</b>.
######### #########
# upgrade # upgrade
######### #########
MigrationFixData=Fix for denormalized data
MigrationOrder=Data migration for customers' orders MigrationOrder=Data migration for customers' orders
MigrationSupplierOrder=Data migration for suppliers' orders MigrationSupplierOrder=Data migration for suppliers' orders
MigrationProposal=Data migration for commercial proposals MigrationProposal=Data migration for commercial proposals

View File

@ -137,6 +137,7 @@ InstallChoiceSuggested=<b>Choix suggéré par l'installeur</b>.
######### #########
# upgrade # upgrade
######### #########
MigrationFixData=Correction de données dénormalisées
MigrationOrder=Migration de données sur les commandes clients MigrationOrder=Migration de données sur les commandes clients
MigrationSupplierOrder=Migration de données sur les commandes fournisseurs MigrationSupplierOrder=Migration de données sur les commandes fournisseurs
MigrationProposal=Migration de données sur les propositions commerciales MigrationProposal=Migration de données sur les propositions commerciales

View File

@ -47,21 +47,21 @@ class DoliDb
var $forcecollate='latin1_swedish_ci'; var $forcecollate='latin1_swedish_ci';
//! Version min database //! Version min database
var $versionmin=array(2000); var $versionmin=array(2000);
//! Resultset de la derni<EFBFBD>re requete //! Resultset de la derniere requete
var $results; var $results;
//! 1 si connect<EFBFBD>, 0 sinon //! 1 si connecte, 0 sinon
var $connected; var $connected;
//! 1 si base s<EFBFBD>lectionn<EFBFBD>, 0 sinon //! 1 si base selectionne, 0 sinon
var $database_selected; var $database_selected;
//! Nom base s<EFBFBD>lectionn<EFBFBD>e //! Nom base selectionnee
var $database_name; var $database_name;
//! Nom user base //! Nom user base
var $database_user; var $database_user;
//! 1 si une transaction est en cours, 0 sinon //! 1 si une transaction est en cours, 0 sinon
var $transaction_opened; var $transaction_opened;
//! Derniere requete ex<EFBFBD>cut<EFBFBD>e //! Derniere requete executee
var $lastquery; var $lastquery;
//! Derniere requete ex<EFBFBD>cut<EFBFBD>e avec echec //! Derniere requete executee avec echec
var $lastqueryerror; var $lastqueryerror;
//! Message erreur mysql //! Message erreur mysql
var $lasterror; var $lasterror;
@ -73,14 +73,14 @@ class DoliDb
/** /**
\brief Ouverture d'une connexion vers le serveur et <EFBFBD>ventuellement une database. * \brief Ouverture d'une connexion vers le serveur et eventuellement une database.
\param type Type de base de donn<EFBFBD>es (mysql ou pgsql) * \param type Type de base de donnees (mysql ou pgsql)
\param host Addresse de la base de donn<EFBFBD>es * \param host Addresse de la base de donnees
\param user Nom de l'utilisateur autoris<EFBFBD> * \param user Nom de l'utilisateur autorise
\param pass Mot de passe * \param pass Mot de passe
\param name Nom de la database * \param name Nom de la database
\param port Port of database server * \param port Port of database server
\return int 1 en cas de succ<EFBFBD>s, 0 sinon * \return int 1 en cas de succes, 0 sinon
*/ */
function DoliDb($type='mssql', $host, $user, $pass, $name='', $port=0) function DoliDb($type='mssql', $host, $user, $pass, $name='', $port=0)
{ {

View File

@ -289,3 +289,7 @@ insert into llx_action_def (rowid,code,titre,description,objet_type) values (4,'
insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 51, 5, '19','0','VAT standard rate',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 51, 5, '19','0','VAT standard rate',1);
insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 52, 5, '7','0','VAT reduced rate', 1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 52, 5, '7','0','VAT reduced rate', 1);
insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 53, 5, '0','0','VAT Rate 0', 1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 53, 5, '0','0','VAT Rate 0', 1);
-- Add rule to avoid duplicate use of discount
update llx_facturedet set fk_remise_except = null where fk_remise_except = 0;
ALTER TABLE llx_facturedet ADD UNIQUE INDEX uk_fk_remise_except (fk_remise_except);

View File

@ -19,8 +19,9 @@
-- =================================================================== -- ===================================================================
-- Supprimme orhpelins pour permettre montée de la clé -- Supprimme orhpelins pour permettre mont<EFBFBD>e de la cl<63>
-- V4 DELETE llx_facturedet FROM llx_facturedet LEFT JOIN llx_facture ON llx_facturedet.fk_facture = llx_facture.rowid WHERE llx_facture.rowid IS NULL; -- V4 DELETE llx_facturedet FROM llx_facturedet LEFT JOIN llx_facture ON llx_facturedet.fk_facture = llx_facture.rowid WHERE llx_facture.rowid IS NULL;
ALTER TABLE llx_facturedet ADD INDEX idx_facturedet_fk_facture (fk_facture); ALTER TABLE llx_facturedet ADD INDEX idx_facturedet_fk_facture (fk_facture);
ALTER TABLE llx_facturedet ADD UNIQUE INDEX uk_fk_remise_except (fk_remise_except);
ALTER TABLE llx_facturedet ADD CONSTRAINT fk_facturedet_fk_facture FOREIGN KEY (fk_facture) REFERENCES llx_facture (rowid); ALTER TABLE llx_facturedet ADD CONSTRAINT fk_facturedet_fk_facture FOREIGN KEY (fk_facture) REFERENCES llx_facture (rowid);