dolibarr  9.0.0
paiement.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
5  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
6  * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
7  * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
8  * Copyright (C) 2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
9  * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
10  * Copyright (C) 2015 Juanjo Menent <jmenent@2byte.es>
11  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
33 require '../main.inc.php';
34 require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
38 
39 // Load translation files required by the page
40 $langs->loadLangs(array('companies', 'bills', 'banks', 'multicurrency'));
41 
42 $action = GETPOST('action','alpha');
43 $confirm = GETPOST('confirm');
44 
45 $facid = GETPOST('facid','int');
46 $socname = GETPOST('socname');
47 $accountid = GETPOST('accountid');
48 $paymentnum = GETPOST('num_paiement');
49 
50 $sortfield = GETPOST('sortfield','alpha');
51 $sortorder = GETPOST('sortorder','alpha');
52 $page = GETPOST('page','int');
53 
54 $amounts=array();
55 $amountsresttopay=array();
56 $addwarning=0;
57 
58 $multicurrency_amounts=array();
59 $multicurrency_amountsresttopay=array();
60 
61 // Security check
62 $socid=0;
63 if ($user->societe_id > 0)
64 {
65  $socid = $user->societe_id;
66 }
67 
68 $object=new Facture($db);
69 
70 // Load object
71 if ($facid > 0)
72 {
73  $ret=$object->fetch($facid);
74 }
75 
76 // Initialize technical object to manage hooks of paiements. Note that conf->hooks_modules contains array array
77 $hookmanager->initHooks(array('paiementcard','globalcard'));
78 
79 
80 /*
81  * Actions
82  */
83 
84 $parameters=array('socid'=>$socid);
85 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
86 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
87 
88 if (empty($reshook))
89 {
90  if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm == 'yes'))
91  {
92  $error = 0;
93 
94  $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth','int'), GETPOST('reday','int'), GETPOST('reyear','int'));
95  $paiement_id = 0;
96  $totalpayment = 0;
97  $multicurrency_totalpayment = 0;
98  $atleastonepaymentnotnull = 0;
99 
100  // Generate payment array and check if there is payment higher than invoice and payment date before invoice date
101  $tmpinvoice=new Facture($db);
102  foreach ($_POST as $key => $value)
103  {
104  if (substr($key,0,7) == 'amount_' && GETPOST($key) != '')
105  {
106  $cursorfacid = substr($key,7);
107  $amounts[$cursorfacid] = price2num(trim(GETPOST($key)));
108  $totalpayment = $totalpayment + $amounts[$cursorfacid];
109  if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++;
110  $result=$tmpinvoice->fetch($cursorfacid);
111  if ($result <= 0) dol_print_error($db);
112  $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement());
113  if ($amounts[$cursorfacid])
114  {
115  // Check amount
116  if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid])))
117  {
118  $addwarning=1;
119  $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay");
120  }
121  // Check date
122  if ($datepaye && ($datepaye < $tmpinvoice->date))
123  {
124  $langs->load("errors");
125  //$error++;
126  setEventMessages($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), null, 'warnings');
127  }
128  }
129 
130  $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]);
131  }
132  elseif (substr($key,0,21) == 'multicurrency_amount_')
133  {
134  $cursorfacid = substr($key,21);
135  $multicurrency_amounts[$cursorfacid] = price2num(trim(GETPOST($key)));
136  $multicurrency_totalpayment += $multicurrency_amounts[$cursorfacid];
137  if (! empty($multicurrency_amounts[$cursorfacid])) $atleastonepaymentnotnull++;
138  $result=$tmpinvoice->fetch($cursorfacid);
139  if ($result <= 0) dol_print_error($db);
140  $multicurrency_amountsresttopay[$cursorfacid]=price2num($tmpinvoice->multicurrency_total_ttc - $tmpinvoice->getSommePaiement(1));
141  if ($multicurrency_amounts[$cursorfacid])
142  {
143  // Check amount
144  if ($multicurrency_amounts[$cursorfacid] && (abs($multicurrency_amounts[$cursorfacid]) > abs($multicurrency_amountsresttopay[$cursorfacid])))
145  {
146  $addwarning=1;
147  $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay");
148  }
149  // Check date
150  if ($datepaye && ($datepaye < $tmpinvoice->date))
151  {
152  $langs->load("errors");
153  //$error++;
154  setEventMessages($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), null, 'warnings');
155  }
156  }
157 
158  $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => GETPOST($key, 'int'));
159  }
160  }
161 
162  // Check parameters
163  if (! GETPOST('paiementcode'))
164  {
165  setEventMessages($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), null, 'errors');
166  $error++;
167  }
168 
169  if (! empty($conf->banque->enabled))
170  {
171  // If bank module is on, account is required to enter a payment
172  if (GETPOST('accountid') <= 0)
173  {
174  setEventMessages($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), null, 'errors');
175  $error++;
176  }
177  }
178 
179  if (empty($totalpayment) && empty($multicurrency_totalpayment) && empty($atleastonepaymentnotnull))
180  {
181  setEventMessages($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), null, 'errors');
182  $error++;
183  }
184 
185  if (empty($datepaye))
186  {
187  setEventMessages($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), null, 'errors');
188  $error++;
189  }
190 
191  // Check if payments in both currency
192  if ($totalpayment > 0 && $multicurrency_totalpayment > 0)
193  {
194  setEventMessages($langs->transnoentities('ErrorPaymentInBothCurrency'), null, 'errors');
195  $error++;
196  }
197  }
198 
199  /*
200  * Action add_paiement
201  */
202  if ($action == 'add_paiement')
203  {
204  if ($error)
205  {
206  $action = 'create';
207  }
208  // Le reste propre a cette action s'affiche en bas de page.
209  }
210 
211  /*
212  * Action confirm_paiement
213  */
214  if ($action == 'confirm_paiement' && $confirm == 'yes')
215  {
216  $error=0;
217 
218  $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
219 
220  $db->begin();
221 
222  // Clean parameters amount if payment is for a credit note
223  if (GETPOST('type') == Facture::TYPE_CREDIT_NOTE)
224  {
225  foreach ($amounts as $key => $value) // How payment is dispatch
226  {
227  $newvalue = price2num($value,'MT');
228  $amounts[$key] = -$newvalue;
229  }
230 
231  foreach ($multicurrency_amounts as $key => $value) // How payment is dispatch
232  {
233  $newvalue = price2num($value,'MT');
234  $multicurrency_amounts[$key] = -$newvalue;
235  }
236  }
237 
238  if (! empty($conf->banque->enabled))
239  {
240  // Si module bank actif, un compte est obligatoire lors de la saisie d'un paiement
241  if (GETPOST('accountid') <= 0)
242  {
243  setEventMessages($langs->trans('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), null, 'errors');
244  $error++;
245  }
246  }
247 
248  // Creation of payment line
249  $paiement = new Paiement($db);
250  $paiement->datepaye = $datepaye;
251  $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id
252  $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
253  $paiement->paiementid = dol_getIdFromCode($db,GETPOST('paiementcode'),'c_paiement','code','id',1);
254  $paiement->num_paiement = GETPOST('num_paiement');
255  $paiement->note = GETPOST('comment');
256 
257  if (! $error)
258  {
259  $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0)); // This include closing invoices and regenerating documents
260  if ($paiement_id < 0)
261  {
262  setEventMessages($paiement->error, $paiement->errors, 'errors');
263  $error++;
264  }
265  }
266 
267  if (! $error)
268  {
269  $label='(CustomerInvoicePayment)';
270  if (GETPOST('type') == Facture::TYPE_CREDIT_NOTE) $label='(CustomerInvoicePaymentBack)'; // Refund of a credit note
271  $result=$paiement->addPaymentToBank($user,'payment',$label,GETPOST('accountid'),GETPOST('chqemetteur'),GETPOST('chqbank'));
272  if ($result < 0)
273  {
274  setEventMessages($paiement->error, $paiement->errors, 'errors');
275  $error++;
276  }
277  }
278 
279  if (! $error)
280  {
281  $db->commit();
282 
283  // If payment dispatching on more than one invoice, we keep on summary page, otherwise jump on invoice card
284  $invoiceid=0;
285  foreach ($paiement->amounts as $key => $amount)
286  {
287  $facid = $key;
288  if (is_numeric($amount) && $amount <> 0)
289  {
290  if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment
291  else $invoiceid=$facid;
292  }
293  }
294  if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture/card.php?facid='.$invoiceid;
295  else $loc = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$paiement_id;
296  header('Location: '.$loc);
297  exit;
298  }
299  else
300  {
301  $db->rollback();
302  }
303  }
304 }
305 
306 
307 /*
308  * View
309  */
310 
311 $form=new Form($db);
312 
313 
314 llxHeader('', $langs->trans("Payment"));
315 
316 
317 
318 if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paiement')
319 {
320  $facture = new Facture($db);
321  $result = $facture->fetch($facid);
322 
323  if ($result >= 0)
324  {
325  $facture->fetch_thirdparty();
326 
327  $title='';
328  if ($facture->type != Facture::TYPE_CREDIT_NOTE) $title.=$langs->trans("EnterPaymentReceivedFromCustomer");
329  if ($facture->type == Facture::TYPE_CREDIT_NOTE) $title.=$langs->trans("EnterPaymentDueToCustomer");
330  print load_fiche_titre($title);
331 
332  // Initialize data for confirmation (this is used because data can be change during confirmation)
333  if ($action == 'add_paiement')
334  {
335  $i=0;
336 
337  $formquestion[$i++]=array('type' => 'hidden','name' => 'facid', 'value' => $facture->id);
338  $formquestion[$i++]=array('type' => 'hidden','name' => 'socid', 'value' => $facture->socid);
339  $formquestion[$i++]=array('type' => 'hidden','name' => 'type', 'value' => $facture->type);
340  }
341 
342  // Invoice with Paypal transaction
343  // TODO add hook possibility (regis)
344  if (! empty($conf->paypalplus->enabled) && $conf->global->PAYPAL_ENABLE_TRANSACTION_MANAGEMENT && ! empty($facture->ref_int))
345  {
346  if (! empty($conf->global->PAYPAL_BANK_ACCOUNT)) $accountid=$conf->global->PAYPAL_BANK_ACCOUNT;
347  $paymentnum=$facture->ref_int;
348  }
349 
350  // Add realtime total information
351  if (! empty($conf->use_javascript_ajax))
352  {
353  print "\n".'<script type="text/javascript" language="javascript">';
354  print '$(document).ready(function () {
355  setPaiementCode();
356 
357  $("#selectpaiementcode").change(function() {
358  setPaiementCode();
359  });
360 
361  function setPaiementCode()
362  {
363  var code = $("#selectpaiementcode option:selected").val();
364 
365  if (code == \'CHQ\' || code == \'VIR\')
366  {
367  if (code == \'CHQ\')
368  {
369  $(\'.fieldrequireddyn\').addClass(\'fieldrequired\');
370  }
371  if ($(\'#fieldchqemetteur\').val() == \'\')
372  {
373  var emetteur = ('.$facture->type.' == '.Facture::TYPE_CREDIT_NOTE.') ? \''.dol_escape_js(dol_escape_htmltag($conf->global->MAIN_INFO_SOCIETE_NOM)).'\' : jQuery(\'#thirdpartylabel\').val();
374  $(\'#fieldchqemetteur\').val(emetteur);
375  }
376  }
377  else
378  {
379  $(\'.fieldrequireddyn\').removeClass(\'fieldrequired\');
380  $(\'#fieldchqemetteur\').val(\'\');
381  }
382  }
383 
384  function _elemToJson(selector)
385  {
386  var subJson = {};
387  $.map(selector.serializeArray(), function(n,i)
388  {
389  subJson[n["name"]] = n["value"];
390  });
391 
392  return subJson;
393  }
394  function callForResult(imgId)
395  {
396  var json = {};
397  var form = $("#payment_form");
398 
399  json["invoice_type"] = $("#invoice_type").val();
400  json["amountPayment"] = $("#amountpayment").attr("value");
401  json["amounts"] = _elemToJson(form.find("input.amount"));
402  json["remains"] = _elemToJson(form.find("input.remain"));
403 
404  if (imgId != null) {
405  json["imgClicked"] = imgId;
406  }
407 
408  $.post("'.DOL_URL_ROOT.'/compta/ajaxpayment.php", json, function(data)
409  {
410  json = $.parseJSON(data);
411 
412  form.data(json);
413 
414  for (var key in json)
415  {
416  if (key == "result") {
417  if (json["makeRed"]) {
418  $("#"+key).addClass("error");
419  } else {
420  $("#"+key).removeClass("error");
421  }
422  json[key]=json["label"]+" "+json[key];
423  $("#"+key).text(json[key]);
424  } else {console.log(key);
425  form.find("input[name*=\""+key+"\"]").each(function() {
426  $(this).attr("value", json[key]);
427  });
428  }
429  }
430  });
431  }
432  $("#payment_form").find("input.amount").change(function() {
433  callForResult();
434  });
435  $("#payment_form").find("input.amount").keyup(function() {
436  callForResult();
437  });
438  ';
439 
440  print ' });'."\n";
441 
442  //Add js for AutoFill
443  print ' $(document).ready(function () {';
444  print ' $(".AutoFillAmout").on(\'click touchstart\', function(){
445  $("input[name="+$(this).data(\'rowname\')+"]").val($(this).data("value")).trigger("change");
446  });';
447  print ' });'."\n";
448 
449  print ' </script>'."\n";
450  }
451 
452  print '<form id="payment_form" name="add_paiement" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
453  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
454  print '<input type="hidden" name="action" value="add_paiement">';
455  print '<input type="hidden" name="facid" value="'.$facture->id.'">';
456  print '<input type="hidden" name="socid" value="'.$facture->socid.'">';
457  print '<input type="hidden" name="type" id="invoice_type" value="'.$facture->type.'">';
458  print '<input type="hidden" name="thirdpartylabel" id="thirdpartylabel" value="'.dol_escape_htmltag($facture->thirdparty->name).'">';
459 
460  dol_fiche_head();
461 
462  print '<table class="border" width="100%">';
463 
464  // Third party
465  print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans('Company').'</span></td><td>'.$facture->thirdparty->getNomUrl(4)."</td></tr>\n";
466 
467  // Date payment
468  print '<tr><td><span class="fieldrequired">'.$langs->trans('Date').'</span></td><td>';
469  $datepayment = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
470  $datepayment= ($datepayment == '' ? (empty($conf->global->MAIN_AUTOFILL_DATE)?-1:'') : $datepayment);
471  print $form->selectDate($datepayment, '', '', '', 0, "add_paiement", 1, 1, 0, '', '', $facture->date);
472  print '</td></tr>';
473 
474  // Payment mode
475  print '<tr><td><span class="fieldrequired">'.$langs->trans('PaymentMode').'</span></td><td>';
476  $form->select_types_paiements((GETPOST('paiementcode')?GETPOST('paiementcode'):$facture->mode_reglement_code),'paiementcode','',2);
477  print "</td>\n";
478  print '</tr>';
479 
480  // Bank account
481  print '<tr>';
482  if (! empty($conf->banque->enabled))
483  {
484  if ($facture->type != 2) print '<td><span class="fieldrequired">'.$langs->trans('AccountToCredit').'</span></td>';
485  if ($facture->type == 2) print '<td><span class="fieldrequired">'.$langs->trans('AccountToDebit').'</span></td>';
486  print '<td>';
487  $form->select_comptes($accountid,'accountid',0,'',2);
488  print '</td>';
489  }
490  else
491  {
492  print '<td>&nbsp;</td>';
493  }
494  print "</tr>\n";
495 
496  // Cheque number
497  print '<tr><td>'.$langs->trans('Numero');
498  print ' <em>('.$langs->trans("ChequeOrTransferNumber").')</em>';
499  print '</td>';
500  print '<td><input name="num_paiement" type="text" value="'.$paymentnum.'"></td></tr>';
501 
502  // Check transmitter
503  print '<tr><td class="'.(GETPOST('paiementcode')=='CHQ'?'fieldrequired ':'').'fieldrequireddyn">'.$langs->trans('CheckTransmitter');
504  print ' <em>('.$langs->trans("ChequeMaker").')</em>';
505  print '</td>';
506  print '<td><input id="fieldchqemetteur" name="chqemetteur" size="30" type="text" value="'.GETPOST('chqemetteur','alphanohtml').'"></td></tr>';
507 
508  // Bank name
509  print '<tr><td>'.$langs->trans('Bank');
510  print ' <em>('.$langs->trans("ChequeBank").')</em>';
511  print '</td>';
512  print '<td><input name="chqbank" size="30" type="text" value="'.GETPOST('chqbank','alphanohtml').'"></td></tr>';
513 
514  // Comments
515  print '<tr><td>'.$langs->trans('Comments').'</td>';
516  print '<td class="tdtop">';
517  print '<textarea name="comment" wrap="soft" class="quatrevingtpercent" rows="'.ROWS_3.'">'.GETPOST('comment','none').'</textarea></td></tr>';
518 
519  print '</table>';
520 
521  dol_fiche_end();
522 
523 
524  /*
525  * List of unpaid invoices
526  */
527 
528  $sql = 'SELECT f.rowid as facid, f.facnumber, f.total_ttc, f.multicurrency_code, f.multicurrency_total_ttc, f.type,';
529  $sql.= ' f.datef as df, f.fk_soc as socid, f.date_lim_reglement as dlr';
530  $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
531  $sql.= ' WHERE f.entity IN ('.getEntity('facture', $conf->entity).')';
532  $sql.= ' AND (f.fk_soc = '.$facture->socid;
533  // Can pay invoices of all child of parent company
534  if(!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS) && !empty($facture->thirdparty->parent)) {
535  $sql.= ' OR f.fk_soc IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'societe WHERE parent = '.$facture->thirdparty->parent.')';
536  }
537  // Can pay invoices of all child of myself
538  if(!empty($conf->global->FACTURE_PAYMENTS_ON_SUBSIDIARY_COMPANIES)){
539  $sql.= ' OR f.fk_soc IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'societe WHERE parent = '.$facture->thirdparty->id.')';
540  }
541  $sql.= ') AND f.paye = 0';
542  $sql.= ' AND f.fk_statut = 1'; // Statut=0 => not validated, Statut=2 => canceled
543  if ($facture->type != 2)
544  {
545  $sql .= ' AND type IN (0,1,3,5)'; // Standard invoice, replacement, deposit, situation
546  }
547  else
548  {
549  $sql .= ' AND type = 2'; // If paying back a credit note, we show all credit notes
550  }
551 
552  // Sort invoices by date and serial number: the older one comes first
553  $sql.=' ORDER BY f.datef ASC, f.facnumber ASC';
554 
555  $resql = $db->query($sql);
556  if ($resql)
557  {
558  $num = $db->num_rows($resql);
559  if ($num > 0)
560  {
561  $sign=1;
562  if ($facture->type == 2) $sign=-1;
563 
564  $arraytitle=$langs->trans('Invoice');
565  if ($facture->type == 2) $arraytitle=$langs->trans("CreditNotes");
566  $alreadypayedlabel=$langs->trans('Received');
567  $multicurrencyalreadypayedlabel=$langs->trans('MulticurrencyReceived');
568  if ($facture->type == 2) { $alreadypayedlabel=$langs->trans("PaidBack"); $multicurrencyalreadypayedlabel=$langs->trans("MulticurrencyPaidBack"); }
569  $remaindertopay=$langs->trans('RemainderToTake');
570  $multicurrencyremaindertopay=$langs->trans('MulticurrencyRemainderToTake');
571  if ($facture->type == 2) { $remaindertopay=$langs->trans("RemainderToPayBack"); $multicurrencyremaindertopay=$langs->trans("MulticurrencyRemainderToPayBack"); }
572 
573  $i = 0;
574  //print '<tr><td colspan="3">';
575  print '<br>';
576  print '<table class="noborder" width="100%">';
577 
578  print '<tr class="liste_titre">';
579  print '<td>'.$arraytitle.'</td>';
580  print '<td align="center">'.$langs->trans('Date').'</td>';
581  print '<td align="center">'.$langs->trans('DateMaxPayment').'</td>';
582  if (!empty($conf->multicurrency->enabled)) {
583  print '<td>'.$langs->trans('Currency').'</td>';
584  print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
585  print '<td align="right">'.$multicurrencyalreadypayedlabel.'</td>';
586  print '<td align="right">'.$multicurrencyremaindertopay.'</td>';
587  print '<td align="right">'.$langs->trans('MulticurrencyPaymentAmount').'</td>';
588  }
589  print '<td align="right">'.$langs->trans('AmountTTC').'</td>';
590  print '<td align="right">'.$alreadypayedlabel.'</td>';
591  print '<td align="right">'.$remaindertopay.'</td>';
592  print '<td align="right">'.$langs->trans('PaymentAmount').'</td>';
593  print '<td align="right">&nbsp;</td>';
594  print "</tr>\n";
595 
596  $total=0;
597  $totalrecu=0;
598  $totalrecucreditnote=0;
599  $totalrecudeposits=0;
600 
601  while ($i < $num)
602  {
603  $objp = $db->fetch_object($resql);
604 
605  $soc = new Societe($db);
606  $soc->fetch($objp->socid);
607 
608  $invoice=new Facture($db);
609  $invoice->fetch($objp->facid);
610  $paiement = $invoice->getSommePaiement();
611  $creditnotes=$invoice->getSumCreditNotesUsed();
612  $deposits=$invoice->getSumDepositsUsed();
613  $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
614  $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
615 
616  // Multicurrency Price
617  if (!empty($conf->multicurrency->enabled)) {
618  $multicurrency_payment = $invoice->getSommePaiement(1);
619  $multicurrency_creditnotes=$invoice->getSumCreditNotesUsed(1);
620  $multicurrency_deposits=$invoice->getSumDepositsUsed(1);
621  $multicurrency_alreadypayed=price2num($multicurrency_payment + $multicurrency_creditnotes + $multicurrency_deposits,'MT');
622  $multicurrency_remaintopay=price2num($invoice->multicurrency_total_ttc - $multicurrency_payment - $multicurrency_creditnotes - $multicurrency_deposits,'MT');
623  }
624 
625  print '<tr class="oddeven">';
626 
627  print '<td>';
628  print $invoice->getNomUrl(1,'');
629  if($objp->socid != $facture->thirdparty->id) print ' - '.$soc->getNomUrl(1).' ';
630  print "</td>\n";
631 
632  // Date
633  print '<td align="center">'.dol_print_date($db->jdate($objp->df),'day')."</td>\n";
634 
635  // Date Max Payment
636  if ($objp->dlr > 0 )
637  {
638  print '<td align="center">';
639  print dol_print_date($db->jdate($objp->dlr), 'day');
640 
641  if ($invoice->hasDelay())
642  {
643  print img_warning($langs->trans('Late'));
644  }
645 
646  print '</td>';
647  }
648  else
649  {
650  print '<td align="center"><b>--</b></td>';
651  }
652 
653  // Currency
654  if (!empty($conf->multicurrency->enabled)) print '<td align="center">'.$objp->multicurrency_code."</td>\n";
655 
656  // Multicurrency Price
657  if (!empty($conf->multicurrency->enabled))
658  {
659  print '<td align="right">';
660  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) print price($sign * $objp->multicurrency_total_ttc);
661  print '</td>';
662 
663  // Multicurrency Price
664  print '<td align="right">';
665  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency)
666  {
667  print price($sign * $multicurrency_payment);
668  if ($multicurrency_creditnotes) print '+'.price($multicurrency_creditnotes);
669  if ($multicurrency_deposits) print '+'.price($multicurrency_deposits);
670  }
671  print '</td>';
672 
673  // Multicurrency Price
674  print '<td align="right">';
675  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) print price($sign * $multicurrency_remaintopay);
676  print '</td>';
677 
678  print '<td align="right">';
679 
680  // Add remind multicurrency amount
681  $namef = 'multicurrency_amount_'.$objp->facid;
682  $nameRemain = 'multicurrency_remain_'.$objp->facid;
683 
684  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency)
685  {
686  if ($action != 'add_paiement')
687  {
688  if (!empty($conf->use_javascript_ajax))
689  print img_picto("Auto fill",'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'");
690  print '<input type=hidden class="multicurrency_remain" name="'.$nameRemain.'" value="'.$multicurrency_remaintopay.'">';
691  print '<input type="text" size="8" class="multicurrency_amount" name="'.$namef.'" value="'.$_POST[$namef].'">';
692  }
693  else
694  {
695  print '<input type="text" size="8" name="'.$namef.'_disabled" value="'.$_POST[$namef].'" disabled>';
696  print '<input type="hidden" name="'.$namef.'" value="'.$_POST[$namef].'">';
697  }
698  }
699  print "</td>";
700  }
701 
702  // Price
703  print '<td align="right">'.price($sign * $objp->total_ttc).'</td>';
704 
705  // Received or paid back
706  print '<td align="right">'.price($sign * $paiement);
707  if ($creditnotes) print '+'.price($creditnotes);
708  if ($deposits) print '+'.price($deposits);
709  print '</td>';
710 
711  // Remain to take or to pay back
712  print '<td align="right">'.price($sign * $remaintopay).'</td>';
713  //$test= price(price2num($objp->total_ttc - $paiement - $creditnotes - $deposits));
714 
715  // Amount
716  print '<td align="right">';
717 
718  // Add remind amount
719  $namef = 'amount_'.$objp->facid;
720  $nameRemain = 'remain_'.$objp->facid;
721 
722  if ($action != 'add_paiement')
723  {
724  if (!empty($conf->use_javascript_ajax))
725  print img_picto("Auto fill",'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $remaintopay)."'");
726  print '<input type="hidden" class="remain" name="'.$nameRemain.'" value="'.$remaintopay.'">';
727  print '<input type="text" size="8" class="amount" name="'.$namef.'" value="'.dol_escape_htmltag(GETPOST($namef)).'">';
728  }
729  else
730  {
731  print '<input type="text" size="8" name="'.$namef.'_disabled" value="'.dol_escape_htmltag(GETPOST($namef)).'" disabled>';
732  print '<input type="hidden" name="'.$namef.'" value="'.dol_escape_htmltag(GETPOST($namef)).'">';
733  }
734  print "</td>";
735 
736  // Warning
737  print '<td align="center" width="16">';
738  //print "xx".$amounts[$invoice->id]."-".$amountsresttopay[$invoice->id]."<br>";
739  if ($amounts[$invoice->id] && (abs($amounts[$invoice->id]) > abs($amountsresttopay[$invoice->id]))
740  || $multicurrency_amounts[$invoice->id] && (abs($multicurrency_amounts[$invoice->id]) > abs($multicurrency_amountsresttopay[$invoice->id])))
741  {
742  print ' '.img_warning($langs->trans("PaymentHigherThanReminderToPay"));
743  }
744  print '</td>';
745 
746  $parameters=array();
747  $reshook=$hookmanager->executeHooks('printObjectLine',$parameters,$objp,$action); // Note that $action and $object may have been modified by hook
748 
749  print "</tr>\n";
750 
751  $total+=$objp->total;
752  $total_ttc+=$objp->total_ttc;
753  $totalrecu+=$paiement;
754  $totalrecucreditnote+=$creditnotes;
755  $totalrecudeposits+=$deposits;
756  $i++;
757  }
758 
759  if ($i > 1)
760  {
761  // Print total
762  print '<tr class="liste_total">';
763  print '<td colspan="2" align="left">'.$langs->trans('TotalTTC').'</td>';
764  if (!empty($conf->multicurrency->enabled)) {
765  print '<td></td>';
766  print '<td></td>';
767  print '<td></td>';
768  print '<td></td>';
769  print '<td align="right" id="multicurrency_result" style="font-weight: bold;"></td>';
770  }
771  print '<td align="right"><b>'.price($sign * $total_ttc).'</b></td>';
772  print '<td align="right"><b>'.price($sign * $totalrecu);
773  if ($totalrecucreditnote) print '+'.price($totalrecucreditnote);
774  if ($totalrecudeposits) print '+'.price($totalrecudeposits);
775  print '</b></td>';
776  print '<td align="right"><b>'.price($sign * price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits,'MT')).'</b></td>';
777  print '<td align="right" id="result" style="font-weight: bold;"></td>'; // Autofilled
778  print '<td align="center">&nbsp;</td>';
779  print "</tr>\n";
780  }
781  print "</table>";
782  //print "</td></tr>\n";
783  }
784  $db->free($resql);
785  }
786  else
787  {
788  dol_print_error($db);
789  }
790 
791 
792  // Bouton Enregistrer
793  if ($action != 'add_paiement')
794  {
795  $checkboxlabel=$langs->trans("ClosePaidInvoicesAutomatically");
796  if ($facture->type == 2) $checkboxlabel=$langs->trans("ClosePaidCreditNotesAutomatically");
797  $buttontitle=$langs->trans('ToMakePayment');
798  if ($facture->type == 2) $buttontitle=$langs->trans('ToMakePaymentBack');
799 
800  print '<br><div class="center">';
801  print '<input type="checkbox" checked name="closepaidinvoices"> '.$checkboxlabel;
802  /*if (! empty($conf->prelevement->enabled))
803  {
804  $langs->load("withdrawals");
805  if (! empty($conf->global->WITHDRAW_DISABLE_AUTOCREATE_ONPAYMENTS)) print '<br>'.$langs->trans("IfInvoiceNeedOnWithdrawPaymentWontBeClosed");
806  }*/
807  print '<br><input type="submit" class="button" value="'.dol_escape_htmltag($buttontitle).'"><br><br>';
808  print '</div>';
809  }
810 
811  // Form to confirm payment
812  if ($action == 'add_paiement')
813  {
814  $preselectedchoice=$addwarning?'no':'yes';
815 
816  print '<br>';
817  if (!empty($totalpayment)) $text=$langs->trans('ConfirmCustomerPayment',$totalpayment,$langs->trans("Currency".$conf->currency));
818  if (!empty($multicurrency_totalpayment))
819  {
820  $text.='<br>'.$langs->trans('ConfirmCustomerPayment',$multicurrency_totalpayment,$langs->trans("paymentInInvoiceCurrency"));
821  }
822  if (GETPOST('closepaidinvoices'))
823  {
824  $text.='<br>'.$langs->trans("AllCompletelyPayedInvoiceWillBeClosed");
825  print '<input type="hidden" name="closepaidinvoices" value="'.GETPOST('closepaidinvoices').'">';
826  }
827  print $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$facture->id.'&socid='.$facture->socid.'&type='.$facture->type,$langs->trans('ReceivedCustomersPayments'),$text,'confirm_paiement',$formquestion,$preselectedchoice);
828  }
829 
830  print "</form>\n";
831  }
832 }
833 
834 
838 if (! GETPOST('action','aZ09'))
839 {
840  if ($page == -1) $page = 0 ;
841  $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
842  $offset = $limit * $page ;
843 
844  if (! $sortorder) $sortorder='DESC';
845  if (! $sortfield) $sortfield='p.datep';
846 
847  $sql = 'SELECT p.datep as dp, p.amount, f.amount as fa_amount, f.facnumber';
848  $sql.=', f.rowid as facid, c.libelle as paiement_type, p.num_paiement';
849  $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement as p LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
850  $sql.= ', '.MAIN_DB_PREFIX.'facture as f';
851  $sql.= ' WHERE p.fk_facture = f.rowid';
852  $sql.= ' AND f.entity IN (' . getEntity('facture').')';
853  if ($socid)
854  {
855  $sql.= ' AND f.fk_soc = '.$socid;
856  }
857 
858  $sql.= ' ORDER BY '.$sortfield.' '.$sortorder;
859  $sql.= $db->plimit($limit+1, $offset);
860  $resql = $db->query($sql);
861 
862  if ($resql)
863  {
864  $num = $db->num_rows($resql);
865  $i = 0;
866 
867  print_barre_liste($langs->trans('Payments'), $page, $_SERVER["PHP_SELF"],'',$sortfield,$sortorder,'',$num);
868  print '<table class="noborder" width="100%">';
869  print '<tr class="liste_titre">';
870  print_liste_field_titre('Invoice',$_SERVER["PHP_SELF"],'facnumber','','','',$sortfield,$sortorder);
871  print_liste_field_titre('Date',$_SERVER["PHP_SELF"],'dp','','','',$sortfield,$sortorder);
872  print_liste_field_titre('Type',$_SERVER["PHP_SELF"],'libelle','','','',$sortfield,$sortorder);
873  print_liste_field_titre('Amount',$_SERVER["PHP_SELF"],'fa_amount','','','align="right"',$sortfield,$sortorder);
874  print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch ');
875  print "</tr>\n";
876 
877  while ($i < min($num,$limit))
878  {
879  $objp = $db->fetch_object($resql);
880 
881  print '<tr class="oddeven">';
882  print '<td><a href="'.DOL_URL_ROOT.'/compta/facture/card.php?facid='.$objp->facid.'">'.$objp->facnumber."</a></td>\n";
883  print '<td>'.dol_print_date($db->jdate($objp->dp))."</td>\n";
884  print '<td>'.$objp->paiement_type.' '.$objp->num_paiement."</td>\n";
885  print '<td align="right">'.price($objp->amount).'</td><td>&nbsp;</td>';
886 
887  $parameters=array();
888  $reshook=$hookmanager->executeHooks('printObjectLine',$parameters,$objp,$action); // Note that $action and $object may have been modified by hook
889 
890  print '</tr>';
891  $i++;
892  }
893  print '</table>';
894  }
895 }
896 
897 llxFooter();
898 
899 $db->close();
img_warning($titlealt='default', $moreatt='')
Show warning logo.
llxFooter()
Empty footer.
Definition: wrapper.php:56
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
print
Draft customers invoices.
Definition: index.php:91
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->lire) if(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) if(! empty($conf->facture->enabled) &&! empty($conf->commande->enabled) && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm=false, $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0)
Return an id or code from a code or id.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage generation of HTML components Only common components must be here.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='title_generic.png', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0)
Print a title with navigation controls for pagination.
Class to manage third parties objects (customers, suppliers, prospects...)
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_fiche_end($notab=0)
Show tab footer of a card.
Class to manage payments of customer invoices.
llxHeader()
Empty header.
Definition: wrapper.php:44
if(GETPOST('cancel', 'alpha')) if(! GETPOST( 'confirmmassaction', 'alpha') &&$massaction !='presend' &&$massaction !='confirm_presend')
Draft customers invoices.
Definition: list.php:156
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="")
Show title line of an array.
Class to manage invoices.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it&#39;s its name (generic function)
price2num($amount, $rounding='', $alreadysqlnb=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='')
Show tab header of a card.