';
- 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(! empty($discount_type)) {
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
+ {
+ if (! $filter || $filter=="fk_invoice_supplier_source IS NULL") $translationKey = 'HasAbsoluteDiscountFromSupplier'; // If we want deposit to be substracted to payments only and not to total of final invoice
+ else $translationKey = 'HasCreditNoteFromSupplier';
+ }
+ else
+ {
+ if (! $filter || $filter=="fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')") $translationKey = 'HasAbsoluteDiscountFromSupplier';
+ else $translationKey = 'HasCreditNoteFromSupplier';
+ }
+ } else {
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
+ {
+ if (! $filter || $filter=="fk_facture_source IS NULL") $translationKey = 'CompanyHasAbsoluteDiscount'; // If we want deposit to be substracted to payments only and not to total of final invoice
+ else $translationKey = 'CompanyHasCreditNote';
+ }
+ else
+ {
+ if (! $filter || $filter=="fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')") $translationKey = 'CompanyHasAbsoluteDiscount';
+ else $translationKey = 'CompanyHasCreditNote';
+ }
}
+ print $langs->trans($translationKey,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
+ $newfilter = 'discount_type='.intval($discount_type);
+ if(! empty($discount_type)) {
+ $newfilter.= ' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Supplier discounts available
+ } else {
+ $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..ae8410bd188 100644
--- a/htdocs/core/lib/doc.lib.php
+++ b/htdocs/core/lib/doc.lib.php
@@ -73,13 +73,15 @@ function doc_getlinedesc($line,$outputlangs,$hideref=0,$hidedesc=0,$issupplierli
{
$discount=new DiscountAbsolute($db);
$discount->fetch($line->fk_remise_except);
- $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$discount->ref_facture_source);
+ $sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
+ $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$sourceref);
}
elseif ($desc == '(DEPOSIT)' && $line->fk_remise_except)
{
$discount=new DiscountAbsolute($db);
$discount->fetch($line->fk_remise_except);
- $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$discount->ref_facture_source);
+ $sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
+ $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$sourceref);
// Add date of deposit
if (! empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) $libelleproduitservice.=' ('.dol_print_date($discount->datec,'day','',$outputlangs).')';
}
@@ -89,6 +91,12 @@ function doc_getlinedesc($line,$outputlangs,$hideref=0,$hidedesc=0,$issupplierli
$discount->fetch($line->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived",$discount->ref_facture_source);
}
+ elseif ($desc == '(EXCESS PAID)' && $line->fk_remise_except)
+ {
+ $discount=new DiscountAbsolute($db);
+ $discount->fetch($line->fk_remise_except);
+ $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid",$discount->ref_invoice_supplier_source);
+ }
else
{
if ($idprod)
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index ab7ce8599b0..43f5aaaf579 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -1236,13 +1236,15 @@ 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("DiscountFromCreditNote",$discount->ref_facture_source);
+ $sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
+ $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$sourceref);
}
elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except)
{
$discount=new DiscountAbsolute($db);
$discount->fetch($object->lines[$i]->fk_remise_except);
- $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$discount->ref_facture_source);
+ $sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
+ $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$sourceref);
// Add date of deposit
if (! empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) echo ' ('.dol_print_date($discount->datec,'day','',$outputlangs).')';
}
@@ -1252,6 +1254,12 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
$discount->fetch($object->lines[$i]->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived",$discount->ref_facture_source);
}
+ elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except)
+ {
+ $discount=new DiscountAbsolute($db);
+ $discount->fetch($object->lines[$i]->fk_remise_except);
+ $libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid",$discount->ref_invoice_supplier_source);
+ }
else
{
if ($idprod)
diff --git a/htdocs/core/tpl/object_discounts.tpl.php b/htdocs/core/tpl/object_discounts.tpl.php
new file mode 100644
index 00000000000..e8accdc4d26
--- /dev/null
+++ b/htdocs/core/tpl/object_discounts.tpl.php
@@ -0,0 +1,104 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see ';
// Discounts for third party
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+ $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
+ } else {
+ $filterabsolutediscount = "fk_facture_source IS NULL OR (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)%')";
+ }
+
print ''.$langs->trans('Discounts').' ';
- if ($soc->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_percent);
- else print $langs->trans("CompanyHasNoRelativeDiscount");
- print '. ';
- $absolute_discount=$soc->getAvailableDiscounts('','fk_facture_source IS NULL');
- $absolute_creditnote=$soc->getAvailableDiscounts('','fk_facture_source IS NOT NULL');
+
+ $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount);
+ $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote);
$absolute_discount=price2num($absolute_discount,'MT');
$absolute_creditnote=price2num($absolute_creditnote,'MT');
- if ($absolute_discount)
- {
- if ($object->statut > Commande::STATUS_DRAFT)
- {
- print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
- }
- else
- {
- // Remise dispo de type non avoir
- $filter='fk_facture_source IS NULL';
- print ' ';
- $form->form_remise_dispo($_SERVER["PHP_SELF"].'?id='.$object->id,0,'remise_id',$soc->id,$absolute_discount,$filter, 0, '', 1);
- }
- }
- if ($absolute_creditnote)
- {
- print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'. ';
- }
- if (! $absolute_discount && ! $absolute_creditnote) print $langs->trans("CompanyHasNoAbsoluteDiscount").'.';
+
+ $thirdparty = $soc;
+ $discount_type = 0;
+ $backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
+ $cannotApplyDiscount = 1;
+ include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print ' ';
// Date
diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php
index 5eb963a4e49..d71585b0420 100644
--- a/htdocs/fourn/card.php
+++ b/htdocs/fourn/card.php
@@ -258,6 +258,39 @@ if ($object->id > 0)
print "";
print '';
+ // Relative discounts (Discounts-Drawbacks-Rebates)
+ print '';
+ print '';
+ print $langs->trans("CustomerRelativeDiscountShort");
+ print ' ';
+ if ($user->rights->societe->creer && !$user->societe_id > 0)
+ {
+ print ''.img_edit($langs->trans("Modify")).' ';
+ }
+ print '
';
+ print ' '.($object->remise_supplier_percent?''.$object->remise_supplier_percent.'% ':'').' ';
+ print ' ';
+
+ // Absolute discounts (Discounts-Drawbacks-Rebates)
+ print '';
+ print '';
+ print ' ';
+ print '';
+ $amount_discount=$object->getAvailableDiscounts('', '', 0, 1);
+ if ($amount_discount < 0) dol_print_error($db,$object->error);
+ if ($amount_discount > 0) print 'id).'">'.price($amount_discount,1,$langs,1,-1,-1,$conf->currency).' ';
+ //else print $langs->trans("DiscountNone");
+ print ' ';
+ print ' ';
+
print '';
print '';
print $form->editfieldkey("OrderMinAmount",'supplier_order_min_amount',$object->supplier_order_min_amount,$object,$user->rights->societe->creer);
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index 51f0263a664..5b98acb9fcc 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -894,6 +894,107 @@ 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_fourn=$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->product_type=0;
+ $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
@@ -927,6 +1028,33 @@ class FactureFournisseur extends CommonInvoice
// Fin appel triggers
}
+ if (! $error) {
+ // If invoice was converted into a discount not yet consumed, we remove discount
+ $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'societe_remise_except';
+ $sql .= ' WHERE fk_invoice_supplier_source = ' . $rowid;
+ $sql .= ' AND fk_invoice_supplier_line IS NULL';
+ $resql = $this->db->query($sql);
+
+ // If invoice has consumned discounts
+ $this->fetch_lines();
+ $list_rowid_det = array ();
+ foreach ($this->lines as $key => $invoiceline) {
+ $list_rowid_det[] = $invoiceline->rowid;
+ }
+
+ // Consumned discounts are freed
+ if (count($list_rowid_det)) {
+ $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except';
+ $sql .= ' SET fk_invoice_supplier = NULL, fk_invoice_supplier_line = NULL';
+ $sql .= ' WHERE fk_invoice_supplier_line IN (' . join(',', $list_rowid_det) . ')';
+
+ dol_syslog(get_class($this) . "::delete", LOG_DEBUG);
+ if (! $this->db->query($sql)) {
+ $error ++;
+ }
+ }
+ }
+
if (! $error)
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';';
@@ -1668,6 +1796,22 @@ class FactureFournisseur extends CommonInvoice
$rowid = $this->id;
}
+ $this->db->begin();
+
+ // Libere remise liee a ligne de facture
+ $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except';
+ $sql .= ' SET fk_invoice_supplier_line = NULL';
+ $sql .= ' WHERE fk_invoice_supplier_line = ' . $rowid;
+
+ dol_syslog(get_class($this) . "::deleteline", LOG_DEBUG);
+ $result = $this->db->query($sql);
+ if (! $result)
+ {
+ $this->error = $this->db->error();
+ $this->db->rollback();
+ return - 2;
+ }
+
$line = new SupplierInvoiceLine($this->db);
if ($line->fetch($rowid) < 1) {
@@ -1677,12 +1821,24 @@ class FactureFournisseur extends CommonInvoice
$res = $line->delete($notrigger);
if ($res < 1) {
- $this->errors[] = $line->error;
+ $this->errors[] = $line->error;
+ $this->db->rollback();
+ return - 3;
} else {
- $res = $this->update_price();
- }
+ $res = $this->update_price();
- return $res;
+ if ($res > 0)
+ {
+ $this->db->commit();
+ return 1;
+ }
+ else
+ {
+ $this->db->rollback();
+ $this->error = $this->db->lasterror();
+ return - 4;
+ }
+ }
}
diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
index 555cde48899..faf0cba82a8 100644
--- a/htdocs/fourn/commande/card.php
+++ b/htdocs/fourn/commande/card.php
@@ -1401,7 +1401,7 @@ if ($action=='create')
$availability_id = (!empty($objectsrc->availability_id)?$objectsrc->availability_id:(!empty($soc->availability_id)?$soc->availability_id:0));
$shipping_method_id = (! empty($objectsrc->shipping_method_id)?$objectsrc->shipping_method_id:(! empty($soc->shipping_method_id)?$soc->shipping_method_id:0));
$demand_reason_id = (!empty($objectsrc->demand_reason_id)?$objectsrc->demand_reason_id:(!empty($soc->demand_reason_id)?$soc->demand_reason_id:0));
- $remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_percent)?$soc->remise_percent:0));
+ $remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_supplier_percent)?$soc->remise_supplier_percent:0));
$remise_absolue = (!empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(!empty($soc->remise_absolue)?$soc->remise_absolue:0));
$dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:'';
@@ -1439,7 +1439,7 @@ if ($action=='create')
print ' ';
print ' ';
print ' ' . "\n";
- print ' ';
+ print ' ';
print ' ';
print ' ';
if (!empty($currency_tx)) print ' ';
@@ -1480,6 +1480,21 @@ if ($action=='create')
}
print ' ';
+ if ($societe->id > 0)
+ {
+ // Discounts for third party
+ print ' ' . $langs->trans('Discounts') . ' ';
+
+ $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
+
+ $thirdparty = $societe;
+ $discount_type = 1;
+ $backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
+ include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
+
+ print ' ';
+ }
+
// Ref supplier
print ''.$langs->trans('RefSupplier').' ';
print ' ';
@@ -1860,6 +1875,29 @@ elseif (! empty($object->id))
print ''.$author->getNomUrl(1, '', 0, 0, 0).' ';
print '';
+ // Relative and absolute discounts
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+ $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ } else {
+ $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
+ $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
+ }
+
+ $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
+ $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 1);
+ $absolute_discount = price2num($absolute_discount, 'MT');
+ $absolute_creditnote = price2num($absolute_creditnote, 'MT');
+
+ print '' . $langs->trans('Discounts') . ' ';
+
+ $thirdparty = $societe;
+ $discount_type = 1;
+ $backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
+ include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
+
+ print ' ';
+
// Conditions de reglement par defaut
$langs->load('bills');
print '';
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index 3e368b59027..c90336f8a4b 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->fournisseur->facture->creer)
+ {
+ $discount = new DiscountAbsolute($db);
+ $result = $discount->fetch(GETPOST("discountid"));
+ $discount->unlink_invoice();
+ }
elseif ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer)
{
@@ -317,12 +326,12 @@ if (empty($reshook))
}
// Multicurrency Code
- else if ($action == 'setmulticurrencycode' && $user->rights->facture->creer) {
+ else if ($action == 'setmulticurrencycode' && $user->rights->fournisseur->facture->creer) {
$result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
}
// Multicurrency rate
- else if ($action == 'setmulticurrencyrate' && $user->rights->facture->creer) {
+ else if ($action == 'setmulticurrencyrate' && $user->rights->fournisseur->facture->creer) {
$result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx', 'alpha')));
}
@@ -376,6 +385,187 @@ if (empty($reshook))
$result=$object->update($user);
if ($result < 0) dol_print_error($db,$object->error);
}
+ elseif ($action == "setabsolutediscount" && $user->rights->fournisseur->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);
+ 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->fournisseur->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->discount_type = 1; // Supplier discount
+ $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 +654,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 +710,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 +872,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);
@@ -1434,7 +1629,7 @@ if ($action == 'create')
$cond_reglement_id = (!empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(!empty($soc->cond_reglement_supplier_id)?$soc->cond_reglement_supplier_id:1));
$mode_reglement_id = (!empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(!empty($soc->mode_reglement_supplier_id)?$soc->mode_reglement_supplier_id:0));
$fk_account = (! empty($objectsrc->fk_account)?$objectsrc->fk_account:(! empty($soc->fk_account)?$soc->fk_account:0));
- $remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_percent)?$soc->remise_percent:0));
+ $remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_supplier_percent)?$soc->remise_supplier_percent:0));
$remise_absolue = (!empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(!empty($soc->remise_absolue)?$soc->remise_absolue:0));
$dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:'';
@@ -1489,6 +1684,7 @@ if ($action == 'create')
if ($societe->id > 0)
{
+ $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
print $societe->getNomUrl(1);
print ' ';
}
@@ -1654,90 +1850,80 @@ if ($action == 'create')
if (empty($origin))
{
- if ($conf->global->MAIN_FEATURES_LEVEL > 0) // Need to fix reports of standard accounting module to manage supplier credit note
+ if ($societe->id > 0)
{
- if ($societe->id > 0)
- {
- // Credit note
- if (empty($conf->global->INVOICE_DISABLE_CREDIT_NOTE))
- {
- print '';
- }
- }
- else
+ // Credit note
+ if (empty($conf->global->INVOICE_DISABLE_CREDIT_NOTE))
{
print '' . "\n";
+
+ print '';
+ print ' 0 ? 'checked':'').' /> '.$langs->trans('invoiceAvoirWithLines')." ";
+ print ' 0 ? 'checked':'').' /> '.$langs->trans('invoiceAvoirWithPaymentRestAmount')." ";
+ print '
';
+
+ print '';
}
}
+ else
+ {
+ print '' . "\n";
+ }
}
print '';
print ' ';
- if ($socid > 0)
+ if ($societe->id > 0)
{
// Discounts for third party
print '' . $langs->trans('Discounts') . ' ';
- if ($soc->remise_percent)
- print $langs->trans("CompanyHasRelativeDiscount", 'id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . $soc->remise_percent . ' ');
- else
- print $langs->trans("CompanyHasNoRelativeDiscount");
- print ' id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditRelativeDiscount") . ') ';
- print '. ';
- print ' ';
- if ($absolute_discount)
- print $langs->trans("CompanyHasAbsoluteDiscount", 'id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . price($absolute_discount) . ' ', $langs->trans("Currency" . $conf->currency));
- else
- print $langs->trans("CompanyHasNoAbsoluteDiscount");
- print ' id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditGlobalDiscounts") . ') ';
- print '.';
+
+ $thirdparty = $societe;
+ $discount_type = 1;
+ $backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $societe->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
+ include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
+
print ' ';
}
@@ -1948,6 +2134,18 @@ else
}
$resteapayeraffiche = $resteapayer;
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { // Never use this
+ $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ } else {
+ $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
+ $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
+ }
+
+ $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
+ $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 1);
+ $absolute_discount = price2num($absolute_discount, 'MT');
+ $absolute_creditnote = price2num($absolute_creditnote, 'MT');
/*
* View card
@@ -1957,6 +2155,17 @@ else
dol_fiche_head($head, 'card', $titre, -1, 'bill');
+ $formconfirm = '';
+
+ // Confirmation de la conversion de l'avoir en reduc
+ if ($action == 'converttoreduc') {
+ if($object->type == FactureFournisseur::TYPE_STANDARD) $type_fac = 'ExcessPaid';
+ elseif($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) $type_fac = 'CreditNote';
+ elseif($object->type == FactureFournisseur::TYPE_DEPOSIT) $type_fac = 'Deposit';
+ $text = $langs->trans('ConfirmConvertToReducSupplier', strtolower($langs->transnoentities($type_fac)));
+ $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
+ }
+
// Clone confirmation
if ($action == 'clone')
{
@@ -2192,8 +2401,27 @@ else
$facthatreplace->fetch($facidnext);
print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')';
}
+ if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
+ $discount = new DiscountAbsolute($db);
+ $result = $discount->fetch(0, 0, $object->id);
+ if ($result > 0){
+ print '. '.$langs->trans("CreditNoteConvertedIntoDiscount", $object->getLibType(), $discount->getNomUrl(1, 'discount')).' ';
+ }
+ }
print '';
+
+ // Relative and absolute discounts
+ print '' . $langs->trans('Discounts');
+ print ' ';
+
+ $thirdparty = $societe;
+ $discount_type = 1;
+ $backtopage = urlencode($_SERVER["PHP_SELF"] . '?facid=' . $object->id);
+ include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
+
+ print ' ';
+
// Label
print '';
print ''.$form->editfieldkey("Label",'label',$object->label,$object,($user->rights->fournisseur->facture->creer)).' ';
@@ -2543,18 +2771,20 @@ else
print $langs->trans('AlreadyPaid');
print ' : 0)?' class="amountalreadypaid"':'').'>' . price($totalpaye) . ' ';
- $resteapayer = $object->total_ttc - $totalpaye;
+ //$resteapayer = $object->total_ttc - $totalpaye;
$resteapayeraffiche = $resteapayer;
+
$cssforamountpaymentcomplete = 'amountpaymentcomplete';
// Loop on each credit note or deposit amount applied
$creditnoteamount = 0;
$depositamount = 0;
- /*
+
+
$sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
- $sql .= " re.description, re.fk_facture_source";
- $sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except_supplier as re";
- $sql .= " WHERE fk_facture = " . $object->id;
+ $sql .= " re.description, re.fk_invoice_supplier_source";
+ $sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as re";
+ $sql .= " WHERE fk_invoice_supplier = " . $object->id;
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
@@ -2562,7 +2792,7 @@ else
$invoice = new FactureFournisseur($db);
while ($i < $num) {
$obj = $db->fetch_object($resql);
- $invoice->fetch($obj->fk_facture_source);
+ $invoice->fetch($obj->fk_invoice_supplier_source);
print '';
if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE)
print $langs->trans("CreditNote") . ' ';
@@ -2583,7 +2813,6 @@ else
} else {
dol_print_error($db);
}
- */
// Paye partiellement 'escompte'
if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'discount_vat') {
@@ -2629,9 +2858,9 @@ else
if ($resteapayeraffiche >= 0)
print $langs->trans('RemainderToPay');
else
- print $langs->trans('ExcessReceived');
+ print $langs->trans('ExcessPaid');
print ' : ';
- print '' . price($resteapayeraffiche) . ' ';
+ print '' . price($resteapayeraffiche) . ' ';
print ' ';
}
else // Credit note
@@ -2653,7 +2882,7 @@ else
else
print $langs->trans('ExcessPaydBack');
print ' :';
- print '' . price($sign * $resteapayeraffiche) . ' ';
+ print '' . price($sign * $resteapayeraffiche) . ' ';
print ' ';
// Sold credit note
@@ -2796,7 +3025,7 @@ else
}
// Reverse back money or convert to reduction
- if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
+ if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) {
// For credit note only
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0)
{
@@ -2810,6 +3039,11 @@ else
}
}
+ // For standard invoice with excess paid
+ if ($object->type == FactureFournisseur::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) < 0 && $user->rights->fournisseur->facture->creer && empty($discount->id))
+ {
+ print '';
+ }
// For credit note
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->fournisseur->facture->creer && $object->getSommePaiement() == 0) {
print '';
diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php
index f48f3d2c01d..78ea00f205a 100644
--- a/htdocs/fourn/facture/list.php
+++ b/htdocs/fourn/facture/list.php
@@ -76,6 +76,7 @@ $search_amount_all_tax = GETPOST("search_amount_all_tax","alpha");
$search_product_category=GETPOST('search_product_category','int');
$search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha');
$search_refsupplier=GETPOST('search_refsupplier','alpha');
+$search_type=GETPOST('search_type','int');
$search_project=GETPOST('search_project','alpha');
$search_societe=GETPOST('search_societe','alpha');
$search_montant_ht=GETPOST('search_montant_ht','alpha');
@@ -148,6 +149,7 @@ $checkedtypetiers=0;
$arrayfields=array(
'f.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
'f.ref_supplier'=>array('label'=>$langs->trans("RefSupplier"), 'checked'=>1),
+ 'f.type'=>array('label'=>$langs->trans("Type"), 'checked'=>0),
'f.label'=>array('label'=>$langs->trans("Label"), 'checked'=>0),
'f.datef'=>array('label'=>$langs->trans("DateInvoice"), 'checked'=>1),
'f.date_lim_reglement'=>array('label'=>$langs->trans("DateDue"), 'checked'=>1),
@@ -203,6 +205,7 @@ if (empty($reshook))
$search_product_category='';
$search_ref="";
$search_refsupplier="";
+ $search_type="";
$search_label="";
$search_project='';
$search_societe="";
@@ -261,7 +264,7 @@ llxHeader('',$langs->trans("SuppliersInvoices"),'EN:Suppliers_Invoices|FR:Factur
$sql = "SELECT";
if ($search_all || $search_product_category > 0) $sql = 'SELECT DISTINCT';
-$sql.= " f.rowid as facid, f.ref, f.ref_supplier, f.datef, f.date_lim_reglement as datelimite, f.fk_mode_reglement,";
+$sql.= " f.rowid as facid, f.ref, f.ref_supplier, f.type, f.datef, f.date_lim_reglement as datelimite, f.fk_mode_reglement,";
$sql.= " f.total_ht, f.total_ttc, f.total_tva as total_vat, f.paye as paye, f.fk_statut as fk_statut, f.libelle as label, f.datec as date_creation, f.tms as date_update,";
$sql.= " f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,";
$sql.= " s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur,";
@@ -307,6 +310,15 @@ if ($search_ref)
}
if ($search_ref) $sql .= natural_search('f.ref', $search_ref);
if ($search_refsupplier) $sql .= natural_search('f.ref_supplier', $search_refsupplier);
+if ($search_type != '' && $search_type >= 0)
+{
+ if ($search_type == '0') $sql.=" AND f.type = 0"; // standard
+ if ($search_type == '1') $sql.=" AND f.type = 1"; // replacement
+ if ($search_type == '2') $sql.=" AND f.type = 2"; // credit note
+ if ($search_type == '3') $sql.=" AND f.type = 3"; // deposit
+ //if ($search_type == '4') $sql.=" AND f.type = 4"; // proforma
+ //if ($search_type == '5') $sql.=" AND f.type = 5"; // situation
+}
if ($search_project) $sql .= natural_search('p.ref', $search_project);
if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
if ($search_town) $sql.= natural_search('s.town', $search_town);
@@ -377,7 +389,7 @@ $sql.=$hookmanager->resPrint;
if (! $search_all)
{
- $sql.= " GROUP BY f.rowid, f.ref, f.ref_supplier, f.datef, f.date_lim_reglement, f.fk_mode_reglement,";
+ $sql.= " GROUP BY f.rowid, f.ref, f.ref_supplier, f.type, f.datef, f.date_lim_reglement, f.fk_mode_reglement,";
$sql.= " f.total_ht, f.total_ttc, f.total_tva, f.paye, f.fk_statut, f.libelle, f.datec, f.tms,";
$sql.= " f.localtax1, f.localtax2,";
$sql.= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,';
@@ -434,6 +446,7 @@ if ($resql)
if ($year_lim) $param.='&year_lim=' .urlencode($year_lim);
if ($search_ref) $param.='&search_ref='.urlencode($search_ref);
if ($search_refsupplier) $param.='&search_refsupplier='.urlencode($search_refsupplier);
+ if ($search_type != '') $param.='&search_type='.urlencode($search_type);
if ($search_label) $param.='&search_label='.urlencode($search_label);
if ($search_company) $param.='&search_company='.urlencode($search_company);
if ($search_montant_ht != '') $param.='&search_montant_ht='.urlencode($search_montant_ht);
@@ -590,6 +603,26 @@ if ($resql)
print ' ';
print '';
}
+ // Type
+ if (! empty($arrayfields['f.type']['checked']))
+ {
+ print '';
+ $listtype=array(
+ FactureFournisseur::TYPE_STANDARD=>$langs->trans("InvoiceStandard"),
+ FactureFournisseur::TYPE_REPLACEMENT=>$langs->trans("InvoiceReplacement"),
+ FactureFournisseur::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"),
+ FactureFournisseur::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"),
+ );
+/*
+ if (! empty($conf->global->INVOICE_USE_SITUATION))
+ {
+ $listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation");
+ }
+*/
+ //$listtype[Facture::TYPE_PROFORMA]=$langs->trans("InvoiceProForma"); // A proformat invoice is not an invoice but must be an order.
+ print $form->selectarray('search_type', $listtype, $search_type, 1, 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth100');
+ print ' ';
+ }
// Label
if (! empty($arrayfields['f.label']['checked']))
{
@@ -741,6 +774,7 @@ if ($resql)
print '';
if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'],$_SERVER['PHP_SELF'],'f.ref,f.rowid','',$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['f.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['f.ref_supplier']['label'],$_SERVER["PHP_SELF"],'f.ref_supplier','',$param,'',$sortfield,$sortorder);
+ if (! empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'],$_SERVER["PHP_SELF"],'f.type','',$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['f.label']['checked'])) print_liste_field_titre($arrayfields['f.label']['label'],$_SERVER['PHP_SELF'],"f.libelle,f.rowid",'',$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['f.datef']['checked'])) print_liste_field_titre($arrayfields['f.datef']['label'],$_SERVER['PHP_SELF'],'f.datef,f.rowid','',$param,'align="center"',$sortfield,$sortorder);
if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder);
@@ -767,7 +801,7 @@ if ($resql)
print $hookmanager->resPrint;
if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
- if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder);
+ if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type","",$param,'align="right"',$sortfield,$sortorder);
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ');
print " \n";
@@ -843,6 +877,15 @@ if ($resql)
print '';
if (! $i) $totalarray['nbfield']++;
}
+
+ // Type
+ if (! empty($arrayfields['f.type']['checked']))
+ {
+ print '';
+ print $facturestatic->getLibType();
+ print " ";
+ if (! $i) $totalarray['nbfield']++;
+ }
// Label
if (! empty($arrayfields['f.label']['checked']))
diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql
index dc7b7d083ab..eb3c865c106 100644
--- a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql
+++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql
@@ -57,6 +57,21 @@ create table llx_c_type_container
ALTER TABLE llx_c_type_container ADD UNIQUE INDEX uk_c_type_container_id (code, entity);
+
+ALTER TABLE llx_societe_remise_except ADD COLUMN discount_type integer DEFAULT 0 NOT NULL AFTER fk_soc;
+ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_discount_type (discount_type);
+ALTER TABLE llx_societe ADD COLUMN remise_supplier real DEFAULT 0 AFTER remise_client;
+CREATE TABLE llx_societe_remise_supplier
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ entity integer DEFAULT 1 NOT NULL, -- multi company id
+ fk_soc integer NOT NULL,
+ tms timestamp,
+ datec datetime, -- creation date
+ fk_user_author integer, -- creation user
+ remise_supplier double(6,3) DEFAULT 0 NOT NULL, -- discount
+ note text
+)ENGINE=innodb;
insert into llx_c_type_container (code,label,module,active) values ('page', 'Page', 'system', 1);
insert into llx_c_type_container (code,label,module,active) values ('banner', 'Banner', 'system', 1);
insert into llx_c_type_container (code,label,module,active) values ('blogpost', 'BlogPost', 'system', 1);
diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql
index 9ffb9734d7f..f1714021fb8 100644
--- a/htdocs/install/mysql/tables/llx_societe.sql
+++ b/htdocs/install/mysql/tables/llx_societe.sql
@@ -78,6 +78,7 @@ create table llx_societe
customer_rate real DEFAULT 0, -- taux fiabilite client (0 a 1)
supplier_rate real DEFAULT 0, -- taux fiabilite fournisseur (0 a 1)
remise_client real DEFAULT 0, -- remise systematique pour le client
+ remise_supplier real DEFAULT 0, -- remise systematique auprès du fournisseur
mode_reglement tinyint, -- mode de reglement
cond_reglement tinyint, -- condition de reglement
mode_reglement_supplier tinyint, -- mode de reglement fournisseur
diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql
index 148a8777915..525af592041 100644
--- a/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql
+++ b/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql
@@ -26,6 +26,7 @@ ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_soc
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_line (fk_facture_line);
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture (fk_facture);
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_source (fk_facture_source);
+ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_discount_type (discount_type);
ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid);
diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.sql
index 3a19a026ca9..151e33d7f1e 100644
--- a/htdocs/install/mysql/tables/llx_societe_remise_except.sql
+++ b/htdocs/install/mysql/tables/llx_societe_remise_except.sql
@@ -23,7 +23,8 @@ create table llx_societe_remise_except
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1 NOT NULL, -- multi company id
- fk_soc integer NOT NULL, -- client
+ fk_soc integer NOT NULL, -- customer or supplier
+ discount_type integer DEFAULT 0 NOT NULL, -- 0 => customer, 1 => supplier
datec datetime,
amount_ht double(24,8) NOT NULL,
amount_tva double(24,8) DEFAULT 0 NOT NULL,
diff --git a/htdocs/install/mysql/tables/llx_societe_remise_supplier.sql b/htdocs/install/mysql/tables/llx_societe_remise_supplier.sql
new file mode 100644
index 00000000000..c1b56f225c7
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_societe_remise_supplier.sql
@@ -0,0 +1,34 @@
+-- ========================================================================
+-- Copyright (C) 2000-2004 Rodolphe Quiedeville
+-- Copyright (C) 2011-2016 Regis Houssin
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+--
+-- Historique evolution de la remise relative des tiers
+-- ========================================================================
+
+create table llx_societe_remise_supplier
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ entity integer DEFAULT 1 NOT NULL, -- multi company id
+ fk_soc integer NOT NULL,
+ tms timestamp,
+ datec datetime, -- creation date
+ fk_user_author integer, -- creation user
+ remise_supplier double(6,3) DEFAULT 0 NOT NULL, -- discount
+ note text
+
+)ENGINE=innodb;
+
diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
index 668090129ff..62386adbe99 100644
--- a/htdocs/langs/en_US/bills.lang
+++ b/htdocs/langs/en_US/bills.lang
@@ -67,6 +67,7 @@ PaidBack=Paid back
DeletePayment=Delete payment
ConfirmDeletePayment=Are you sure you want to delete this payment?
ConfirmConvertToReduc=Do you want to convert this %s into an absolute discount ? The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this customer.
+ConfirmConvertToReducSupplier=Do you want to convert this %s into an absolute discount ? The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this supplier.
SupplierPayments=Suppliers payments
ReceivedPayments=Received payments
ReceivedCustomersPayments=Payments received from customers
@@ -91,7 +92,7 @@ PaymentAmount=Payment amount
ValidatePayment=Validate payment
PaymentHigherThanReminderToPay=Payment higher than reminder to pay
HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the rest to pay. Edit your entry, otherwise confirm and think about creating a credit note of the excess received for each overpaid invoices.
-HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the rest to pay. Edit your entry, otherwise confirm.
+HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the rest to pay. Edit your entry, otherwise confirm and think about creating a credit note of the excess paid for each overpaid invoice.
ClassifyPaid=Classify 'Paid'
ClassifyPaidPartially=Classify 'Paid partially'
ClassifyCanceled=Classify 'Abandoned'
@@ -110,6 +111,7 @@ DoPayment=Enter payment
DoPaymentBack=Enter refund
ConvertToReduc=Convert into future discount
ConvertExcessReceivedToReduc=Convert excess received into future discount
+ConvertExcessPaidToReduc=Convert excess paid into future discount
EnterPaymentReceivedFromCustomer=Enter payment received from customer
EnterPaymentDueToCustomer=Make payment due to customer
DisabledBecauseRemainderToPayIsZero=Disabled because remaining unpaid is zero
@@ -220,6 +222,7 @@ RemainderToPayBack=Remaining amount to refund
Rest=Pending
AmountExpected=Amount claimed
ExcessReceived=Excess received
+ExcessPaid=Excess paid
EscompteOffered=Discount offered (payment before term)
EscompteOfferedShort=Discount
SendBillRef=Submission of invoice %s
@@ -284,15 +287,19 @@ Deposits=Down payments
DiscountFromCreditNote=Discount from credit note %s
DiscountFromDeposit=Down payments from invoice %s
DiscountFromExcessReceived=Payments from excess received of invoice %s
+DiscountFromExcessPaid=Payments from excess paid of invoice %s
AbsoluteDiscountUse=This kind of credit can be used on invoice before its validation
CreditNoteDepositUse=Invoice must be validated to use this kind of credits
NewGlobalDiscount=New absolute discount
NewRelativeDiscount=New relative discount
+DiscountType=Discount type
NoteReason=Note/Reason
ReasonDiscount=Reason
DiscountOfferedBy=Granted by
DiscountStillRemaining=Discounts available
DiscountAlreadyCounted=Discounts already consumed
+CustomerDiscounts=Customer discounts
+SupplierDiscounts=Supplier discounts
BillAddress=Bill address
HelpEscompte=This discount is a discount granted to customer because its payment was made before term.
HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptional loose.
diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang
index 57ff05ed8ac..36339d5ce08 100644
--- a/htdocs/langs/en_US/companies.lang
+++ b/htdocs/langs/en_US/companies.lang
@@ -79,6 +79,7 @@ VATIsUsed=Sales tax is used
VATIsNotUsed=Sales tax is not used
CopyAddressFromSoc=Fill address with third party address
ThirdpartyNotCustomerNotSupplierSoNoRef=Thirdparty neither customer nor supplier, no available refering objects
+ThirdpartyIsNeitherCustomerNorClientSoCannotHaveDiscounts=Thirdparty neither customer nor supplier, discounts are not available
PaymentBankAccount=Payment bank account
OverAllProposals=Proposals
OverAllOrders=Orders
@@ -268,12 +269,20 @@ CustomerRelativeDiscountShort=Relative discount
CustomerAbsoluteDiscountShort=Absolute discount
CompanyHasRelativeDiscount=This customer has a default discount of %s%%
CompanyHasNoRelativeDiscount=This customer has no relative discount by default
+HasRelativeDiscountFromSupplier=You have a default discount of %s%% from this supplier
+HasNoRelativeDiscountFromSupplier=You have no default relative discount from this supplier
CompanyHasAbsoluteDiscount=This customer has discount available (credits notes or down payments) for %s %s
CompanyHasDownPaymentOrCommercialDiscount=This customer has discount available (commercial, down payments) for %s %s
CompanyHasCreditNote=This customer still has credit notes for %s %s
+HasNoAbsoluteDiscountFromSupplier=You have no discount credit available from this supplier
+HasAbsoluteDiscountFromSupplier=You have discounts available (credits notes or down payments) for %s %s from this supplier
+HasDownPaymentOrCommercialDiscountFromSupplier=You have discounts available (commercial, down payments) for %s %s from this supplier
+HasCreditNoteFromSupplier=You have credit notes for %s %s from this supplier
CompanyHasNoAbsoluteDiscount=This customer has no discount credit available
-CustomerAbsoluteDiscountAllUsers=Absolute discounts (granted by all users)
-CustomerAbsoluteDiscountMy=Absolute discounts (granted by yourself)
+CustomerAbsoluteDiscountAllUsers=Absolute customer discounts (granted by all users)
+CustomerAbsoluteDiscountMy=Absolute customer discounts (granted by yourself)
+SupplierAbsoluteDiscountAllUsers=Absolute supplier discounts (granted by all users)
+SupplierAbsoluteDiscountMy=Absolute supplier discounts (granted by yourself)
DiscountNone=None
Supplier=Supplier
AddContact=Create contact
diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php
index 384eb02f921..aafea674bcf 100644
--- a/htdocs/societe/card.php
+++ b/htdocs/societe/card.php
@@ -149,7 +149,7 @@ if (empty($reshook))
$listofproperties=array(
'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
- 'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
+ 'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
'model_pdf', 'fk_projet'
diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php
index fa52c73f597..1cdfabf7fca 100644
--- a/htdocs/societe/class/api_thirdparties.class.php
+++ b/htdocs/societe/class/api_thirdparties.class.php
@@ -83,8 +83,14 @@ class Thirdparties extends DolibarrApi
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
- $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)%')";
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+ $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
+ } else {
+ $filterabsolutediscount = "fk_facture_source IS NULL OR (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)%')";
+ }
+
$absolute_discount = $this->company->getAvailableDiscounts('', $filterabsolutediscount);
$absolute_creditnote = $this->company->getAvailableDiscounts('', $filtercreditnote);
$this->company->absolute_discount = price2num($absolute_discount, 'MT');
@@ -308,7 +314,7 @@ class Thirdparties extends DolibarrApi
$listofproperties=array(
'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
- 'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
+ 'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
'model_pdf', 'fk_projet'
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 94b686c3b35..b936a431080 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -234,6 +234,7 @@ class Societe extends CommonObject
var $forme_juridique;
var $remise_percent;
+ var $remise_supplier_percent;
var $mode_reglement_supplier_id;
var $cond_reglement_supplier_id;
var $fk_prospectlevel;
@@ -1144,7 +1145,7 @@ class Societe extends CommonObject
$sql .= ', s.fk_forme_juridique as forme_juridique_code';
$sql .= ', s.webservices_url, s.webservices_key';
$sql .= ', s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.parent, s.barcode';
- $sql .= ', s.fk_departement, s.fk_pays as country_id, s.fk_stcomm, s.remise_client, s.mode_reglement, s.cond_reglement, s.fk_account, s.tva_assuj';
+ $sql .= ', s.fk_departement, s.fk_pays as country_id, s.fk_stcomm, s.remise_client, s.remise_supplier, s.mode_reglement, s.cond_reglement, s.fk_account, s.tva_assuj';
$sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo';
$sql .= ', s.fk_shipping_method';
$sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms';
@@ -1277,6 +1278,7 @@ class Societe extends CommonObject
$this->prefix_comm = $obj->prefix_comm;
$this->remise_percent = $obj->remise_client;
+ $this->remise_supplier_percent = $obj->remise_supplier;
$this->mode_reglement_id = $obj->mode_reglement;
$this->cond_reglement_id = $obj->cond_reglement;
$this->mode_reglement_supplier_id = $obj->mode_reglement_supplier;
@@ -1660,17 +1662,79 @@ class Societe extends CommonObject
return 1;
}
}
+
+ /**
+ * Definit la societe comme un client
+ *
+ * @param float $remise Valeur en % de la remise
+ * @param string $note Note/Motif de modification de la remise
+ * @param User $user Utilisateur qui definie la remise
+ * @return int <0 if KO, >0 if OK
+ */
+ function set_remise_supplier($remise, $note, User $user)
+ {
+ global $conf, $langs;
+
+ // Nettoyage parametres
+ $note=trim($note);
+ if (! $note)
+ {
+ $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("NoteReason"));
+ return -2;
+ }
+
+ dol_syslog(get_class($this)."::set_remise_supplier ".$remise.", ".$note.", ".$user->id);
+
+ if ($this->id)
+ {
+ $this->db->begin();
+
+ $now=dol_now();
+
+ // Positionne remise courante
+ $sql = "UPDATE ".MAIN_DB_PREFIX."societe ";
+ $sql.= " SET remise_supplier = '".$this->db->escape($remise)."'";
+ $sql.= " WHERE rowid = " . $this->id;
+ $resql=$this->db->query($sql);
+ if (! $resql)
+ {
+ $this->db->rollback();
+ $this->error=$this->db->error();
+ return -1;
+ }
+
+ // Ecrit trace dans historique des remises
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_supplier";
+ $sql.= " (entity, datec, fk_soc, remise_supplier, note, fk_user_author)";
+ $sql.= " VALUES (".$conf->entity.", '".$this->db->idate($now)."', ".$this->id.", '".$this->db->escape($remise)."',";
+ $sql.= " '".$this->db->escape($note)."',";
+ $sql.= " ".$user->id;
+ $sql.= ")";
+
+ $resql=$this->db->query($sql);
+ if (! $resql)
+ {
+ $this->db->rollback();
+ $this->error=$this->db->lasterror();
+ return -1;
+ }
+
+ $this->db->commit();
+ return 1;
+ }
+ }
/**
* Add a discount for third party
*
- * @param float $remise Amount of discount
- * @param User $user User adding discount
- * @param string $desc Reason of discount
- * @param float $tva_tx VAT rate
+ * @param float $remise Amount of discount
+ * @param User $user User adding discount
+ * @param string $desc Reason of discount
+ * @param float $tva_tx VAT rate
+ * @param int $discount_type 0 => customer discount, 1 => supplier discount
* @return int <0 if KO, id of discount record if OK
*/
- function set_remise_except($remise, User $user, $desc, $tva_tx=0)
+ function set_remise_except($remise, User $user, $desc, $tva_tx=0, $discount_type=0)
{
global $langs;
@@ -1696,11 +1760,13 @@ class Societe extends CommonObject
$discount = new DiscountAbsolute($this->db);
$discount->fk_soc=$this->id;
+ $discount->discount_type=$discount_type;
$discount->amount_ht=price2num($remise,'MT');
$discount->amount_tva=price2num($remise*$tva_tx/100,'MT');
$discount->amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT');
$discount->tva_tx=price2num($tva_tx,'MT');
$discount->description=$desc;
+
$result=$discount->create($user);
if ($result > 0)
{
@@ -1718,17 +1784,18 @@ class Societe extends CommonObject
/**
* Renvoie montant TTC des reductions/avoirs en cours disponibles de la societe
*
- * @param User $user Filtre sur un user auteur des remises
- * @param string $filter Filtre autre
- * @param integer $maxvalue Filter on max value for discount
+ * @param User $user Filtre sur un user auteur des remises
+ * @param string $filter Filtre autre
+ * @param integer $maxvalue Filter on max value for discount
+ * @param int $discount_type 0 => customer discount, 1 => supplier discount
* @return int <0 if KO, Credit note amount otherwise
*/
- function getAvailableDiscounts($user='',$filter='',$maxvalue=0)
+ function getAvailableDiscounts($user='',$filter='',$maxvalue=0,$discount_type=0)
{
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discountstatic=new DiscountAbsolute($this->db);
- $result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue);
+ $result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue,$discount_type);
if ($result >= 0)
{
return $result;
diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php
index ffb4cac77fa..1a6a4be6199 100644
--- a/htdocs/societe/consumption.php
+++ b/htdocs/societe/consumption.php
@@ -491,6 +491,7 @@ if ($sql_select)
print img_object($langs->trans("ShowReduc"),'reduc').' ';
if ($objp->description == '(DEPOSIT)') $txt=$langs->trans("Deposit");
elseif ($objp->description == '(EXCESS RECEIVED)') $txt=$langs->trans("ExcessReceived");
+ elseif ($objp->description == '(EXCESS PAID)') $txt=$langs->trans("ExcessPaid");
//else $txt=$langs->trans("Discount");
print $txt;
?>
@@ -510,6 +511,12 @@ if ($sql_select)
$discount->fetch($objp->fk_remise_except);
echo ($txt?' - ':'').$langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0));
}
+ elseif ($objp->description == '(EXCESS PAID)' && $objp->fk_remise_except > 0)
+ {
+ $discount=new DiscountAbsolute($db);
+ $discount->fetch($objp->fk_remise_except);
+ echo ($txt?' - ':'').$langs->transnoentities("DiscountFromExcessPaid",$discount->getNomUrl(0));
+ }
elseif ($objp->description == '(DEPOSIT)' && $objp->fk_remise_except > 0)
{
$discount=new DiscountAbsolute($db);
diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php
index 27f38b3a298..5585d3ba87b 100644
--- a/htdocs/supplier_proposal/card.php
+++ b/htdocs/supplier_proposal/card.php
@@ -1000,7 +1000,7 @@ if ($action == 'create')
$cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1));
$mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0));
- $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0));
+ $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_supplier_percent)?$soc->remise_supplier_percent:0));
$remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0));
// Replicate extrafields
@@ -1053,6 +1053,21 @@ if ($action == 'create')
}
print '' . "\n";
+ if ($soc->id > 0)
+ {
+ // Discounts for third party
+ print '' . $langs->trans('Discounts') . ' ';
+
+ $absolute_discount = $soc->getAvailableDiscounts('', '', 0, 1);
+
+ $thirdparty = $soc;
+ $discount_type = 1;
+ $backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
+ include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
+
+ print ' ';
+ }
+
// Terms of payment
print '' . $langs->trans('PaymentConditionsShort') . ' ';
$form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1);
@@ -1392,6 +1407,29 @@ if ($action == 'create')
print '';
+ // Relative and absolute discounts
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+ $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
+ } else {
+ $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
+ $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
+ }
+
+ print '' . $langs->trans('Discounts') . ' ';
+
+ $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
+ $absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote, 0, 1);
+ $absolute_discount = price2num($absolute_discount, 'MT');
+ $absolute_creditnote = price2num($absolute_creditnote, 'MT');
+
+ $thirdparty = $soc;
+ $discount_type = 1;
+ $backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
+ include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
+
+ print ' ';
+
// Payment term
print '';
print '