dolibarr 19.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-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
38require '../../main.inc.php';
39require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
40require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
41require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
42require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
43require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
44require_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');
74if (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;
80if (!$sortorder) {
81 $sortorder = "DESC";
82}
83if (!$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
95if ($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
118if ($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
130if (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
145if ($reshook < 0) {
146 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
147}
148
149if (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
382llxHeader('', $langs->trans('ListPayment'));
383
384if ($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 == '' ? (!getDolGlobalString('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;
536 $errors = $hookmanager->errors;
537 if (empty($reshook)) {
538 /*
539 * All unpaid supplier invoices
540 */
541 $sql = 'SELECT f.rowid as facid, f.ref, f.ref_supplier, f.type, f.total_ht, f.total_ttc,';
542 $sql .= ' f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc,';
543 $sql .= ' f.datef as df, f.date_lim_reglement as dlr,';
544 $sql .= ' SUM(pf.amount) as am, SUM(pf.multicurrency_amount) as multicurrency_am';
545 $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as f';
546 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid';
547 $sql .= " WHERE f.entity = ".((int) $conf->entity);
548 $sql .= ' AND f.fk_soc = '.((int) $object->socid);
549 $sql .= ' AND f.paye = 0';
550 $sql .= ' AND f.fk_statut = 1'; // Status=0 => unvalidated, Status=2 => canceled
551 if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE) {
552 $sql .= ' AND f.type IN (0,1,3,5)'; // Standard invoice, replacement, deposit, situation
553 } else {
554 $sql .= ' AND f.type = 2'; // If paying back a credit note, we show all credit notes
555 }
556 // Group by because we have a total
557 $sql .= ' GROUP BY f.datef, f.ref, f.ref_supplier, f.rowid, f.type, f.total_ht, f.total_ttc,';
558 $sql .= ' f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc,';
559 $sql .= ' f.datef, f.date_lim_reglement';
560 // Sort invoices by date and serial number: the older one comes first
561 $sql .= ' ORDER BY f.datef ASC, f.ref ASC';
562
563 $resql = $db->query($sql);
564 if ($resql) {
565 $num = $db->num_rows($resql);
566 if ($num > 0) {
567 $i = 0;
568 print '<br>';
569
570 if (!empty($conf->use_javascript_ajax)) {
571 //Add js for AutoFill
572 print "\n".'<script type="text/javascript">';
573 print ' $(document).ready(function () {';
574 print ' $(".AutoFillAmout").on(\'click touchstart\', function(){
575 $("input[name="+$(this).data(\'rowname\')+"]").val($(this).data("value"));
576 });';
577 print ' });'."\n";
578 print ' </script>'."\n";
579 }
580
581 print '<div class="div-table-responsive-no-min">';
582 print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
583
584 print '<tr class="liste_titre">';
585 print '<td>'.$langs->trans('Invoice').'</td>';
586 print '<td>'.$langs->trans('RefSupplier').'</td>';
587 print '<td class="center">'.$langs->trans('Date').'</td>';
588 print '<td class="center">'.$langs->trans('DateMaxPayment').'</td>';
589 if (isModEnabled("multicurrency")) {
590 print '<td>'.$langs->trans('Currency').'</td>';
591 print '<td class="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
592 print '<td class="right">'.$langs->trans('MulticurrencyAlreadyPaid').'</td>';
593 print '<td class="right">'.$langs->trans('MulticurrencyRemainderToPay').'</td>';
594 print '<td class="center">'.$langs->trans('MulticurrencyPaymentAmount').'</td>';
595 }
596 print '<td class="right">'.$langs->trans('AmountTTC').'</td>';
597 print '<td class="right">'.$langs->trans('AlreadyPaid').'</td>';
598 print '<td class="right">'.$langs->trans('RemainderToPay').'</td>';
599 print '<td class="center">'.$langs->trans('PaymentAmount').'</td>';
600 print '</tr>';
601
602 $total = 0;
603 $total_ttc = 0;
604 $totalrecu = 0;
605 $totalrecucreditnote = 0; // PHP Warning: Undefined variable $totalrecucreditnote
606 $totalrecudeposits = 0; // PHP Warning: Undefined variable $totalrecudeposits
607 while ($i < $num) {
608 $objp = $db->fetch_object($resql);
609
610 $sign = 1;
611 if ($objp->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
612 $sign = -1;
613 }
614
615 $invoice = new FactureFournisseur($db);
616 $invoice->fetch($objp->facid);
617
618 $invoicesupplierstatic->ref = $objp->ref;
619 $invoicesupplierstatic->id = $objp->facid;
620
621 $paiement = $invoice->getSommePaiement();
622 $creditnotes = $invoice->getSumCreditNotesUsed();
623 $deposits = $invoice->getSumDepositsUsed();
624 $alreadypayed = price2num($paiement + $creditnotes + $deposits, 'MT');
625 $remaintopay = price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT');
626
627 // Multicurrency Price
628 if (isModEnabled("multicurrency")) {
629 $multicurrency_payment = $invoice->getSommePaiement(1);
630 $multicurrency_creditnotes = $invoice->getSumCreditNotesUsed(1);
631 $multicurrency_deposits = $invoice->getSumDepositsUsed(1);
632 $multicurrency_alreadypayed = price2num($multicurrency_payment + $multicurrency_creditnotes + $multicurrency_deposits, 'MT');
633 $multicurrency_remaintopay = price2num($invoice->multicurrency_total_ttc - $multicurrency_payment - $multicurrency_creditnotes - $multicurrency_deposits, 'MT');
634 }
635
636 print '<tr class="oddeven'.(($invoice->id == $facid) ? ' highlight' : '').'">';
637
638 // Ref
639 print '<td class="nowraponall">';
640 print $invoicesupplierstatic->getNomUrl(1);
641 print '</td>';
642
643 // Ref supplier
644 print '<td>'.$objp->ref_supplier.'</td>';
645
646 // Date
647 if ($objp->df > 0) {
648 print '<td class="center nowraponall">';
649 print dol_print_date($db->jdate($objp->df), 'day').'</td>';
650 } else {
651 print '<td class="center"><b>!!!</b></td>';
652 }
653
654 // Date Max Payment
655 if ($objp->dlr > 0) {
656 print '<td class="center nowraponall">';
657 print dol_print_date($db->jdate($objp->dlr), 'day');
658
659 if ($invoice->hasDelay()) {
660 print img_warning($langs->trans('Late'));
661 }
662
663 print '</td>';
664 } else {
665 print '<td class="center"><b>--</b></td>';
666 }
667
668 // Multicurrency
669 if (isModEnabled("multicurrency")) {
670 // Currency
671 print '<td class="center">'.$objp->multicurrency_code."</td>\n";
672
673 print '<td class="right">';
674 if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
675 print price($objp->multicurrency_total_ttc);
676 }
677 print '</td>';
678
679 print '<td class="right">';
680 if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
681 print price($sign * $multicurrency_payment);
682 if ($multicurrency_creditnotes) {
683 print '+'.price($multicurrency_creditnotes);
684 }
685 if ($multicurrency_deposits) {
686 print '+'.price($multicurrency_deposits);
687 }
688 }
689 print '</td>';
690
691 print '<td class="right">';
692 if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
693 print price($sign * $multicurrency_remaintopay);
694 }
695 print '</td>';
696
697 print '<td class="right">';
698 // Add remind multicurrency amount
699 $namef = 'multicurrency_amount_'.$objp->facid;
700 $nameRemain = 'multicurrency_remain_'.$objp->facid;
701 if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) {
702 if ($action != 'add_paiement') {
703 if (!empty($conf->use_javascript_ajax)) {
704 print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'");
705 }
706 print '<input type=hidden class="multicurrency_remain" name="'.$nameRemain.'" value="'.$multicurrency_remaintopay.'">';
707 print '<input type="text" size="8" class="multicurrency_amount" name="'.$namef.'" value="'.GETPOST($namef).'">';
708 } else {
709 print '<input type="text" size="8" name="'.$namef.'_disabled" value="'.GETPOST($namef).'" disabled>';
710 print '<input type="hidden" name="'.$namef.'" value="'.GETPOST($namef).'">';
711 }
712 }
713 print "</td>";
714 }
715
716 print '<td class="right">'.price($sign * $objp->total_ttc).'</td>';
717
718 print '<td class="right">'.price($sign * $objp->am);
719 if ($creditnotes) {
720 print '+'.price($creditnotes);
721 }
722 if ($deposits) {
723 print '+'.price($deposits);
724 }
725 print '</td>';
726
727 print '<td class="right">';
728 print price($sign * $remaintopay);
729 if (isModEnabled('paymentbybanktransfer')) {
730 $numdirectdebitopen = 0;
731 $totaldirectdebit = 0;
732 $sql = "SELECT COUNT(pfd.rowid) as nb, SUM(pfd.amount) as amount";
733 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
734 $sql .= " WHERE fk_facture_fourn = ".((int) $objp->facid);
735 $sql .= " AND pfd.traite = 0";
736 $sql .= " AND pfd.ext_payment_id IS NULL";
737
738 $result_sql = $db->query($sql);
739 if ($result_sql) {
740 $obj = $db->fetch_object($result_sql);
741 $numdirectdebitopen = $obj->nb;
742 $totaldirectdebit = $obj->amount;
743 } else {
744 dol_print_error($db);
745 }
746 if ($numdirectdebitopen) {
747 $langs->load("withdrawals");
748 print img_warning($langs->trans("WarningSomeCreditTransferAlreadyExists", $numdirectdebitopen, price(price2num($totaldirectdebit, 'MT'), 0, $langs, 1, -1, -1, $conf->currency)), '', 'classfortooltip');
749 }
750 }
751 print '</td>';
752
753 // Amount
754 print '<td class="center nowraponall">';
755
756 $namef = 'amount_'.$objp->facid;
757 $nameRemain = 'remain_'.$objp->facid;
758
759 if ($action != 'add_paiement') {
760 if (!empty($conf->use_javascript_ajax)) {
761 print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $remaintopay)."'");
762 }
763 print '<input type="hidden" class="remain" name="'.$nameRemain.'" value="'.$remaintopay.'">';
764 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();
765 } else {
766 print '<input type="text" size="8" name="'.$namef.'_disabled" value="'.dol_escape_htmltag(GETPOST($namef)).'" disabled>';
767 print '<input type="hidden" class="amount" name="'.$namef.'" value="'.dol_escape_htmltag(GETPOST($namef)).'">'; // class is requied to be used by javascript callForResult();
768 }
769 print "</td>";
770
771 print "</tr>\n";
772 $total += $objp->total_ht;
773 $total_ttc += $objp->total_ttc;
774 $totalrecu += $objp->am;
775 $totalrecucreditnote += $creditnotes;
776 $totalrecudeposits += $deposits;
777 $i++;
778 }
779 if ($i > 1) {
780 // Print total
781 print '<tr class="liste_total">';
782 print '<td colspan="4" class="left">'.$langs->trans('TotalTTC').':</td>';
783 if (isModEnabled("multicurrency")) {
784 print '<td>&nbsp;</td>';
785 print '<td>&nbsp;</td>';
786 print '<td>&nbsp;</td>';
787 print '<td>&nbsp;</td>';
788 print '<td class="right" id="multicurrency_result" style="font-weight: bold;"></td>';
789 }
790 print '<td class="right"><b>'.price($sign * $total_ttc).'</b></td>';
791 print '<td class="right"><b>'.price($sign * $totalrecu);
792 if ($totalrecucreditnote) {
793 print '+'.price($totalrecucreditnote);
794 }
795 if ($totalrecudeposits) {
796 print '+'.price($totalrecudeposits);
797 }
798 print '</b></td>';
799 print '<td class="right"><b>'.price($sign * price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits, 'MT')).'</b></td>';
800 print '<td class="center" id="result" style="font-weight: bold;"></td>'; // Autofilled
801 print "</tr>\n";
802 }
803 print "</table>\n";
804
805 print "</div>";
806 }
807 $db->free($resql);
808 } else {
809 dol_print_error($db);
810 }
811 }
812
813 // Save + Cancel Buttons
814 if ($action != 'add_paiement') {
815 print '<br><div class="center">';
816 print '<input type="checkbox" checked id="closepaidinvoices" name="closepaidinvoices"> <label for="closepaidinvoices">'.$langs->trans("ClosePaidInvoicesAutomatically").'</label><br>';
817 print '<input type="submit" class="button" value="'.$langs->trans('ToMakePayment').'">';
818 print ' &nbsp; <input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
819 print '</div>';
820 }
821
822 // Form to confirm payment
823 if ($action == 'add_paiement') {
824 $preselectedchoice = $addwarning ? 'no' : 'yes';
825
826 print '<br>';
827 if (!empty($totalpayment)) {
828 $text = $langs->trans('ConfirmSupplierPayment', price($totalpayment), $langs->transnoentitiesnoconv("Currency".$conf->currency));
829 }
830 if (!empty($multicurrency_totalpayment)) {
831 $text .= '<br>'.$langs->trans('ConfirmSupplierPayment', price($multicurrency_totalpayment), $langs->transnoentitiesnoconv("paymentInInvoiceCurrency"));
832 }
833 if (GETPOST('closepaidinvoices')) {
834 $text .= '<br>'.$langs->trans("AllCompletelyPayedInvoiceWillBeClosed");
835 print '<input type="hidden" name="closepaidinvoices" value="'.GETPOST('closepaidinvoices').'">';
836 }
837 print $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id.'&socid='.$object->socid.'&type='.$object->type, $langs->trans('PayedSuppliersPayments'), $text, 'confirm_paiement', $formquestion, $preselectedchoice);
838 }
839
840 print '</form>';
841 }
842 } else {
843 dol_print_error($db);
844 }
845}
846
847// End of page
848llxFooter();
849$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: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.
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...)
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.
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...