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