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