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