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