2
0
forked from Wavyzz/dolibarr

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
print '<table class="noborder" width="100%">';
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 '</table>';
@@ -83,7 +84,8 @@ print "<br>\n";
// Database
print '<table class="noborder" width="100%">';
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 '<br>';

View File

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

View File

@@ -152,7 +152,7 @@ class FactureFournisseur extends Facture
if ($resql)
{
$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 .= ' VALUES ('.$this->id.');';
@@ -894,6 +894,15 @@ class FactureFournisseur extends Facture
$object->close_code = '';
$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
$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
$tvaligne=$com->lignes[$i]->total_tva;
$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;
$nexY+=2; // Passe espace entre les lignes

View File

@@ -284,7 +284,7 @@ class pdf_crabe extends ModelePDFFactures
$tvaligne=$fac->lignes[$i]->total_tva;
if ($fac->remise_percent) $tvaligne-=($tvaligne*$fac->remise_percent)/100;
$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;
$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;
if ($propale->remise_percent) $tvaligne-=($tvaligne*$propale->remise_percent)/100;
$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;
$nexY+=2; // Passe espace entre les lignes

View File

@@ -279,7 +279,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
$tvaligne=$com->lignes[$i]->total_tva;
if ($com->remise_percent) $tvaligne-=($tvaligne*$com->remise_percent)/100;
$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;
$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_restore_missing_links($db,$langs,$conf);
// On commit dans tous les cas.
// 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
On recherche facture incorrecte:

View File

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

View File

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

View File

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