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