dolibarr  17.0.4
paiement.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
4  * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
5  * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
6  * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
7  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
8  * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
9  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
10  * Copyright (C) 2015 Juanjo Menent <jmenent@2byte.es>
11  * Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
12  * Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
13  * Copyright (C) 2021 Charlene Benke <charlene@patas-monkey.com>
14  * Copyright (C) 2022 Udo Tamm <dev@dolibit.de>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program. If not, see <https://www.gnu.org/licenses/>.
28  */
29 
36 // Load Dolibarr environment
37 require '../../main.inc.php';
38 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
39 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
41 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
43 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
44 
45 // Load translation files required by the page
46 $langs->loadLangs(array('companies', 'bills', 'banks', 'compta'));
47 
48 $action = GETPOST('action', 'alpha');
49 $confirm = GETPOST('confirm', 'alpha');
50 $optioncss = GETPOST('optioncss', 'alpha');
51 $cancel = GETPOST('cancel', 'alpha');
52 $backtopage = GETPOST('backtopage', 'alpha');
53 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
54 
55 $facid = GETPOST('facid', 'int');
56 $socid = GETPOST('socid', 'int');
57 $accountid = GETPOST('accountid', 'int');
58 $day = GETPOST('day', 'int');
59 $month = GETPOST('month', 'int');
60 $year = GETPOST('year', 'int');
61 
62 $search_ref = GETPOST('search_ref', 'alpha');
63 $search_account = GETPOST('search_account', 'int');
64 $search_paymenttype = GETPOST('search_paymenttype');
65 $search_amount = GETPOST('search_amount', 'alpha'); // alpha because we must be able to search on "< x"
66 $search_company = GETPOST('search_company', 'alpha');
67 $search_payment_num = GETPOST('search_payment_num', 'alpha');
68 
69 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
70 $sortfield = GETPOST('sortfield', 'aZ09comma');
71 $sortorder = GETPOST('sortorder', 'aZ09comma');
72 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
73 if (empty($page) || $page == -1) {
74  $page = 0;
75 } // If $page is not defined, or '' or -1
76 $offset = $limit * $page;
77 $pageprev = $page - 1;
78 $pagenext = $page + 1;
79 if (!$sortorder) {
80  $sortorder = "DESC";
81 }
82 if (!$sortfield) {
83  $sortfield = "p.rowid";
84 }
85 
86 $amounts = array();
87 $amountsresttopay = array();
88 $addwarning = 0;
89 
90 $multicurrency_amounts = array();
91 $multicurrency_amountsresttopay = array();
92 
93 // Security check
94 if ($user->socid > 0) {
95  $socid = $user->socid;
96 }
97 
98 $object = new PaiementFourn($db);
99 
100 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
101 $hookmanager->initHooks(array('paymentsupplierlist'));
102 $extrafields = new ExtraFields($db);
103 
104 // fetch optionals attributes and labels
105 $extrafields->fetch_name_optionals_label($object->table_element);
106 
107 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
108 
109 $arrayfields = array();
110 
111 
112 
113 /*
114  * Actions
115  */
116 
117 if ($cancel) {
118  if (!empty($backtopageforcancel)) {
119  header("Location: ".$backtopageforcancel);
120  exit;
121  } elseif (!empty($backtopage)) {
122  header("Location: ".$backtopage);
123  exit;
124  }
125  header("Location: ".DOL_URL_ROOT.'/fourn/facture/list.php');
126  exit;
127 }
128 
129 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
130  $search_ref = "";
131  $search_account = "";
132  $search_amount = "";
133  $search_paymenttype = "";
134  $search_payment_num = "";
135  $search_company = "";
136  $day = '';
137  $year = '';
138  $month = '';
139  $search_array_options = array();
140 }
141 
142 $parameters = array('socid'=>$socid);
143 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
144 if ($reshook < 0) {
145  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
146 }
147 
148 if (empty($reshook)) {
149  if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm == 'yes')) {
150  $error = 0;
151 
152  $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
153  $paiement_id = 0;
154  $totalpayment = 0;
155  $atleastonepaymentnotnull = 0;
156  $multicurrency_totalpayment = 0;
157 
158  // Generate payment array and check if there is payment higher than invoice and payment date before invoice date
159  $tmpinvoice = new FactureFournisseur($db);
160  foreach ($_POST as $key => $value) {
161  if (substr($key, 0, 7) == 'amount_') {
162  $cursorfacid = substr($key, 7);
163  $amounts[$cursorfacid] = price2num(GETPOST($key));
164  if (!empty($amounts[$cursorfacid])) {
165  $atleastonepaymentnotnull++;
166  if (is_numeric($amounts[$cursorfacid])) {
167  $totalpayment = $totalpayment + $amounts[$cursorfacid];
168  } else {
169  setEventMessages($langs->transnoentities("InputValueIsNotAnNumber", GETPOST($key)), null, 'warnings');
170  }
171  }
172  $result = $tmpinvoice->fetch($cursorfacid);
173  if ($result <= 0) {
174  dol_print_error($db);
175  }
176  $amountsresttopay[$cursorfacid] = price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement());
177  if ($amounts[$cursorfacid]) {
178  // Check amount
179  if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) {
180  $addwarning = 1;
181  $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier");
182  }
183  // Check date
184  if ($datepaye && ($datepaye < $tmpinvoice->date)) {
185  $langs->load("errors");
186  //$error++;
187  setEventMessages($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye, 'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), null, 'warnings');
188  }
189  }
190 
191  $formquestion[$i++] = array('type' => 'hidden', 'name' => $key, 'value' => GETPOST($key));
192  } elseif (substr($key, 0, 21) == 'multicurrency_amount_') {
193  $cursorfacid = substr($key, 21);
194  $multicurrency_amounts[$cursorfacid] = (GETPOST($key) ? price2num(GETPOST($key)) : 0);
195  $multicurrency_totalpayment += $multicurrency_amounts[$cursorfacid];
196  if (!empty($multicurrency_amounts[$cursorfacid])) {
197  $atleastonepaymentnotnull++;
198  }
199  $result = $tmpinvoice->fetch($cursorfacid);
200  if ($result <= 0) {
201  dol_print_error($db);
202  }
203  $multicurrency_amountsresttopay[$cursorfacid] = price2num($tmpinvoice->multicurrency_total_ttc - $tmpinvoice->getSommePaiement(1));
204  if ($multicurrency_amounts[$cursorfacid]) {
205  // Check amount
206  if ($multicurrency_amounts[$cursorfacid] && (abs($multicurrency_amounts[$cursorfacid]) > abs($multicurrency_amountsresttopay[$cursorfacid]))) {
207  $addwarning = 1;
208  $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier");
209  }
210  // Check date
211  if ($datepaye && ($datepaye < $tmpinvoice->date)) {
212  $langs->load("errors");
213  //$error++;
214  setEventMessages($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye, 'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), null, 'warnings');
215  }
216  }
217 
218  $formquestion[$i++] = array('type' => 'hidden', 'name' => $key, 'value' => GETPOST($key, 'int'));
219  }
220  }
221 
222  // Check parameters
223  if (GETPOST('paiementid') <= 0) {
224  setEventMessages($langs->transnoentities('ErrorFieldRequired', $langs->transnoentities('PaymentMode')), null, 'errors');
225  $error++;
226  }
227 
228  if (isModEnabled("banque")) {
229  // If bank module is on, account is required to enter a payment
230  if (GETPOST('accountid') <= 0) {
231  setEventMessages($langs->transnoentities('ErrorFieldRequired', $langs->transnoentities('AccountToCredit')), null, 'errors');
232  $error++;
233  }
234  }
235 
236  if (empty($totalpayment) && empty($multicurrency_totalpayment) && empty($atleastonepaymentnotnull)) {
237  setEventMessages($langs->transnoentities('ErrorFieldRequired', $langs->trans('PaymentAmount')), null, 'errors');
238  $error++;
239  }
240 
241  if (empty($datepaye)) {
242  setEventMessages($langs->transnoentities('ErrorFieldRequired', $langs->transnoentities('Date')), null, 'errors');
243  $error++;
244  }
245 
246  // Check if payments in both currency
247  if ($totalpayment > 0 && $multicurrency_totalpayment > 0) {
248  setEventMessages($langs->transnoentities('ErrorPaymentInBothCurrency'), null, 'errors');
249  $error++;
250  }
251  }
252 
253  /*
254  * Action add_paiement
255  */
256  if ($action == 'add_paiement') {
257  if ($error) {
258  $action = 'create';
259  }
260  // All the next of this action is displayed at the page's bottom.
261  }
262 
263 
264  /*
265  * Action confirm_paiement
266  */
267  if ($action == 'confirm_paiement' && $confirm == 'yes') {
268  $error = 0;
269 
270  $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
271 
272  $multicurrency_code = array();
273 
274  // Clean parameters amount if payment is for a credit note
275  foreach ($amounts as $key => $value) { // How payment is dispatched
276  $tmpinvoice = new FactureFournisseur($db);
277  $tmpinvoice->fetch($key);
278  if ($tmpinvoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
279  $newvalue = price2num($value, 'MT');
280  $amounts[$key] = - abs($newvalue);
281  }
282  $multicurrency_code[$key] = $tmpinvoice->multicurrency_code;
283  }
284 
285  foreach ($multicurrency_amounts as $key => $value) { // How payment is dispatched
286  $tmpinvoice = new FactureFournisseur($db);
287  $tmpinvoice->fetch($key);
288  if ($tmpinvoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
289  $newvalue = price2num($value, 'MT');
290  $multicurrency_amounts[$key] = - abs($newvalue);
291  }
292  $multicurrency_code[$key] = $tmpinvoice->multicurrency_code;
293  }
294 
295  //var_dump($amounts);
296  //var_dump($multicurrency_amounts);
297  //exit;
298 
299  if (!$error) {
300  $db->begin();
301 
302  $thirdparty = new Societe($db);
303  if ($socid > 0) {
304  $thirdparty->fetch($socid);
305  }
306 
307  // Creation of payment line
308  $paiement = new PaiementFourn($db);
309  $paiement->datepaye = $datepaye;
310  $paiement->amounts = $amounts; // Array of amounts
311  $paiement->multicurrency_amounts = $multicurrency_amounts;
312  $paiement->multicurrency_code = $multicurrency_code; // Array with all currency of payments dispatching
313  $paiement->paiementid = GETPOST('paiementid', 'int');
314  $paiement->num_payment = GETPOST('num_paiement', 'alphanohtml');
315  $paiement->note_private = GETPOST('comment', 'alpha');
316  $paiement->fk_account = GETPOST('accountid', 'int');
317 
318  if (!$error) {
319  // Create payment and update this->multicurrency_amounts if this->amounts filled or
320  // this->amounts if this->multicurrency_amounts filled.
321  // This also set ->amount and ->multicurrency_amount
322  $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices') == 'on' ? 1 : 0), $thirdparty);
323  if ($paiement_id < 0) {
324  setEventMessages($paiement->error, $paiement->errors, 'errors');
325  $error++;
326  }
327  }
328 
329  if (!$error) {
330  $result = $paiement->addPaymentToBank($user, 'payment_supplier', '(SupplierInvoicePayment)', $accountid, GETPOST('chqemetteur'), GETPOST('chqbank'));
331  if ($result < 0) {
332  setEventMessages($paiement->error, $paiement->errors, 'errors');
333  $error++;
334  }
335  }
336 
337  if (!$error) {
338  $db->commit();
339 
340  // If payment dispatching on more than one invoice, we stay on summary page, otherwise go on invoice card
341  $invoiceid = 0;
342  foreach ($paiement->amounts as $key => $amount) {
343  $facid = $key;
344  if (is_numeric($amount) && $amount <> 0) {
345  if ($invoiceid != 0) {
346  $invoiceid = -1; // There is more than one invoice payed by this payment
347  } else {
348  $invoiceid = $facid;
349  }
350  }
351  }
352  if ($invoiceid > 0) {
353  $loc = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$invoiceid;
354  } else {
355  $loc = DOL_URL_ROOT.'/fourn/paiement/card.php?id='.$paiement_id;
356  }
357  header('Location: '.$loc);
358  exit;
359  } else {
360  $db->rollback();
361  }
362  }
363  }
364 }
365 
366 
367 /*
368  * View
369  */
370 
371 $form = new Form($db);
372 $formother = new FormOther($db);
373 
374 $supplierstatic = new Societe($db);
375 $invoicesupplierstatic = new FactureFournisseur($db);
376 
377 llxHeader('', $langs->trans('ListPayment'));
378 
379 if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paiement') {
380  $object = new FactureFournisseur($db);
381  $result = $object->fetch($facid);
382 
383  $datefacture = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
384  $dateinvoice = ($datefacture == '' ? (empty($conf->global->MAIN_AUTOFILL_DATE) ?-1 : '') : $datefacture);
385 
386  $sql = 'SELECT s.nom as name, s.rowid as socid,';
387  $sql .= ' f.rowid, f.ref, f.ref_supplier, f.total_ttc as total, f.fk_mode_reglement, f.fk_account';
388  if (empty($user->rights->societe->client->voir) && !$socid) {
389  $sql .= ", sc.fk_soc, sc.fk_user ";
390  }
391  $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s, '.MAIN_DB_PREFIX.'facture_fourn as f';
392  if (empty($user->rights->societe->client->voir) && !$socid) {
393  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
394  }
395  $sql .= ' WHERE f.fk_soc = s.rowid';
396  $sql .= ' AND f.rowid = '.((int) $facid);
397  if (empty($user->rights->societe->client->voir) && !$socid) {
398  $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
399  }
400  $resql = $db->query($sql);
401  if ($resql) {
402  $num = $db->num_rows($resql);
403  if ($num) {
404  $obj = $db->fetch_object($resql);
405  $total = $obj->total;
406 
407  print load_fiche_titre($langs->trans('DoPayment'));
408 
409  // Add realtime total information
410  if (!empty($conf->use_javascript_ajax)) {
411  print "\n".'<script type="text/javascript">';
412  print '$(document).ready(function () {
413 
414  function _elemToJson(selector)
415  {
416  var subJson = {};
417  $.map(selector.serializeArray(), function(n,i)
418  {
419  subJson[n["name"]] = n["value"];
420  });
421 
422  return subJson;
423  }
424  function callForResult(imgId)
425  {
426  console.log("callForResult Calculate total of payment");
427  var json = {};
428  var form = $("#payment_form");
429 
430  json["invoice_type"] = $("#invoice_type").val();
431  json["amountPayment"] = $("#amountpayment").attr("value");
432  json["amounts"] = _elemToJson(form.find("input.amount"));
433  json["remains"] = _elemToJson(form.find("input.remain"));
434  json["token"] = "'.currentToken().'";
435  if (imgId != null) {
436  json["imgClicked"] = imgId;
437  }
438 
439  $.post("'.DOL_URL_ROOT.'/compta/ajaxpayment.php", json, function(data)
440  {
441  json = $.parseJSON(data);
442 
443  form.data(json);
444 
445  for (var key in json)
446  {
447  if (key == "result") {
448  if (json["makeRed"]) {
449  $("#"+key).addClass("error");
450  } else {
451  $("#"+key).removeClass("error");
452  }
453  json[key]=json["label"]+" "+json[key];
454  $("#"+key).text(json[key]);
455  } else {console.log(key);
456  form.find("input[name*=\""+key+"\"]").each(function() {
457  $(this).attr("value", json[key]);
458  });
459  }
460  }
461  });
462  }
463  callForResult();
464  $("#payment_form").find("input.amount").change(function() {
465  callForResult();
466  });
467  $("#payment_form").find("input.amount").keyup(function() {
468  callForResult();
469  });
470  ';
471 
472  print ' });'."\n";
473 
474  //Add js for AutoFill
475  print ' $(document).ready(function () {';
476  print ' $(".AutoFillAmout").on(\'click touchstart\', function(){
477  $("input[name="+$(this).data(\'rowname\')+"]").val($(this).data("value")).trigger("change");
478  });';
479  print ' });'."\n";
480 
481  print ' </script>'."\n";
482  }
483 
484  print '<form id="payment_form" name="addpaiement" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
485  print '<input type="hidden" name="token" value="'.newToken().'">';
486  print '<input type="hidden" name="action" value="add_paiement">';
487  print '<input type="hidden" name="facid" value="'.$facid.'">';
488  print '<input type="hidden" name="ref_supplier" value="'.$obj->ref_supplier.'">';
489  print '<input type="hidden" name="socid" value="'.$obj->socid.'">';
490  print '<input type="hidden" name="type" id="invoice_type" value="'.$object->type.'">';
491  print '<input type="hidden" name="societe" value="'.$obj->name.'">';
492 
493  print dol_get_fiche_head(null);
494 
495  print '<table class="border centpercent">';
496 
497  print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans('Company').'</td><td>';
498  $supplierstatic->id = $obj->socid;
499  $supplierstatic->name = $obj->name;
500  print $supplierstatic->getNomUrl(1, 'supplier');
501  print '</td></tr>';
502  print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td>';
503  print $form->selectDate($dateinvoice, '', '', '', 0, "addpaiement", 1, 1, 0, '', '', $object->date);
504  print '</td></tr>';
505  print '<tr><td class="fieldrequired">'.$langs->trans('PaymentMode').'</td><td>';
506  $form->select_types_paiements(!GETPOST('paiementid') ? $obj->fk_mode_reglement : GETPOST('paiementid'), 'paiementid');
507  print '</td>';
508  if (isModEnabled("banque")) {
509  print '<tr><td class="fieldrequired">'.$langs->trans('Account').'</td><td>';
510  print img_picto('', 'bank_account', 'class="pictofixedwidth"');
511  print $form->select_comptes(empty($accountid) ? $obj->fk_account : $accountid, 'accountid', 0, '', 2, '', 0, 'widthcentpercentminusx maxwidth500', 1);
512  print '</td></tr>';
513  } else {
514  print '<tr><td>&nbsp;</td></tr>';
515  }
516  print '<tr><td>'.$langs->trans('Numero').'</td><td><input name="num_paiement" type="text" value="'.(!GETPOST('num_paiement') ? '' : GETPOST('num_paiement')).'"></td></tr>';
517  print '<tr><td>'.$langs->trans('Comments').'</td>';
518  print '<td class="tdtop">';
519  print '<textarea name="comment" wrap="soft" class="quatrevingtpercent" rows="'.ROWS_3.'">'.(!GETPOST('comment') ? '' : GETPOST('comment')).'</textarea></td></tr>';
520  print '</table>';
521  print dol_get_fiche_end();
522 
523 
524  $parameters = array('facid'=>$facid, 'ref'=>$ref, 'objcanvas'=>$objcanvas);
525  $reshook = $hookmanager->executeHooks('paymentsupplierinvoices', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
526  $error = $hookmanager->error; $errors = $hookmanager->errors;
527  if (empty($reshook)) {
528  /*
529  * All unpaid supplier invoices
530  */
531  $sql = 'SELECT f.rowid as facid, f.ref, f.ref_supplier, f.type, f.total_ht, f.total_ttc,';
532  $sql .= ' f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc,';
533  $sql .= ' f.datef as df, f.date_lim_reglement as dlr,';
534  $sql .= ' SUM(pf.amount) as am, SUM(pf.multicurrency_amount) as multicurrency_am';
535  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as f';
536  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid';
537  $sql .= " WHERE f.entity = ".((int) $conf->entity);
538  $sql .= ' AND f.fk_soc = '.((int) $object->socid);
539  $sql .= ' AND f.paye = 0';
540  $sql .= ' AND f.fk_statut = 1'; // Status=0 => unvalidated, Status=2 => canceled
541  if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE) {
542  $sql .= ' AND f.type IN (0,1,3,5)'; // Standard invoice, replacement, deposit, situation
543  } else {
544  $sql .= ' AND f.type = 2'; // If paying back a credit note, we show all credit notes
545  }
546  // Group by because we have a total
547  $sql .= ' GROUP BY f.datef, f.ref, f.ref_supplier, f.rowid, f.type, f.total_ht, f.total_ttc,';
548  $sql .= ' f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc,';
549  $sql .= ' f.datef, f.date_lim_reglement';
550  // Sort invoices by date and serial number: the older one comes first
551  $sql .= ' ORDER BY f.datef ASC, f.ref ASC';
552 
553  $resql = $db->query($sql);
554  if ($resql) {
555  $num = $db->num_rows($resql);
556  if ($num > 0) {
557  $i = 0;
558  print '<br>';
559 
560  if (!empty($conf->use_javascript_ajax)) {
561  //Add js for AutoFill
562  print "\n".'<script type="text/javascript">';
563  print ' $(document).ready(function () {';
564  print ' $(".AutoFillAmout").on(\'click touchstart\', function(){
565  $("input[name="+$(this).data(\'rowname\')+"]").val($(this).data("value"));
566  });';
567  print ' });'."\n";
568  print ' </script>'."\n";
569  }
570 
571  print '<div class="div-table-responsive-no-min">';
572  print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
573 
574  print '<tr class="liste_titre">';
575  print '<td>'.$langs->trans('Invoice').'</td>';
576  print '<td>'.$langs->trans('RefSupplier').'</td>';
577  print '<td class="center">'.$langs->trans('Date').'</td>';
578  print '<td class="center">'.$langs->trans('DateMaxPayment').'</td>';
579  if (isModEnabled("multicurrency")) {
580  print '<td>'.$langs->trans('Currency').'</td>';
581  print '<td class="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
582  print '<td class="right">'.$langs->trans('MulticurrencyAlreadyPaid').'</td>';
583  print '<td class="right">'.$langs->trans('MulticurrencyRemainderToPay').'</td>';
584  print '<td class="center">'.$langs->trans('MulticurrencyPaymentAmount').'</td>';
585  }
586  print '<td class="right">'.$langs->trans('AmountTTC').'</td>';
587  print '<td class="right">'.$langs->trans('AlreadyPaid').'</td>';
588  print '<td class="right">'.$langs->trans('RemainderToPay').'</td>';
589  print '<td class="center">'.$langs->trans('PaymentAmount').'</td>';
590  print '</tr>';
591 
592  $total = 0;
593  $total_ttc = 0;
594  $totalrecu = 0;
595  while ($i < $num) {
596  $objp = $db->fetch_object($resql);
597 
598  $sign = 1;
599  if ($objp->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
600  $sign = -1;
601  }
602 
603  $invoice = new FactureFournisseur($db);
604  $invoice->fetch($objp->facid);
605 
606  $invoicesupplierstatic->ref = $objp->ref;
607  $invoicesupplierstatic->id = $objp->facid;
608 
609  $paiement = $invoice->getSommePaiement();
610  $creditnotes = $invoice->getSumCreditNotesUsed();
611  $deposits = $invoice->getSumDepositsUsed();
612  $alreadypayed = price2num($paiement + $creditnotes + $deposits, 'MT');
613  $remaintopay = price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT');
614 
615  // Multicurrency Price
616  if (isModEnabled("multicurrency")) {
617  $multicurrency_payment = $invoice->getSommePaiement(1);
618  $multicurrency_creditnotes = $invoice->getSumCreditNotesUsed(1);
619  $multicurrency_deposits = $invoice->getSumDepositsUsed(1);
620  $multicurrency_alreadypayed = price2num($multicurrency_payment + $multicurrency_creditnotes + $multicurrency_deposits, 'MT');
621  $multicurrency_remaintopay = price2num($invoice->multicurrency_total_ttc - $multicurrency_payment - $multicurrency_creditnotes - $multicurrency_deposits, 'MT');
622  }
623 
624  print '<tr class="oddeven'.(($invoice->id == $facid) ? ' highlight' : '').'">';
625 
626  // Ref
627  print '<td class="nowraponall">';
628  print $invoicesupplierstatic->getNomUrl(1);
629  print '</td>';
630 
631  // Ref supplier
632  print '<td>'.$objp->ref_supplier.'</td>';
633 
634  // Date
635  if ($objp->df > 0) {
636  print '<td class="center nowraponall">';
637  print dol_print_date($db->jdate($objp->df), 'day').'</td>';
638  } else {
639  print '<td class="center"><b>!!!</b></td>';
640  }
641 
642  // Date Max Payment
643  if ($objp->dlr > 0) {
644  print '<td class="center nowraponall">';
645  print dol_print_date($db->jdate($objp->dlr), 'day');
646 
647  if ($invoice->hasDelay()) {
648  print img_warning($langs->trans('Late'));
649  }
650 
651  print '</td>';
652  } else {
653  print '<td class="center"><b>--</b></td>';
654  }
655 
656  // Multicurrency
657  if (isModEnabled("multicurrency")) {
658  // Currency
659  print '<td class="center">'.$objp->multicurrency_code."</td>\n";
660 
661  print '<td class="right">';
662  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
663  print price($objp->multicurrency_total_ttc);
664  }
665  print '</td>';
666 
667  print '<td class="right">';
668  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
669  print price($sign * $multicurrency_payment);
670  if ($multicurrency_creditnotes) {
671  print '+'.price($multicurrency_creditnotes);
672  }
673  if ($multicurrency_deposits) {
674  print '+'.price($multicurrency_deposits);
675  }
676  }
677  print '</td>';
678 
679  print '<td class="right">';
680  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
681  print price($sign * $multicurrency_remaintopay);
682  }
683  print '</td>';
684 
685  print '<td class="right">';
686  // Add remind multicurrency amount
687  $namef = 'multicurrency_amount_'.$objp->facid;
688  $nameRemain = 'multicurrency_remain_'.$objp->facid;
689  if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
690  if ($action != 'add_paiement') {
691  if (!empty($conf->use_javascript_ajax)) {
692  print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'");
693  }
694  print '<input type=hidden class="multicurrency_remain" name="'.$nameRemain.'" value="'.$multicurrency_remaintopay.'">';
695  print '<input type="text" size="8" class="multicurrency_amount" name="'.$namef.'" value="'.GETPOST($namef).'">';
696  } else {
697  print '<input type="text" size="8" name="'.$namef.'_disabled" value="'.GETPOST($namef).'" disabled>';
698  print '<input type="hidden" name="'.$namef.'" value="'.GETPOST($namef).'">';
699  }
700  }
701  print "</td>";
702  }
703 
704  print '<td class="right">'.price($sign * $objp->total_ttc).'</td>';
705 
706  print '<td class="right">'.price($sign * $objp->am);
707  if ($creditnotes) {
708  print '+'.price($creditnotes);
709  }
710  if ($deposits) {
711  print '+'.price($deposits);
712  }
713  print '</td>';
714 
715  print '<td class="right">';
716  print price($sign * $remaintopay);
717  if (!empty($conf->paymentbybanktransfer->enabled)) {
718  $numdirectdebitopen = 0;
719  $totaldirectdebit = 0;
720  $sql = "SELECT COUNT(pfd.rowid) as nb, SUM(pfd.amount) as amount";
721  $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
722  $sql .= " WHERE fk_facture_fourn = ".((int) $objp->facid);
723  $sql .= " AND pfd.traite = 0";
724  $sql .= " AND pfd.ext_payment_id IS NULL";
725 
726  $result_sql = $db->query($sql);
727  if ($result_sql) {
728  $obj = $db->fetch_object($result_sql);
729  $numdirectdebitopen = $obj->nb;
730  $totaldirectdebit = $obj->amount;
731  } else {
732  dol_print_error($db);
733  }
734  if ($numdirectdebitopen) {
735  $langs->load("withdrawals");
736  print img_warning($langs->trans("WarningSomeCreditTransferAlreadyExists", $numdirectdebitopen, price(price2num($totaldirectdebit, 'MT'), 0, $langs, 1, -1, -1, $conf->currency)), '', 'classfortooltip');
737  }
738  }
739  print '</td>';
740 
741  // Amount
742  print '<td class="center nowraponall">';
743 
744  $namef = 'amount_'.$objp->facid;
745  $nameRemain = 'remain_'.$objp->facid;
746 
747  if ($action != 'add_paiement') {
748  if (!empty($conf->use_javascript_ajax)) {
749  print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $remaintopay)."'");
750  }
751  print '<input type="hidden" class="remain" name="'.$nameRemain.'" value="'.$remaintopay.'">';
752  print '<input type="text" size="8" class="amount" name="'.$namef.'" value="'.dol_escape_htmltag(GETPOST($namef)).'">'; // class is requied to be used by javascript callForResult();
753  } else {
754  print '<input type="text" size="8" name="'.$namef.'_disabled" value="'.dol_escape_htmltag(GETPOST($namef)).'" disabled>';
755  print '<input type="hidden" class="amount" name="'.$namef.'" value="'.dol_escape_htmltag(GETPOST($namef)).'">'; // class is requied to be used by javascript callForResult();
756  }
757  print "</td>";
758 
759  print "</tr>\n";
760  $total += $objp->total_ht;
761  $total_ttc += $objp->total_ttc;
762  $totalrecu += $objp->am;
763  $totalrecucreditnote += $creditnotes;
764  $totalrecudeposits += $deposits;
765  $i++;
766  }
767  if ($i > 1) {
768  // Print total
769  print '<tr class="liste_total">';
770  print '<td colspan="4" class="left">'.$langs->trans('TotalTTC').':</td>';
771  if (isModEnabled("multicurrency")) {
772  print '<td>&nbsp;</td>';
773  print '<td>&nbsp;</td>';
774  print '<td>&nbsp;</td>';
775  print '<td>&nbsp;</td>';
776  print '<td class="right" id="multicurrency_result" style="font-weight: bold;"></td>';
777  }
778  print '<td class="right"><b>'.price($sign * $total_ttc).'</b></td>';
779  print '<td class="right"><b>'.price($sign * $totalrecu);
780  if ($totalrecucreditnote) {
781  print '+'.price($totalrecucreditnote);
782  }
783  if ($totalrecudeposits) {
784  print '+'.price($totalrecudeposits);
785  }
786  print '</b></td>';
787  print '<td class="right"><b>'.price($sign * price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits, 'MT')).'</b></td>';
788  print '<td class="center" id="result" style="font-weight: bold;"></td>'; // Autofilled
789  print "</tr>\n";
790  }
791  print "</table>\n";
792 
793  print "</div>";
794  }
795  $db->free($resql);
796  } else {
797  dol_print_error($db);
798  }
799  }
800 
801  // Save + Cancel Buttons
802  if ($action != 'add_paiement') {
803  print '<br><div class="center">';
804  print '<input type="checkbox" checked id="closepaidinvoices" name="closepaidinvoices"> <label for="closepaidinvoices">'.$langs->trans("ClosePaidInvoicesAutomatically").'</label><br>';
805  print '<input type="submit" class="button" value="'.$langs->trans('ToMakePayment').'">';
806  print ' &nbsp; <input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
807  print '</div>';
808  }
809 
810  // Form to confirm payment
811  if ($action == 'add_paiement') {
812  $preselectedchoice = $addwarning ? 'no' : 'yes';
813 
814  print '<br>';
815  if (!empty($totalpayment)) {
816  $text = $langs->trans('ConfirmSupplierPayment', price($totalpayment), $langs->trans("Currency".$conf->currency));
817  }
818  if (!empty($multicurrency_totalpayment)) {
819  $text .= '<br>'.$langs->trans('ConfirmSupplierPayment', price($multicurrency_totalpayment), $langs->trans("paymentInInvoiceCurrency"));
820  }
821  if (GETPOST('closepaidinvoices')) {
822  $text .= '<br>'.$langs->trans("AllCompletelyPayedInvoiceWillBeClosed");
823  print '<input type="hidden" name="closepaidinvoices" value="'.GETPOST('closepaidinvoices').'">';
824  }
825  print $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$facture->id.'&socid='.$facture->socid.'&type='.$facture->type, $langs->trans('PayedSuppliersPayments'), $text, 'confirm_paiement', $formquestion, $preselectedchoice);
826  }
827 
828  print '</form>';
829  }
830  } else {
831  dol_print_error($db);
832  }
833 }
834 
835 // End of page
836 llxFooter();
837 $db->close();
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage standard extra fields.
Class to manage suppliers invoices.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
Class to manage payments for supplier invoices.
Class to manage third parties objects (customers, suppliers, prospects...)
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
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='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.