diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 01ea8d93de3..df5e78b8712 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -2989,11 +2989,11 @@ else if ($id > 0 || ! empty($ref))
$resteapayeraffiche = $resteapayer;
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { // Never use this
- $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
- $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ $filterabsolutediscount = "fk_facture IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ $filtercreditnote = "fk_facture IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
- $filterabsolutediscount = "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%'))";
- $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
+ $filterabsolutediscount = "fk_facture IS NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
+ $filtercreditnote = "fk_facture IS NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
}
$absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
index 9d7ae9d0998..c629c6021b4 100644
--- a/htdocs/core/class/commoninvoice.class.php
+++ b/htdocs/core/class/commoninvoice.class.php
@@ -180,12 +180,6 @@ abstract class CommonInvoice extends CommonObject
*/
function getSumCreditNotesUsed($multicurrency=0)
{
- if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier')
- {
- // TODO
- return 0;
- }
-
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discountstatic=new DiscountAbsolute($this->db);
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 0dd9a245136..a320d102c4e 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -3955,7 +3955,7 @@ abstract class CommonObject
$discount=new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
$this->tpl['description'] = $langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0));
- }
+ } // TODO handle (EXCESS PAID)
else
{
$this->tpl['description'] = dol_trunc($line->desc,60);
diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php
index 37dedea8b6b..c8aa11996b6 100644
--- a/htdocs/core/class/discount.class.php
+++ b/htdocs/core/class/discount.class.php
@@ -60,16 +60,17 @@ class DiscountAbsolute
/**
* Load object from database into memory
*
- * @param int $rowid id discount to load
- * @param int $fk_facture_source fk_facture_source
- * @return int <0 if KO, =0 if not found, >0 if OK
+ * @param int $rowid id discount to load
+ * @param int $fk_facture_source fk_facture_source
+ * @param int $fk_invoice_supplier_source fk_invoice_supplier_source
+ * @return int <0 if KO, =0 if not found, >0 if OK
*/
- function fetch($rowid, $fk_facture_source=0)
+ function fetch($rowid, $fk_facture_source=0, $fk_invoice_supplier_source=0)
{
global $conf;
// Check parameters
- if (! $rowid && ! $fk_facture_source)
+ if (! $rowid && ! $fk_facture_source && ! $fk_invoice_supplier_source)
{
$this->error='ErrorBadParameters';
return -1;
@@ -79,14 +80,16 @@ class DiscountAbsolute
$sql.= " sr.fk_user,";
$sql.= " sr.amount_ht, sr.amount_tva, sr.amount_ttc, sr.tva_tx,";
$sql.= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc,";
- $sql.= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.description,";
+ $sql.= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.fk_invoice_supplier_line, sr.fk_invoice_supplier, sr.fk_invoice_supplier_source, sr.description,";
$sql.= " sr.datec,";
- $sql.= " f.facnumber as ref_facture_source";
+ $sql.= " f.facnumber as ref_facture_source, fsup.facnumber as ref_invoice_supplier_source";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as sr";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON sr.fk_facture_source = f.rowid";
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as fsup ON sr.fk_invoice_supplier_source = fsup.rowid";
$sql.= " WHERE sr.entity = " . $conf->entity;
if ($rowid) $sql.= " AND sr.rowid=".$rowid;
if ($fk_facture_source) $sql.= " AND sr.fk_facture_source=".$fk_facture_source;
+ if ($fk_invoice_supplier_source) $sql.= " AND sr.fk_invoice_supplier_source=".$fk_invoice_supplier_source;
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
$resql = $this->db->query($sql);
@@ -113,6 +116,10 @@ class DiscountAbsolute
$this->fk_facture = $obj->fk_facture;
$this->fk_facture_source = $obj->fk_facture_source; // Id avoir source
$this->ref_facture_source = $obj->ref_facture_source; // Ref avoir source
+ $this->fk_invoice_supplier_line = $obj->fk_invoice_supplier_line;
+ $this->fk_invoice_supplier = $obj->fk_invoice_supplier;
+ $this->fk_invoice_supplier_source = $obj->fk_invoice_supplier_source; // Id avoir source
+ $this->ref_invoice_supplier_source = $obj->ref_invoice_supplier_source; // Ref avoir source
$this->description = $obj->description;
$this->datec = $this->db->jdate($obj->datec);
@@ -161,11 +168,12 @@ class DiscountAbsolute
$sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_except";
$sql.= " (entity, datec, fk_soc, fk_user, description,";
$sql.= " amount_ht, amount_tva, amount_ttc, tva_tx,";
- $sql.= " fk_facture_source";
+ $sql.= " fk_facture_source, fk_invoice_supplier_source";
$sql.= ")";
$sql.= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec!=''?$this->datec:dol_now())."', ".$this->fk_soc.", ".$user->id.", '".$this->db->escape($this->description)."',";
$sql.= " ".$this->amount_ht.", ".$this->amount_tva.", ".$this->amount_ttc.", ".$this->tva_tx.",";
- $sql.= " ".($this->fk_facture_source ? "'".$this->db->escape($this->fk_facture_source)."'":"null");
+ $sql.= " ".($this->fk_facture_source ? "'".$this->db->escape($this->fk_facture_source)."'":"null").",";
+ $sql.= " ".($this->fk_invoice_supplier_source ? "'".$this->db->escape($this->fk_invoice_supplier_source)."'":"null");
$sql.= ")";
dol_syslog(get_class($this)."::create", LOG_DEBUG);
@@ -194,7 +202,7 @@ class DiscountAbsolute
global $conf, $langs;
// Check if we can remove the discount
- if ($this->fk_facture_source)
+ if ($this->fk_facture_source) // TODO check
{
$sql="SELECT COUNT(rowid) as nb";
$sql.=" FROM ".MAIN_DB_PREFIX."societe_remise_except";
@@ -278,9 +286,10 @@ class DiscountAbsolute
*
* @param int $rowidline Invoice line id (To use discount into invoice lines)
* @param int $rowidinvoice Invoice id (To use discount as a credit note to reduc payment of invoice)
+ * @param string $mode 'supplier' to link to supplier invoice, 'customer' instead
* @return int <0 if KO, >0 if OK
*/
- function link_to_invoice($rowidline,$rowidinvoice)
+ function link_to_invoice($rowidline,$rowidinvoice,$mode='customer')
{
// Check parameters
if (! $rowidline && ! $rowidinvoice)
@@ -295,16 +304,26 @@ class DiscountAbsolute
}
$sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except";
- if ($rowidline) $sql.=" SET fk_facture_line = ".$rowidline;
- if ($rowidinvoice) $sql.=" SET fk_facture = ".$rowidinvoice;
+ if($mode == 'supplier') {
+ if ($rowidline) $sql.=" SET fk_invoice_supplier_line = ".$rowidline;
+ if ($rowidinvoice) $sql.=" SET fk_invoice_supplier = ".$rowidinvoice;
+ } else {
+ if ($rowidline) $sql.=" SET fk_facture_line = ".$rowidline;
+ if ($rowidinvoice) $sql.=" SET fk_facture = ".$rowidinvoice;
+ }
$sql.=" WHERE rowid = ".$this->id;
dol_syslog(get_class($this)."::link_to_invoice", LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
- $this->fk_facture_line=$rowidline;
- $this->fk_facture=$rowidinvoice;
+ if($mode == 'supplier') {
+ $this->fk_invoice_supplier_line=$rowidline;
+ $this->fk_invoice_supplier=$rowidinvoice;
+ } else {
+ $this->fk_facture_line=$rowidline;
+ $this->fk_facture=$rowidinvoice;
+ }
return 1;
}
else
@@ -319,12 +338,17 @@ class DiscountAbsolute
* Link the discount to a particular invoice line or a particular invoice.
* Do not call this if discount is linked to a reconcialiated invoice
*
+ * @param string $mode 'supplier' to unlink a supplier invoice, 'customer' instead
* @return int <0 if KO, >0 if OK
*/
- function unlink_invoice()
+ function unlink_invoice($mode = 'customer')
{
$sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except";
- $sql.=" SET fk_facture_line = NULL, fk_facture = NULL";
+ if($mode = 'supplier') {
+ $sql.=" SET fk_invoice_supplier_line = NULL, fk_invoice_supplier = NULL";
+ } else {
+ $sql.=" SET fk_facture_line = NULL, fk_facture = NULL";
+ }
$sql.=" WHERE rowid = ".$this->id;
dol_syslog(get_class($this)."::unlink_invoice", LOG_DEBUG);
@@ -359,8 +383,8 @@ class DiscountAbsolute
//$sql = "SELECT rc.amount_ttc as amount";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc";
$sql.= " WHERE rc.entity = " . $conf->entity;
- if ($mode != 'supplier') $sql.= " AND (rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available
- else $sql.= " AND (rc.fk_suppler_invoice IS NULL AND rc.fk_supplier_invoice IS NULL)"; // Available
+ if ($mode == 'supplier') $sql.= " AND (rc.fk_facture_source IS NULL AND rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available
+ else $sql.= " AND (rc.fk_invoice_supplier_source IS NULL AND rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL)"; // Available
if (is_object($company)) $sql.= " AND rc.fk_soc = ".$company->id;
if (is_object($user)) $sql.= " AND rc.fk_user = ".$user->id;
if ($filter) $sql.=' AND ('.$filter.')';
@@ -452,7 +476,7 @@ class DiscountAbsolute
$sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount';
$sql.= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture_fourn as f';
$sql.= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = '.$invoice->id;
- $sql.= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess received
+ $sql.= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess paid
}
else
{
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 4e8f67d6552..8a1cc6ac33c 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -1236,6 +1236,7 @@ class Form
if (preg_match('/\(CREDIT_NOTE\)/', $desc)) $desc=preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc);
if (preg_match('/\(DEPOSIT\)/', $desc)) $desc=preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc);
if (preg_match('/\(EXCESS RECEIVED\)/', $desc)) $desc=preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc);
+ // TODO handle (EXCESS PAID)
$selectstring='';
if ($selected > 0 && $selected == $obj->rowid) $selectstring=' selected';
@@ -4219,9 +4220,10 @@ class Form
* @param int $maxvalue Max value for lines that can be selected
* @param string $more More string to add
* @param int $hidelist 1=Hide list
+ * @param string $mode 'supplier' to list available discounts for suppliers, 'customer' instead
* @return void
*/
- function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0)
+ function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0, $mode='customer')
{
global $conf,$langs;
if ($htmlname != "none")
@@ -4230,28 +4232,51 @@ class Form
print '';
print '';
print '
';
- if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
- {
- if (! $filter || $filter=="fk_facture_source IS NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); // If we want deposit to be substracted to payments only and not to total of final invoice
- else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
- }
- else
- {
- if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));
- else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
+ if($mode == 'supplier') {
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
+ {
+ if (! $filter || $filter=="fk_invoice_supplier IS NOT NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); // If we want deposit to be substracted to payments only and not to total of final invoice
+ else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
+ }
+ else
+ {
+ if (! $filter || $filter=="fk_invoice_supplier IS NOT NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));
+ else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
+ }
+ } else {
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
+ {
+ if (! $filter || $filter=="fk_facture IS NOT NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); // If we want deposit to be substracted to payments only and not to total of final invoice
+ else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
+ }
+ else
+ {
+ if (! $filter || $filter=="fk_facture IS NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));
+ else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
+ }
}
if (empty($hidelist)) print ': ';
print '
';
if (empty($hidelist))
{
print '
';
- $newfilter='fk_facture IS NULL AND fk_facture_line IS NULL'; // Remises disponibles
+ if($mode == 'supplier') {
+ $newfilter = 'fk_facture_source IS NULL AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Exclude customer discounts
+ $newfilter.= ' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Supplier discounts available
+ } else {
+ $newfilter = 'fk_invoice_supplier_source IS NULL AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Exclude supplier discounts
+ $newfilter.= ' AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Customer discounts available
+ }
if ($filter) $newfilter.=' AND ('.$filter.')';
$nbqualifiedlines=$this->select_remises($selected,$htmlname,$newfilter,$socid,$maxvalue);
if ($nbqualifiedlines > 0)
{
print ' ';
}
print '
';
diff --git a/htdocs/core/lib/doc.lib.php b/htdocs/core/lib/doc.lib.php
index 99e576ad057..20eaa9a71f7 100644
--- a/htdocs/core/lib/doc.lib.php
+++ b/htdocs/core/lib/doc.lib.php
@@ -88,7 +88,7 @@ function doc_getlinedesc($line,$outputlangs,$hideref=0,$hidedesc=0,$issupplierli
$discount=new DiscountAbsolute($db);
$discount->fetch($line->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived",$discount->ref_facture_source);
- }
+ } // TODO handle (EXCESS PAID)
else
{
if ($idprod)
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 377f2215b6d..0fb649506cb 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -1251,7 +1251,7 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
$discount=new DiscountAbsolute($db);
$discount->fetch($object->lines[$i]->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived",$discount->ref_facture_source);
- }
+ } // TODO handle (EXCESS PAID)
else
{
if ($idprod)
diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php
index 8d5b13ece7c..bc5d950ab8e 100644
--- a/htdocs/core/tpl/objectline_view.tpl.php
+++ b/htdocs/core/tpl/objectline_view.tpl.php
@@ -72,7 +72,7 @@ if (empty($outputalsopricetotalwithtax)) $outputalsopricetotalwithtax=0;
$txt='';
print img_object($langs->trans("ShowReduc"),'reduc').' ';
if ($line->description == '(DEPOSIT)') $txt=$langs->trans("Deposit");
- elseif ($line->description == '(EXCESS RECEIVED)') $txt=$langs->trans("ExcessReceived");
+ elseif ($line->description == '(EXCESS RECEIVED)') $txt=$langs->trans("ExcessReceived"); // TODO handle (EXCESS PAID)
//else $txt=$langs->trans("Discount");
print $txt;
?>
@@ -100,7 +100,7 @@ if (empty($outputalsopricetotalwithtax)) $outputalsopricetotalwithtax=0;
$discount=new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
echo ($txt?' - ':'').$langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0));
- }
+ } // TODO handle (EXCESS PAID)
else
{
echo ($txt?' - ':'').dol_htmlentitiesbr($line->description);
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index 444eb5d200a..b23c9af5fce 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -897,6 +897,106 @@ class FactureFournisseur extends CommonInvoice
}
}
+ /**
+ * Add a discount line into an invoice (as an invoice line) using an existing absolute discount (Consume the discount)
+ *
+ * @param int $idremise Id of absolute discount
+ * @return int >0 if OK, <0 if KO
+ */
+ function insert_discount($idremise)
+ {
+ global $langs;
+
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
+ include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
+
+ $this->db->begin();
+
+ $remise=new DiscountAbsolute($this->db);
+ $result=$remise->fetch($idremise);
+
+ if ($result > 0)
+ {
+ if ($remise->fk_invoice_supplier) // Protection against multiple submission
+ {
+ $this->error=$langs->trans("ErrorDiscountAlreadyUsed");
+ $this->db->rollback();
+ return -5;
+ }
+
+ $facligne=new SupplierInvoiceLine($this->db);
+ $facligne->fk_facture=$this->id;
+ $facligne->fk_remise_except=$remise->id;
+ $facligne->desc=$remise->description; // Description ligne
+ $facligne->vat_src_code=$remise->vat_src_code;
+ $facligne->tva_tx=$remise->tva_tx;
+ $facligne->subprice = -$remise->amount_ht;
+ $facligne->fk_product=0; // Id produit predefini
+ $facligne->qty=1;
+ $facligne->remise_percent=0;
+ $facligne->rang=-1;
+ $facligne->info_bits=2;
+
+ // Get buy/cost price of invoice that is source of discount
+ if ($remise->fk_invoice_supplier_source > 0)
+ {
+ $srcinvoice=new FactureFournisseur($this->db);
+ $srcinvoice->fetch($remise->fk_invoice_supplier_source);
+ $totalcostpriceofinvoice=0;
+ include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; // TODO Move this into commonobject
+ $formmargin=new FormMargin($this->db);
+ $arraytmp=$formmargin->getMarginInfosArray($srcinvoice, false);
+ $facligne->pa_ht = $arraytmp['pa_total'];
+ }
+
+ $facligne->total_ht = -$remise->amount_ht;
+ $facligne->total_tva = -$remise->amount_tva;
+ $facligne->total_ttc = -$remise->amount_ttc;
+
+ $facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
+ $facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht;
+ $facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva;
+ $facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc;
+
+ $lineid=$facligne->insert();
+ if ($lineid > 0)
+ {
+ $result=$this->update_price(1);
+ if ($result > 0)
+ {
+ // Create link between discount and invoice line
+ $result=$remise->link_to_invoice($lineid,0,'supplier');
+ if ($result < 0)
+ {
+ $this->error=$remise->error;
+ $this->db->rollback();
+ return -4;
+ }
+
+ $this->db->commit();
+ return 1;
+ }
+ else
+ {
+ $this->error=$facligne->error;
+ $this->db->rollback();
+ return -1;
+ }
+ }
+ else
+ {
+ $this->error=$facligne->error;
+ $this->db->rollback();
+ return -2;
+ }
+ }
+ else
+ {
+ $this->db->rollback();
+ return -3;
+ }
+ }
+
/**
* Delete invoice from database
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index 761d5d591e3..a397d40d147 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -36,6 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
@@ -265,6 +266,14 @@ if (empty($reshook))
$action='';
}
}
+
+ // Delete link of credit note to invoice
+ else if ($action == 'unlinkdiscount' && $user->rights->facture->creer)
+ {
+ $discount = new DiscountAbsolute($db);
+ $result = $discount->fetch(GETPOST("discountid"));
+ $discount->unlink_invoice('supplier');
+ }
elseif ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer)
{
@@ -376,6 +385,186 @@ if (empty($reshook))
$result=$object->update($user);
if ($result < 0) dol_print_error($db,$object->error);
}
+ elseif ($action == "setabsolutediscount" && $user->rights->facture->creer)
+ {
+ // POST[remise_id] or POST[remise_id_for_payment]
+
+ // We use the credit to reduce amount of invoice
+ if (! empty($_POST["remise_id"])) {
+ $ret = $object->fetch($id);
+ if ($ret > 0) {
+ $result = $object->insert_discount($_POST["remise_id"]);
+ if ($result < 0) {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ } else {
+ dol_print_error($db, $object->error);
+ }
+ }
+ // We use the credit to reduce remain to pay
+ if (! empty($_POST["remise_id_for_payment"]))
+ {
+ require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
+ $discount = new DiscountAbsolute($db);
+ $discount->fetch($_POST["remise_id_for_payment"]);
+
+ //var_dump($object->getRemainToPay(0));
+ //var_dump($discount->amount_ttc);exit;
+ if ($discount->amount_ttc > $object->getRemainToPay(0))
+ {
+ // TODO Split the discount in 2 automatically
+ $error++;
+ setEventMessages($langs->trans("ErrorDiscountLargerThanRemainToPaySplitItBefore"), null, 'errors');
+ }
+
+ if (! $error)
+ {
+ $result = $discount->link_to_invoice(0, $id, 'supplier');
+ if ($result < 0) {
+ setEventMessages($discount->error, $discount->errors, 'errors');
+ }
+ }
+ }
+
+ if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+ {
+ $outputlangs = $langs;
+ $newlang = '';
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
+ if (! empty($newlang)) {
+ $outputlangs = new Translate("", $conf);
+ $outputlangs->setDefaultLang($newlang);
+ }
+ $ret = $object->fetch($id); // Reload to get new records
+
+ $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+ if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+ // Convertir en reduc
+ else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer)
+ {
+ $object->fetch($id);
+ $object->fetch_thirdparty();
+ //$object->fetch_lines(); // Already done into fetch
+
+ // Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
+ $discountcheck=new DiscountAbsolute($db);
+ $result=$discountcheck->fetch(0,0,$object->id);
+
+ $canconvert=0;
+ if ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc)
+ if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
+ if ($canconvert)
+ {
+ $db->begin();
+
+ $amount_ht = $amount_tva = $amount_ttc = array();
+
+ // Loop on each vat rate
+ $i = 0;
+ foreach ($object->lines as $line)
+ {
+ if ($line->product_type < 9 && $line->total_ht != 0) // Remove lines with product_type greater than or equal to 9
+ { // no need to create discount if amount is null
+ $amount_ht[$line->tva_tx] += $line->total_ht;
+ $amount_tva[$line->tva_tx] += $line->total_tva;
+ $amount_ttc[$line->tva_tx] += $line->total_ttc;
+ $i ++;
+ }
+ }
+
+ // Insert one discount by VAT rate category
+ $discount = new DiscountAbsolute($db);
+ if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE)
+ $discount->description = '(CREDIT_NOTE)';
+ elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT)
+ $discount->description = '(DEPOSIT)';
+ elseif ($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_SITUATION)
+ $discount->description = '(EXCESS PAID)';
+ else {
+ setEventMessages($langs->trans('CantConvertToReducAnInvoiceOfThisType'), null, 'errors');
+ }
+ $discount->fk_soc = $object->socid;
+ $discount->fk_invoice_supplier_source = $object->id;
+
+ $error = 0;
+
+ if ($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_SITUATION)
+ {
+ // If we're on a standard invoice, we have to get excess paid to create a discount in TTC without VAT
+
+ $sql = 'SELECT SUM(pf.amount) as total_paiements';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf, '.MAIN_DB_PREFIX.'paiementfourn as p';
+ $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN (' . getEntity('c_paiement') . ')';
+ $sql.= ' WHERE pf.fk_facturefourn = '.$object->id;
+ $sql.= ' AND pf.fk_paiementfourn = p.rowid';
+ $sql.= ' AND p.entity IN (' . getEntity('facture').')';
+ $sql.= ' ORDER BY p.datep, p.tms';
+
+ $resql = $db->query($sql);
+ if (! $resql) dol_print_error($db);
+
+ $res = $db->fetch_object($resql);
+ $total_paiements = $res->total_paiements;
+
+ $discount->amount_ht = $discount->amount_ttc = $total_paiements - $object->total_ttc;
+ $discount->amount_tva = 0;
+ $discount->tva_tx = 0;
+
+ $result = $discount->create($user);
+ if ($result < 0)
+ {
+ $error++;
+ }
+
+ }
+ if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT)
+ {
+ foreach ($amount_ht as $tva_tx => $xxx)
+ {
+ $discount->amount_ht = abs($amount_ht[$tva_tx]);
+ $discount->amount_tva = abs($amount_tva[$tva_tx]);
+ $discount->amount_ttc = abs($amount_ttc[$tva_tx]);
+ $discount->tva_tx = abs($tva_tx);
+
+ $result = $discount->create($user);
+ if ($result < 0)
+ {
+ $error++;
+ break;
+ }
+ }
+
+ }
+
+ if (empty($error))
+ {
+ if($object->type != FactureFournisseur::TYPE_DEPOSIT) {
+ // Classe facture
+ $result = $object->set_paid($user);
+ if ($result >= 0)
+ {
+ $db->commit();
+ }
+ else
+ {
+ setEventMessages($object->error, $object->errors, 'errors');
+ $db->rollback();
+ }
+ } else {
+ $db->commit();
+ }
+ }
+ else
+ {
+ setEventMessages($discount->error, $discount->errors, 'errors');
+ $db->rollback();
+ }
+ }
+ }
+
// Delete payment
elseif ($action == 'confirm_delete_paiement' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer)
@@ -464,6 +653,7 @@ if (empty($reshook))
// Credit note invoice
if ($_POST['type'] == FactureFournisseur::TYPE_CREDIT_NOTE)
{
+
$sourceinvoice = GETPOST('fac_avoir','int');
if (! ($sourceinvoice > 0) && empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE))
{
@@ -519,6 +709,10 @@ if (empty($reshook))
$id = $object->create($user);
+ if($id <= 0) {
+ $error++;
+ }
+
if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0)
{
$facture_source = new FactureFournisseur($db); // fetch origin object
@@ -677,7 +871,7 @@ if (empty($reshook))
}
$num=count($lines);
- for ($i = 0; $i < $num; $i++)
+ for ($i = 0; $i < $num; $i++) // TODO handle subprice < 0
{
$desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle);
$product_type=($lines[$i]->product_type?$lines[$i]->product_type:0);
@@ -1485,6 +1679,7 @@ if ($action == 'create')
if ($societe->id > 0)
{
+ $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 'supplier');
print $societe->getNomUrl(1);
print '';
}
@@ -1717,22 +1912,22 @@ if ($action == 'create')
print '';
- if ($socid > 0)
+ if ($societe->id > 0)
{
// Discounts for third party
print '