Browse Source

New add payment with multicurrency module

phf 9 năm trước cách đây
mục cha
commit
a0cfe9aad8

+ 9 - 7
htdocs/compta/facture/class/facture.class.php

@@ -2802,7 +2802,7 @@ class Facture extends CommonInvoice
 			$field2='fk_paiementfourn';
 		}
 
-		$sql = 'SELECT pf.amount, p.fk_paiement, p.datep, t.code';
+		$sql = 'SELECT pf.amount, pf.multicurrency_amount, p.fk_paiement, p.datep, t.code';
 		$sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t';
 		$sql.= ' WHERE pf.'.$field.' = '.$this->id;
 		$sql.= ' AND pf.'.$field2.' = p.rowid';
@@ -2836,14 +2836,15 @@ class Facture extends CommonInvoice
 	/**
 	 *    	Return amount (with tax) of all credit notes and deposits invoices used by invoice
 	 *
-	 *		@return		int			<0 if KO, Sum of credit notes and deposits amount otherwise
+	 * 		@param 		int 	$multicurrency 	Return multicurrency_amount instead of amount
+	 *		@return		int						<0 if KO, Sum of credit notes and deposits amount otherwise
 	 */
-	function getSumCreditNotesUsed()
+	function getSumCreditNotesUsed($multicurrency=0)
 	{
 		require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
 
 		$discountstatic=new DiscountAbsolute($this->db);
-		$result=$discountstatic->getSumCreditNotesUsed($this);
+		$result=$discountstatic->getSumCreditNotesUsed($this, $multicurrency);
 		if ($result >= 0)
 		{
 			return $result;
@@ -2858,14 +2859,15 @@ class Facture extends CommonInvoice
 	/**
 	 *    	Return amount (with tax) of all deposits invoices used by invoice
 	 *
-	 *		@return		int			<0 if KO, Sum of deposits amount otherwise
+	 * 		@param 		int 	$multicurrency 	Return multicurrency_amount instead of amount
+	 *		@return		int						<0 if KO, Sum of deposits amount otherwise
 	 */
-	function getSumDepositsUsed()
+	function getSumDepositsUsed($multicurrency=0)
 	{
 		require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
 
 		$discountstatic=new DiscountAbsolute($this->db);
-		$result=$discountstatic->getSumDepositsUsed($this);
+		$result=$discountstatic->getSumDepositsUsed($this, $multicurrency);
 		if ($result >= 0)
 		{
 			return $result;

+ 131 - 17
htdocs/compta/paiement.php

@@ -54,6 +54,9 @@ $amounts=array();
 $amountsresttopay=array();
 $addwarning=0;
 
+$multicurrency_amounts=array();
+$multicurrency_amountsresttopay=array();
+
 // Security check
 $socid=0;
 if ($user->societe_id > 0)
@@ -90,10 +93,11 @@ if (empty($reshook))
 	    $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
 	    $paiement_id = 0;
 	    $totalpayment = 0;
+		$multicurrency_totalpayment = 0;
 	    $atleastonepaymentnotnull = 0;
 
 	    // Generate payment array and check if there is payment higher than invoice and payment date before invoice date
-	    $tmpinvoice=new Facture($db);
+	    $tmpinvoice=new Facture($db); 
 	    foreach ($_POST as $key => $value)
 	    {
 	        if (substr($key,0,7) == 'amount_')
@@ -124,6 +128,34 @@ if (empty($reshook))
 
 	            $formquestion[$i++]=array('type' => 'hidden','name' => $key,  'value' => $_POST[$key]);
 	        }
+			elseif (substr($key,0,21) == 'multicurrency_amount_')
+			{
+				$cursorfacid = substr($key,21);
+	            $multicurrency_amounts[$cursorfacid] = price2num(trim(GETPOST($key)));
+	            $multicurrency_totalpayment += $multicurrency_amounts[$cursorfacid];
+	            if (! empty($multicurrency_amounts[$cursorfacid])) $atleastonepaymentnotnull++;
+	            $result=$tmpinvoice->fetch($cursorfacid);
+	            if ($result <= 0) dol_print_error($db);
+	            $multicurrency_amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement(1));
+	            if ($multicurrency_amounts[$cursorfacid])
+	            {
+		            // Check amount
+		            if ($multicurrency_amounts[$cursorfacid] && (abs($multicurrency_amounts[$cursorfacid]) > abs($multicurrency_amountsresttopay[$cursorfacid])))
+		            {
+		                $addwarning=1;
+		                $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay");
+		            }
+		            // Check date
+		            if ($datepaye && ($datepaye < $tmpinvoice->date))
+		            {
+		            	$langs->load("errors");
+		                //$error++;
+		                setEventMessages($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), null, 'warnings');
+		            }
+	            }
+
+	            $formquestion[$i++]=array('type' => 'hidden','name' => $key,  'value' => GETPOST($key, 'int'));
+			}
 	    }
 
 	    // Check parameters
@@ -143,7 +175,7 @@ if (empty($reshook))
 	        }
 	    }
 
-	    if (empty($totalpayment) && empty($atleastonepaymentnotnull))
+	    if (empty($totalpayment) && empty($multicurrency_totalpayment) && empty($atleastonepaymentnotnull))
 	    {
 	        setEventMessages($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), null, 'errors');
 	        $error++;
@@ -154,6 +186,13 @@ if (empty($reshook))
 	        setEventMessages($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), null, 'errors');
 	        $error++;
 	    }
+		
+		// Check if payments in both currency
+		if ($totalpayment > 0 && $multicurrency_totalpayment > 0)
+		{
+			setEventMessages($langs->transnoentities('ErrorPaymentInBothCurrency'), null, 'errors');
+	        $error++;
+		}
 	}
 
 	/*
@@ -187,6 +226,12 @@ if (empty($reshook))
 		    	$newvalue = price2num($value,'MT');
 		    	$amounts[$key] = -$newvalue;
 		    }
+			
+			foreach ($multicurrency_amounts as $key => $value)	// How payment is dispatch
+		    {
+		    	$newvalue = price2num($value,'MT');
+		    	$multicurrency_amounts[$key] = -$newvalue;
+		    }
 	    }
 
 	    if (! empty($conf->banque->enabled))
@@ -203,6 +248,7 @@ if (empty($reshook))
 	    $paiement = new Paiement($db);
 	    $paiement->datepaye     = $datepaye;
 	    $paiement->amounts      = $amounts;   // Array with all payments dispatching
+	    $paiement->multicurrency_amounts = $multicurrency_amounts;   // Array with all payments dispatching
 	    $paiement->paiementid   = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement');
 	    $paiement->num_paiement = $_POST['num_paiement'];
 	    $paiement->note         = $_POST['comment'];
@@ -336,6 +382,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
 							{
 								subJson[n["name"]] = n["value"];
 							});
+							
 							return subJson;
 						}
 						function callForResult(imgId)
@@ -345,8 +392,8 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
 
 							json["invoice_type"] = $("#invoice_type").val();
 							json["amountPayment"] = $("#amountpayment").attr("value");
-							json["amounts"] = _elemToJson(form.find("input[name*=\"amount_\"]"));
-							json["remains"] = _elemToJson(form.find("input[name*=\"remain_\"]"));
+							json["amounts"] = _elemToJson(form.find("input.amount"));
+							json["remains"] = _elemToJson(form.find("input.remain]"));
 
 							if (imgId != null) {
 								json["imgClicked"] = imgId;
@@ -368,7 +415,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
 										}
 										json[key]=json["label"]+" "+json[key];
 										$("#"+key).text(json[key]);
-									} else {
+									} else {console.log(key);
 										form.find("input[name*=\""+key+"\"]").each(function() {
 											$(this).attr("value", json[key]);
 										});
@@ -376,10 +423,10 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
 								}
 							});
 						}
-						$("#payment_form").find("input[name*=\"amount_\"]").change(function() {
+						$("#payment_form").find("input.amount").change(function() {
 							callForResult();
 						});
-						$("#payment_form").find("input[name*=\"amount_\"]").keyup(function() {
+						$("#payment_form").find("input.amount").keyup(function() {
 							callForResult();
 						});
 			';
@@ -470,7 +517,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
         /*
          * List of unpaid invoices
          */
-        $sql = 'SELECT f.rowid as facid, f.facnumber, f.total_ttc, f.type, ';
+        $sql = 'SELECT f.rowid as facid, f.facnumber, f.total_ttc, f.multicurrency_total_ttc, f.type, ';
         $sql.= ' f.datef as df';
         $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
         $sql.= ' WHERE f.entity = '.$conf->entity;
@@ -501,9 +548,11 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
 				$arraytitle=$langs->trans('Invoice');
 				if ($facture->type == 2) $arraytitle=$langs->trans("CreditNotes");
 				$alreadypayedlabel=$langs->trans('Received');
-				if ($facture->type == 2) $alreadypayedlabel=$langs->trans("PaidBack");
+				$multicurrencyalreadypayedlabel=$langs->trans('MulticurrencyReceived');
+				if ($facture->type == 2) { $alreadypayedlabel=$langs->trans("PaidBack"); $multicurrencyalreadypayedlabel=$langs->trans("MulticurrencyPaidBack"); }
 				$remaindertopay=$langs->trans('RemainderToTake');
-				if ($facture->type == 2) $remaindertopay=$langs->trans("RemainderToPayBack");
+				$multicurrencyremaindertopay=$langs->trans('MulticurrencyRemainderToTake');
+				if ($facture->type == 2) { $remaindertopay=$langs->trans("RemainderToPayBack"); $multicurrencyremaindertopay=$langs->trans("MulticurrencyRemainderToPayBack"); }
 
                 $i = 0;
                 //print '<tr><td colspan="3">';
@@ -513,9 +562,13 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                 print '<td>'.$arraytitle.'</td>';
                 print '<td align="center">'.$langs->trans('Date').'</td>';
                 print '<td align="right">'.$langs->trans('AmountTTC').'</td>';
+                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
                 print '<td align="right">'.$alreadypayedlabel.'</td>';
+                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$multicurrencyalreadypayedlabel.'</td>';
                 print '<td align="right">'.$remaindertopay.'</td>';
+                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$multicurrencyremaindertopay.'</td>';
                 print '<td align="right">'.$langs->trans('PaymentAmount').'</td>';
+                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyPaymentAmount').'</td>';
                 print '<td align="right">&nbsp;</td>';
                 print "</tr>\n";
 
@@ -537,7 +590,17 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                     $deposits=$invoice->getSumDepositsUsed();
                     $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
                     $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
-
+					
+					// Multicurrency Price
+					if (!empty($conf->multicurrency->enabled)) 
+					{
+						$multicurrency_payment = $invoice->getSommePaiement(1);
+						$multicurrency_creditnotes=$invoice->getSumCreditNotesUsed(1);
+						$multicurrency_deposits=$invoice->getSumDepositsUsed(1);
+						$multicurrency_alreadypayed=price2num($multicurrency_payment + $multicurrency_creditnotes + $multicurrency_deposits,'MT');
+	                    $multicurrency_remaintopay=price2num($invoice->multicurrency_total_ttc - $multicurrency_payment - $multicurrency_creditnotes - $multicurrency_deposits,'MT');
+					}
+					
                     print '<tr '.$bc[$var].'>';
 
                     print '<td>';
@@ -549,17 +612,35 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
 
                     // Price
                     print '<td align="right">'.price($sign * $objp->total_ttc).'</td>';
-
+					
+					// Multicurrency Price
+					if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.price($sign * $objp->multicurrency_total_ttc).'</td>';
+					
                     // Received or paid back
                     print '<td align="right">'.price($sign * $paiement);
                     if ($creditnotes) print '+'.price($creditnotes);
                     if ($deposits) print '+'.price($deposits);
                     print '</td>';
 
+					// Multicurrency Price
+					if (!empty($conf->multicurrency->enabled)) 
+					{
+						print '<td align="right">'.price($sign * $multicurrency_payment);
+		                if ($multicurrency_creditnotes) print '+'.price($multicurrency_creditnotes);
+		                if ($multicurrency_deposits) print '+'.price($multicurrency_deposits);
+		                print '</td>';
+					}
+					
                     // Remain to take or to pay back
                     print '<td align="right">'.price($sign * $remaintopay).'</td>';
                     //$test= price(price2num($objp->total_ttc - $paiement - $creditnotes - $deposits));
 
+                    // Multicurrency Price
+					if (!empty($conf->multicurrency->enabled)) 
+					{
+						print '<td align="right">'.price($sign * $multicurrency_remaintopay).'</td>';
+					}
+                    
                     // Amount
                     print '<td align="right">';
 
@@ -571,8 +652,8 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                     {
 						if(!empty($conf->global->FAC_AUTO_FILLJS))
 							print img_picto("Auto fill",'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $remaintopay)."'");
-                        print '<input type=hidden name="'.$nameRemain.'" value="'.$remaintopay.'">';
-                        print '<input type="text" size="8" name="'.$namef.'" value="'.$_POST[$namef].'">';
+                        print '<input type=hidden class="remain" name="'.$nameRemain.'" value="'.$remaintopay.'">';
+                        print '<input type="text" size="8" class="amount" name="'.$namef.'" value="'.$_POST[$namef].'">';
                     }
                     else
                     {
@@ -581,10 +662,35 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                     }
                     print "</td>";
 
+					// Multicurrency Price
+					if (!empty($conf->multicurrency->enabled)) 
+					{
+						print '<td align="right">';
+						
+						// Add remind multicurrency amount
+	                    $namef = 'multicurrency_amount_'.$objp->facid;
+	                    $nameRemain = 'multicurrency_remain_'.$objp->facid;
+	
+	                    if ($action != 'add_paiement')
+	                    {
+							if(!empty($conf->global->FAC_AUTO_FILLJS))
+								print img_picto("Auto fill",'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'");
+	                        print '<input type=hidden class="multicurrency_remain" name="'.$nameRemain.'" value="'.$multicurrency_remaintopay.'">';
+	                        print '<input type="text" size="8" class="multicurrency_amount" name="'.$namef.'" value="'.$_POST[$namef].'">';
+	                    }
+	                    else
+	                    {
+	                        print '<input type="text" size="8" name="'.$namef.'_disabled" value="'.$_POST[$namef].'" disabled>';
+	                        print '<input type="hidden" name="'.$namef.'" value="'.$_POST[$namef].'">';
+	                    }
+	                    print "</td>";
+					}
+
                     // Warning
-                    print '<td align="center" width="16">';
+                    print '<td align="center" width="16">'; 
                     //print "xx".$amounts[$invoice->id]."-".$amountsresttopay[$invoice->id]."<br>";
-                    if ($amounts[$invoice->id] && (abs($amounts[$invoice->id]) > abs($amountsresttopay[$invoice->id])))
+                    if ($amounts[$invoice->id] && (abs($amounts[$invoice->id]) > abs($amountsresttopay[$invoice->id]))
+                    	|| $multicurrency_amounts[$invoice->id] && (abs($multicurrency_amounts[$invoice->id]) > abs($multicurrency_amountsresttopay[$invoice->id])))
                     {
                         print ' '.img_warning($langs->trans("PaymentHigherThanReminderToPay"));
                     }
@@ -608,12 +714,16 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                     print '<tr class="liste_total">';
                     print '<td colspan="2" align="left">'.$langs->trans('TotalTTC').'</td>';
                     print '<td align="right"><b>'.price($sign * $total_ttc).'</b></td>';
+					if (!empty($conf->multicurrency->enabled)) print '<td></td>';
                     print '<td align="right"><b>'.price($sign * $totalrecu);
                     if ($totalrecucreditnote) print '+'.price($totalrecucreditnote);
                     if ($totalrecudeposits) print '+'.price($totalrecudeposits);
                     print '</b></td>';
+					if (!empty($conf->multicurrency->enabled)) print '<td></td>';
                     print '<td align="right"><b>'.price($sign * price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits,'MT')).'</b></td>';
+					if (!empty($conf->multicurrency->enabled)) print '<td></td>';
                     print '<td align="right" id="result" style="font-weight: bold;"></td>';
+					if (!empty($conf->multicurrency->enabled)) print '<td align="right" id="multicurrency_result" style="font-weight: bold;"></td>';
                     print '<td align="center">&nbsp;</td>';
                     print "</tr>\n";
                 }
@@ -653,7 +763,11 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
             $preselectedchoice=$addwarning?'no':'yes';
 
             print '<br>';
-            $text=$langs->trans('ConfirmCustomerPayment',$totalpayment,$langs->trans("Currency".$conf->currency));
+            if (!empty($totalpayment)) $text=$langs->trans('ConfirmCustomerPayment',$totalpayment,$langs->trans("Currency".$conf->currency));
+			if (!empty($multicurrency_totalpayment)) 
+			{
+				$text.='<br />'.$langs->trans('ConfirmCustomerPayment',$multicurrency_totalpayment,$langs->trans("paymentInInvoiceCurrency"));
+			}
             if (GETPOST('closepaidinvoices'))
             {
                 $text.='<br>'.$langs->trans("AllCompletelyPayedInvoiceWillBeClosed");

+ 78 - 15
htdocs/compta/paiement/class/paiement.class.php

@@ -27,6 +27,7 @@
  *	\brief      File of class to manage payments of customers invoices
  */
 require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
+require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php';
 
 
 /**
@@ -51,6 +52,7 @@ class Paiement extends CommonObject
 	var $montant;
 	var $amount;            // Total amount of payment
 	var $amounts=array();   // Array of amounts
+	var $multicurrency_amounts=array();   // Array of amounts
 	var $author;
 	var $paiementid;	// Type de paiement. Stocke dans fk_paiement
 	// de llx_paiement qui est lie aux types de
@@ -148,21 +150,41 @@ class Paiement extends CommonObject
 		global $conf, $langs;
 
 		$error = 0;
-
-        $now=dol_now();
-
+		$way = $this->getWay();  
+		
+		$now=dol_now();
+		
         // Clean parameters
         $totalamount = 0;
+		$totalamount_converted = 0;
         $atleastonepaymentnotnull = 0;
-		foreach ($this->amounts as $key => $value)	// How payment is dispatch
+		
+		if ($way == 'dolibarr')
 		{
+			$amounts = &$this->amounts;
+			$amounts_to_update = &$this->multicurrency_amounts;
+		}
+		else
+		{
+			$amounts = &$this->multicurrency_amounts;
+			$amounts_to_update = &$this->amounts;
+		}
+		
+		foreach ($amounts as $key => $value)	// How payment is dispatch
+		{
+			$value_converted = Multicurrency::getAmountConversionFromInvoiceRate($key, $value, $way);
+			$totalamount_converted += $value_converted;
+			$amounts_to_update[$key] = price2num($value_converted, 'MT');
+			
 			$newvalue = price2num($value,'MT');
-			$this->amounts[$key] = $newvalue;
+			$amounts[$key] = $newvalue;
 			$totalamount += $newvalue;
 			if (! empty($newvalue)) $atleastonepaymentnotnull++;
 		}
+		
 		$totalamount = price2num($totalamount);
-
+		$totalamount_converted = price2num($totalamount_converted);
+		
 		// Check parameters
         if (empty($totalamount) && empty($atleastonepaymentnotnull))	 // We accept negative amounts for withdraw reject but not empty arrays
         {
@@ -174,9 +196,20 @@ class Paiement extends CommonObject
 
 		$ref = $this->getNextNumRef('');
 
-		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, fk_paiement, num_paiement, note, fk_user_creat)";
-		$sql.= " VALUES (".$conf->entity.", '".$ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$totalamount."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($this->note)."', ".$user->id.")";
+		if ($way == 'dolibarr')
+		{
+			$total = $totalamount;
+			$mtotal = $totalamount_converted; // Maybe use price2num with MT for the converted value
+		}
+		else
+		{
+			$total = $totalamount_converted; // Maybe use price2num with MT for the converted value
+			$mtotal = $totalamount;
+		}
 
+		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, fk_user_creat)";
+		$sql.= " VALUES (".$conf->entity.", '".$ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($this->note)."', ".$user->id.")";
+		
 		dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
 		$resql = $this->db->query($sql);
 		if ($resql)
@@ -190,9 +223,9 @@ class Paiement extends CommonObject
 				if (is_numeric($amount) && $amount <> 0)
 				{
 					$amount = price2num($amount);
-					$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'paiement_facture (fk_facture, fk_paiement, amount)';
-					$sql .= ' VALUES ('.$facid.', '. $this->id.', \''.$amount.'\')';
-
+					$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'paiement_facture (fk_facture, fk_paiement, amount, multicurrency_amount)';
+					$sql .= ' VALUES ('.$facid.', '. $this->id.', \''.$amount.'\', \''.$this->multicurrency_amounts[$key].'\')';
+		
 					dol_syslog(get_class($this).'::Create Amount line '.$key.' insert paiement_facture', LOG_DEBUG);
 					$resql=$this->db->query($sql);
 					if ($resql)
@@ -277,8 +310,9 @@ class Paiement extends CommonObject
 
 		if (! $error)
 		{
-		    $this->amount=$totalamount;
-		    $this->total=$totalamount;    // deprecated
+		    $this->amount=$total;
+		    $this->total=$total;    // deprecated
+		    $this->multicurrency_amount=$mtotal;
 			$this->db->commit();
 			return $this->id;
 		}
@@ -434,9 +468,13 @@ class Paiement extends CommonObject
 
             $acc = new Account($this->db);
             $result=$acc->fetch($this->fk_account);
-
-            $totalamount=$this->amount;
+			
+			$totalamount=$this->amount;
             if (empty($totalamount)) $totalamount=$this->total; // For backward compatibility
+            
+            // if dolibarr currency != bank currency then we received an amount in customer currency (currently I don't manage the case : my currency is USD, the customer currency is EUR and he paid me in GBP. Seems no sense for me)
+            if (!empty($conf->multicurrency->enabled) && $conf->currency != $acc->currency_code) $totalamount=$this->multicurrency_amount;
+			
             if ($mode == 'payment_supplier') $totalamount=-$totalamount;
 
             // Insert payment into llx_bank
@@ -858,6 +896,31 @@ class Paiement extends CommonObject
 		}
 	}
 
+	/**
+	 * 	get the right way of payment
+	 * 
+	 * 	@return 	string 	'dolibarr' if standard comportment or paid in dolibarr currency, 'customer' if payment received from multicurrency inputs
+	 */
+	function getWay()
+	{
+		global $conf;
+		
+		$way = 'dolibarr';
+		if (!empty($conf->multicurrency->enabled))
+		{
+			foreach ($this->multicurrency_amounts as $value)
+			{
+				if (!empty($value)) // one value found then payment is in invoice currency
+				{
+					$way = 'customer';
+					break;
+				}
+			}
+		}
+		
+		return $way;
+	}
+	
 	/**
 	 *  Initialise an instance with random values.
 	 *  Used to build previews or test instances.

+ 6 - 4
htdocs/core/class/commoninvoice.class.php

@@ -91,9 +91,10 @@ abstract class CommonInvoice extends CommonObject
 	/**
 	 * 	Return amount of payments already done
 	 *
-	 *	@return		int		Amount of payment already done, <0 if KO
+	 *  @param 		int 	$multicurrency 	Return multicurrency_amount instead of amount
+	 *	@return		int						Amount of payment already done, <0 if KO
 	 */
-	function getSommePaiement()
+	function getSommePaiement($multicurrency=0)
 	{
 		$table='paiement_facture';
 		$field='fk_facture';
@@ -103,7 +104,7 @@ abstract class CommonInvoice extends CommonObject
 			$field='fk_facturefourn';
 		}
 
-		$sql = 'SELECT sum(amount) as amount';
+		$sql = 'SELECT sum(amount) as amount, sum(multicurrency_amount) as multicurrency_amount';
 		$sql.= ' FROM '.MAIN_DB_PREFIX.$table;
 		$sql.= ' WHERE '.$field.' = '.$this->id;
 
@@ -113,7 +114,8 @@ abstract class CommonInvoice extends CommonObject
 		{
 			$obj = $this->db->fetch_object($resql);
 			$this->db->free($resql);
-			return $obj->amount;
+			if ($multicurrency) return $obj->multicurrency_amount;
+			else return $obj->amount;
 		}
 		else
 		{

+ 14 - 10
htdocs/core/class/discount.class.php

@@ -371,12 +371,13 @@ class DiscountAbsolute
     /**
      *  Return amount (with tax) of all credit notes and deposits invoices used by invoice
      *
-     *	@param		Facture		$invoice	Object invoice
-     *	@return		int						<0 if KO, Sum of credit notes and deposits amount otherwise
+     *	@param		Facture		$invoice		Object invoice
+	 *	@param		int			$multicurrency	Return multicurrency_amount instead of amount
+     *	@return		int							<0 if KO, Sum of credit notes and deposits amount otherwise
      */
-    function getSumCreditNotesUsed($invoice)
+    function getSumCreditNotesUsed($invoice, $multicurrency=0)
     {
-        $sql = 'SELECT sum(rc.amount_ttc) as amount';
+        $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 as f';
         $sql.= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = '.$invoice->id;
         $sql.= ' AND f.type = 2';
@@ -386,7 +387,8 @@ class DiscountAbsolute
         if ($resql)
         {
             $obj = $this->db->fetch_object($resql);
-            return $obj->amount;
+            if ($multicurrency) return $obj->multicurrency_amount;
+			else return $obj->amount;
         }
         else
         {
@@ -397,12 +399,13 @@ class DiscountAbsolute
     /**
      *  Return amount (with tax) of all deposits invoices used by invoice
      *
-     *	@param		Facture		$invoice	Object invoice
-     *	@return		int						<0 if KO, Sum of credit notes and deposits amount otherwise
+     *	@param		Facture		$invoice		Object invoice
+	 *  @param 		int 		$multicurrency 	Return multicurrency_amount instead of amount
+     *	@return		int							<0 if KO, Sum of credit notes and deposits amount otherwise
      */
-    function getSumDepositsUsed($invoice)
+    function getSumDepositsUsed($invoice, $multicurrency=0)
     {
-        $sql = 'SELECT sum(rc.amount_ttc) as amount';
+        $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 as f';
         $sql.= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = '.$invoice->id;
         $sql.= ' AND f.type = 3';
@@ -412,7 +415,8 @@ class DiscountAbsolute
         if ($resql)
         {
             $obj = $this->db->fetch_object($resql);
-            return $obj->amount;
+            if ($multicurrency) return $obj->multicurrency_amount;
+			else return $obj->amount;
         }
         else
         {

+ 8 - 1
htdocs/install/mysql/migration/3.9.0-4.0.0.sql

@@ -211,4 +211,11 @@ ALTER TABLE llx_propaldet ADD COLUMN multicurrency_total_ht double(24,8) DEFAULT
 ALTER TABLE llx_propaldet ADD COLUMN multicurrency_total_tva double(24,8) DEFAULT 0;
 ALTER TABLE llx_propaldet ADD COLUMN multicurrency_total_ttc double(24,8) DEFAULT 0;
  
- 
+ALTER TABLE llx_paiement ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0;
+ALTER TABLE llx_paiement_facture ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0;
+ALTER TABLE llx_paiementfourn_facturefourn ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0;
+
+ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ht double(24,8) NOT NULL;
+ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_tva double(24,8) DEFAULT 0 NOT NULL;
+ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ttc double(24,8) DEFAULT 0 NOT NULL;
+

+ 2 - 1
htdocs/install/mysql/tables/llx_paiement.sql

@@ -26,7 +26,8 @@ create table llx_paiement
   datec            datetime,							-- date de creation
   tms              timestamp,
   datep            datetime,							-- payment date
-  amount           double(24,8) DEFAULT 0,
+  amount           double(24,8) DEFAULT 0,				-- amount paid in Dolibarr currency
+  multicurrency_amount double(24,8) DEFAULT 0,			-- amount paid in invoice currency	
   fk_paiement      integer NOT NULL,
   num_paiement     varchar(50),
   note             text,

+ 3 - 0
htdocs/install/mysql/tables/llx_societe_remise_except.sql

@@ -33,4 +33,7 @@ create table llx_societe_remise_except
   fk_facture			integer,
   fk_facture_source		integer,
   description			text NOT NULL
+  multicurrency_amount_ht	double(24,8) NOT NULL,
+  multicurrency_amount_tva	double(24,8) DEFAULT 0 NOT NULL,
+  multicurrency_amount_ttc	double(24,8) DEFAULT 0 NOT NULL,
 )ENGINE=innodb;

+ 1 - 0
htdocs/langs/en_US/bills.lang

@@ -58,6 +58,7 @@ Payment=Payment
 PaymentBack=Payment back
 Payments=Payments
 PaymentsBack=Payments back
+paymentInInvoiceCurrency=in invoices currency
 PaidBack=Paid back
 DeletePayment=Delete payment
 ConfirmDeletePayment=Are you sure you want to delete this payment ?

+ 45 - 1
htdocs/multicurrency/class/multicurrency.class.php

@@ -475,7 +475,51 @@ class MultiCurrency extends CommonObject
 		$resql = $db->query($sql);
 		if ($resql && $obj = $db->fetch_object($resql)) return array($obj->rowid, $obj->rate);
 		else return array(0, 1);
-	 }
+	 }  
+	 
+	 /**
+	  * Get the conversion of amount with invoice rate
+	  * 
+	  * @param	int		$fk_facture		id of facture
+	  * @param	double	$amount			amount to convert
+	  * @param	string	$way			dolibarr mean the amount is in dolibarr currency
+	  * @param	string	$table			facture or facture_fourn
+	  * 
+	  * @return	double					amount converted
+	  */
+	  public static function getAmountConversionFromInvoiceRate($fk_facture, $amount, $way='dolibarr', $table='facture')
+	  {
+		 global $db;
+		 
+		 $multicurrency_tx = self::getInvoiceRate($fk_facture, $table);
+		 
+		 if ($multicurrency_tx) 
+		 {
+		 	if ($way == 'dolibarr') return $amount * $multicurrency_tx;
+			else return $amount / $multicurrency_tx;
+		 }
+		 else return $amount;
+	  }
+	  
+	  /**
+	   *  Get current invoite rate
+	   * 
+	   *  @param	int 	$fk_facture 	id of facture
+	   *  @param 	string 	$table 			facture or facture_fourn
+	   */
+	   public static function getInvoiceRate($fk_facture, $table='facture')
+	   {
+		 global $db;
+		 
+		 $sql = 'SELECT multicurrency_tx FROM '.MAIN_DB_PREFIX.$table.' WHERE rowid = '.$fk_facture;
+		 $resql = $db->query($sql);
+		 if ($resql && ($line = $db->fetch_object($resql)))
+		 {
+		 	return $line->multicurrency_tx;
+		 }
+		 
+		 return false;
+	   }
 }
 
 /**