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