diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 9081659391b..5e7e64758b4 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -79,6 +79,33 @@ $NBLINES=4;
* Actions
*/
+// Validation
+if ($_GET['action'] == 'valid')
+{
+ $facture = new Facture($db);
+ $facture->fetch($_GET['facid']);
+
+ // On verifie signe facture
+ if ($facture->type == 2)
+ {
+ // Si avoir, le signe doit etre négatif
+ if ($facture->total_ht >= 0)
+ {
+ $mesg='
'.$langs->trans('Type').' ';
print '';
print '';
@@ -1062,13 +1136,16 @@ if ($_GET['action'] == 'create')
$desc=$html->textwithhelp($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1);
print $desc;
print ' ';
+
print '';
print ' ';
print ' ';
$text=$langs->trans("InvoiceReplacementAsk").' ';
- $text.='';
+ $text.='';
if ($options)
{
$text.=' ';
@@ -1082,10 +1159,29 @@ if ($_GET['action'] == 'create')
$desc=$html->textwithhelp($text,$langs->transnoentities("InvoiceReplacementDesc"),1);
print $desc;
print ' ';
+
print '';
- print ' ';
+ print ' ';
print ' ';
- $desc=$html->textwithhelp($langs->trans("InvoiceAvoirAsk").' ('.$langs->trans("FeatureNotYetAvailable").')',$langs->transnoentities("InvoiceAvoirDesc"),1);
+ $text=$langs->transnoentities("InvoiceAvoirAsk").' ';
+// $text.=' ';
+ $text.='';
+ if ($options)
+ {
+ $text.=' ';
+ $text.=$optionsav;
+ }
+ else
+ {
+ $text.=''.$langs->trans("NoInvoiceToCorrect").' ';
+ }
+ $text.=' ';
+ $desc=$html->textwithhelp($text,$langs->transnoentities("InvoiceAvoirDesc"),1);
+ //.' ('.$langs->trans("FeatureNotYetAvailable").')',$langs->transnoentities("InvoiceAvoirDesc"),1);
print $desc;
print ' ';
print '
';
@@ -1642,6 +1738,12 @@ else
$facreplaced->fetch($fac->fk_facture_source);
print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')';
}
+ if ($fac->type == 2)
+ {
+ $facreplaced=new Facture($db);
+ $facreplaced->fetch($fac->fk_facture_source);
+ print ' ('.$langs->transnoentities("CorrectInvoice",$facreplaced->getNomUrl(1)).')';
+ }
$facidnext=$fac->getIdReplacingInvoice();
if ($facidnext > 0)
{
diff --git a/htdocs/facture.class.php b/htdocs/facture.class.php
index 9e3d6732ca5..3f21af6477c 100644
--- a/htdocs/facture.class.php
+++ b/htdocs/facture.class.php
@@ -50,13 +50,14 @@ class Facture extends CommonObject
var $id;
var $socid; // Id client
- var $client; // Objet societe client (à charger par fetch_client)
+ var $client; // Objet societe client (à charger par fetch_client)
var $number;
var $author;
var $date;
var $ref;
var $ref_client;
+ var $type; // 0=Facture normale, 1=Facture remplacement, 2=Facture avoir, 3=Facture récurrente
var $amount;
var $remise;
var $tva;
@@ -2231,6 +2232,46 @@ class Facture extends CommonObject
}
}
+
+ /**
+ * \brief Renvoi liste des factures qualifiables pour avoir
+ * Statut validee + pas deja remplacées
+ * \param socid Id societe
+ * \return array Tableau des factures ($id => $ref)
+ */
+ function list_avoir_invoices($socid=0)
+ {
+ global $conf;
+
+ $return = array();
+
+ $sql = "SELECT f.rowid as rowid, f.facnumber";
+ $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
+ $sql.= " WHERE f.fk_statut >= 1 AND f.paye = 0";
+ if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
+ $sql.= " ORDER BY f.facnumber";
+
+ dolibarr_syslog("Facture.class::list_avoir_invoices sql=$sql");
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ while ($obj=$this->db->fetch_object($resql))
+ {
+ $return[$obj->rowid]=$obj->facnumber;
+ }
+
+ return $return;
+ }
+ else
+ {
+ $this->error=$this->db->error();
+ dolibarr_syslog("Facture.class::list_avoir_invoices ".$this->error);
+ return -1;
+ }
+ }
+
+
/**
* \brief Créé une demande de prélèvement
* \param user Utilisateur créant la demande
diff --git a/htdocs/includes/modules/facture/pdf_crabe.modules.php b/htdocs/includes/modules/facture/pdf_crabe.modules.php
index a62a90ac97e..2017cc4a183 100644
--- a/htdocs/includes/modules/facture/pdf_crabe.modules.php
+++ b/htdocs/includes/modules/facture/pdf_crabe.modules.php
@@ -496,7 +496,7 @@ class pdf_crabe extends ModelePDFFactures
/*
* Conditions de règlements
*/
- if ($object->cond_reglement_code || $object->cond_reglement)
+ if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement))
{
$pdf->SetFont('Arial','B',8);
$pdf->SetXY($this->marge_gauche, $posy);
@@ -514,7 +514,7 @@ class pdf_crabe extends ModelePDFFactures
/*
* Check si absence mode règlement
*/
- if (! $conf->global->FACTURE_CHQ_NUMBER && ! $conf->global->FACTURE_RIB_NUMBER)
+ if ($object->type != 2 && (! $conf->global->FACTURE_CHQ_NUMBER && ! $conf->global->FACTURE_RIB_NUMBER))
{
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->SetTextColor(200,0,0);
@@ -528,7 +528,7 @@ class pdf_crabe extends ModelePDFFactures
/*
* Propose mode règlement par CHQ
*/
- if (! $object->mode_reglement_code || $object->mode_reglement_code == 'CHQ')
+ if ($object->type != 2 && (! $object->mode_reglement_code || $object->mode_reglement_code == 'CHQ'))
{
// Si mode reglement non force ou si force a CHQ
if ($conf->global->FACTURE_CHQ_NUMBER)
@@ -568,7 +568,7 @@ class pdf_crabe extends ModelePDFFactures
/*
* Propose mode règlement par RIB
*/
- if (! $object->mode_reglement_code || $object->mode_reglement_code == 'VIR')
+ if ($object->type != 2 && (! $object->mode_reglement_code || $object->mode_reglement_code == 'VIR'))
{
// Si mode reglement non force ou si force a VIR
if ($conf->global->FACTURE_RIB_NUMBER)
@@ -651,7 +651,7 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->trans("TotalHT"), 0, 'L', 1);
$pdf->SetXY ($col2x, $tab2_top + 0);
- $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ht + $object->remise), 0, 'R', 1);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(abs($object->total_ht + $object->remise)), 0, 'R', 1);
// Remise globale
if ($object->remise > 0)
@@ -666,7 +666,7 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->trans("WithDiscountTotalHT"), 0, 'L', 1);
$pdf->SetXY ($col2x, $tab2_top + $tab2_hl * 2);
- $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ht), 0, 'R', 1);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(abs($object->total_ht)), 0, 'R', 1);
$index = 2;
}
@@ -689,7 +689,7 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->trans("TotalVAT").' '.abs($tvakey).'%'.$tvacompl, 0, 'L', 1);
$pdf->SetXY ($col2x, $tab2_top + $tab2_hl * $index);
- $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval * (float)$tvakey / 100 ), 0, 'R', 1);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(abs($tvaval * (float)$tvakey / 100 )), 0, 'R', 1);
}
}
if (! $this->atleastoneratenotnull)
@@ -699,7 +699,7 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->trans("TotalVAT"), 0, 'L', 1);
$pdf->SetXY ($col2x, $tab2_top + $tab2_hl * $index);
- $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', 1);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(abs($object->total_tva)), 0, 'R', 1);
}
$useborder=0;
@@ -708,10 +708,12 @@ class pdf_crabe extends ModelePDFFactures
$pdf->SetXY ($col1x, $tab2_top + $tab2_hl * $index);
$pdf->SetTextColor(0,0,60);
$pdf->SetFillColor(224,224,224);
- $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->trans("TotalTTC"), $useborder, 'L', 1);
+ $text=$outputlangs->trans("TotalTTC");
+ if ($object->type == 2) $text=$outputlangs->trans("TotalTTCToYourCredit");
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $text, $useborder, 'L', 1);
$pdf->SetXY ($col2x, $tab2_top + $tab2_hl * $index);
- $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc), $useborder, 'R', 1);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(abs($object->total_ttc)), $useborder, 'R', 1);
$pdf->SetTextColor(0,0,0);
if ($deja_regle > 0)
@@ -736,7 +738,7 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->trans("EscompteOffered"), $useborder, 'L', 1);
$pdf->SetXY ($col2x, $tab2_top + $tab2_hl * $index);
- $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle), $useborder, 'R', 1);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(abs($object->total_ttc - $deja_regle)), $useborder, 'R', 1);
}
$index++;
@@ -746,7 +748,7 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->trans("RemainderToPay"), $useborder, 'L', 1);
$pdf->SetXY ($col2x, $tab2_top + $tab2_hl * $index);
- $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', 1);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(abs($resteapayer)), $useborder, 'R', 1);
// Fin
$pdf->SetFont('Arial','', 9);
diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
index 5ccf5b9ca4d..1f199df3143 100644
--- a/htdocs/langs/en_US/bills.lang
+++ b/htdocs/langs/en_US/bills.lang
@@ -15,11 +15,13 @@ InvoiceReplacement=Replacement invoice. Must replace invoice with reference
InvoiceReplacementAsk=Replacement invoice for invoice
InvoiceReplacementDesc=Replacement invoice is used to cancel and replace completely an invoice with no paiement already recevided. Reference of canceled invoice is required.
InvoiceAvoir=Avoir invoice
-InvoiceAvoirAsk=Avoir invoice
+InvoiceAvoirAsk=Avoir invoice to correct invoice
InvoiceAvoirDesc=La facture d'avoir est une facture négative destinée à compenser une facture comportant un montant supérieur à ce qui a été ou sera réellement payé (toutes causes possibles).
ReplaceInvoice=Replace invoice %s
ReplacedByInvoice=Replaced by invoice %s
+CorrectInvoice=Correct invoice %s
NoReplacableInvoice=No replacable invoices
+NoInvoiceToCorrect=No invoice to correct
CardBill=Invoice card
Invoice=Invoice
Invoices=Invoices
@@ -58,6 +60,7 @@ DoPayment=Do payment
VAT=VAT
VATRate=VAT Rate
Amount=Amount
+TotalTTCToYourCredit=Total TTC to your credit
BillStatus=Invoice status
BillStatusDraft=Draft (need to be validated)
BillStatusPayed=Payed
@@ -82,6 +85,8 @@ ErrorCreateBankAccount=Creat a bank account then go to Setup panel of Invoice mo
ErrorBillNotFound=Invoice %s does not exists
ErrorInvoiceAlreadyReplaced=Error, invoice %s has already been replaced by invoice %s
ErrorDiscountAlreadyUsed=Error, discount already used
+ErrorInvoiceAvoirMustBeNegative=Error, correct invoice must have a negative amount
+ErrorInvoiceOfThisTypeMustBePositive=Error, this type of invoice must have a positive amount
BillFrom=From
BillTo=Bill to
ActionsOnBill=Actions on invoice
diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang
index 08ebda4a802..4275687d77a 100644
--- a/htdocs/langs/fr_FR/bills.lang
+++ b/htdocs/langs/fr_FR/bills.lang
@@ -15,11 +15,13 @@ InvoiceReplacement=Facture de remplacement
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. La référence de la facture qui doit être annulée est obligatoire.
InvoiceAvoir=Facture avoir
-InvoiceAvoirAsk=Facture avoir
+InvoiceAvoirAsk=Facture avoir pour correction de la facture
InvoiceAvoirDesc=La facture d'avoir est une facture négative destinée à compenser une facture comportant un montant supérieur à ce qui a été ou sera réellement payé (toutes causes possibles).
ReplaceInvoice=Remplace la facture %s
ReplacedByInvoice=Remplacée par la facture %s
+CorrectInvoice=Corrige facture %s
NoReplacableInvoice=Pas de factures remplacables
+NoInvoiceToCorrect=Pas de factures à corriger
CardBill=Fiche facture
Invoice=Facture
Invoices=Factures
@@ -58,6 +60,7 @@ DoPayment=
VAT=TVA
VATRate=Taux TVA
Amount=Montant
+TotalTTCToYourCredit=Total TTC à votre crédit
BillStatus=État de la facture
BillStatusDraft=Brouillon (à valider)
BillStatusPayed=Payée
@@ -82,6 +85,8 @@ ErrorCreateBankAccount=Cr
ErrorBillNotFound=Facture %s inexistante
ErrorInvoiceAlreadyReplaced=Erreur, la facture %s a déjà été remplacée par la facture %s
ErrorDiscountAlreadyUsed=Erreur, la remise a déjà été attribuée
+ErrorInvoiceAvoirMustBeNegative=Erreur, une facture de type Avoir doit avoir un montant négatif
+ErrorInvoiceOfThisTypeMustBePositive=Erreur, une facture de ce type doit avoir un montant positif
BillFrom=Émetteur
BillTo=Adressé à
ActionsOnBill=Actions sur la facture