dolibarr 24.0.2
prelevement.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
4 * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2014 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
8 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
9 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
31// Load Dolibarr environment
32require '../../main.inc.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
36require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
38require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
39require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.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.'/compta/facture/class/facture-rec.class.php';
43require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
44
45
55// Load translation files required by the page
56$langs->loadLangs(array('bills', 'banks', 'withdrawals', 'companies'));
57
58$id = (GETPOSTINT('id') ? GETPOSTINT('id') : GETPOSTINT('facid')); // For backward compatibility
59$ref = GETPOST('ref', 'alpha');
60$socid = GETPOSTINT('socid');
61$action = GETPOST('action', 'aZ09');
62$type = GETPOST('type', 'aZ09');
63
64$fieldid = (!empty($ref) ? 'ref' : 'rowid');
65if ($user->socid) {
66 $socid = $user->socid;
67}
68
69$moreparam = '';
70if ($type == 'bank-transfer') {
72 $moreparam = '&type='.$type;
73} else {
74 $object = new Facture($db);
75}
76
77// Load object
78$isdraft = 1;
79if ($id > 0 || !empty($ref)) {
80 $ret = $object->fetch($id, $ref);
81 $isdraft = (($object->status == FactureFournisseur::STATUS_DRAFT) ? 1 : 0);
82 if ($ret > 0) {
83 $id = $object->id; // The page may be called with the ref only: the security check must be done on the object found
84 $fieldid = 'rowid'; // $id is now the id of the invoice, not its ref
85 $object->fetch_thirdparty();
86 }
87}
88
89$hookmanager->initHooks(array('directdebitcard', 'globalcard'));
90
91if ($type == 'bank-transfer') {
92 $result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', $fieldid, $isdraft);
93 if (!$user->hasRight('fournisseur', 'facture', 'lire')) {
95 }
96} else {
97 $result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid, $isdraft);
98 if (!$user->hasRight('facture', 'lire')) {
100 }
101}
102
103if ($type == 'bank-transfer') {
104 $usercancreate = ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer);
105} else {
106 $usercancreate = $user->hasRight('facture', 'creer');
107}
108
109
110/*
111 * Actions
112 */
113
114$parameters = array('socid' => $socid);
115$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
116if ($reshook < 0) {
117 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
118}
119
120if (empty($reshook)) {
121 if ($action == "new" && $usercancreate) {
122 if ($object->id > 0) {
123 $db->begin();
124
125 $newtype = $type;
126 $sourcetype = 'facture';
127 if ($type == 'bank-transfer') {
128 $sourcetype = 'supplier_invoice';
129 $newtype = 'bank-transfer';
130 }
131 $paymentservice = GETPOST('paymentservice');
132
133 // Get chosen iban id
134 $iban = GETPOSTINT('accountcustomerid');
135 $amount = GETPOST('withdraw_request_amount', 'alpha');
136 $result = $object->demande_prelevement($user, (float) price2num($amount), $newtype, $sourcetype, 0, $iban ?? 0);
137
138 if ($result > 0) {
139 $db->commit();
140
141 setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
142 } else {
143 $db->rollback();
144 setEventMessages($object->error, $object->errors, 'errors');
145 }
146 }
147 $action = '';
148 }
149
150 if ($action == "delete" && $usercancreate) {
151 if ($object->id > 0) {
152 $result = $object->demande_prelevement_delete($user, GETPOSTINT('did'));
153 if ($result == 0) {
154 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id.'&type='.$type);
155 exit;
156 }
157 }
158 }
159
160 // Request payment with a Stripe Direct Debit for a customer invoice
161 if ($action == 'sepastripedirectdebit' && $usercancreate) {
162 $result = $object->makeStripeSepaRequest($user, GETPOSTINT('did'), 'direct-debit', 'facture');
163 if ($result < 0) {
164 setEventMessages($object->error, $object->errors, 'errors');
165 } else {
166 // We refresh object data
167 $ret = $object->fetch($id, $ref);
168 $isdraft = (($object->status == Facture::STATUS_DRAFT) ? 1 : 0);
169 if ($ret > 0) {
170 $object->fetch_thirdparty();
171 }
172 }
173 }
174
175 // Make payment with a stripe sepa for a supplier invoice
176 if ($action == 'sepastripecredittransfer' && $usercancreate) {
177 $result = $object->makeStripeSepaRequest($user, GETPOSTINT('did'), 'bank-transfer', 'supplier_invoice');
178 if ($result < 0) {
179 setEventMessages($object->error, $object->errors, 'errors');
180 } else {
181 // We refresh object data
182 $ret = $object->fetch($id, $ref);
183 $isdraft = (($object->status == FactureFournisseur::STATUS_DRAFT) ? 1 : 0);
184 if ($ret > 0) {
185 $object->fetch_thirdparty();
186 }
187 }
188 }
189
190 // Set payments conditions
191 if ($action == 'setconditions' && $usercancreate) {
192 $object->fetch($id);
193 $object->cond_reglement_code = 0; // To clean property
194 $object->cond_reglement_id = 0; // To clean property
195
196 $error = 0;
197
198 $db->begin();
199
200 if (!$error) {
201 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'));
202 if ($result < 0) {
203 $error++;
204 setEventMessages($object->error, $object->errors, 'errors');
205 }
206 }
207
208 if (!$error) {
209 $old_date_echeance = $object->date_echeance;
210 $new_date_echeance = $object->calculate_date_lim_reglement();
211 if ($new_date_echeance > $old_date_echeance) {
212 $object->date_echeance = $new_date_echeance;
213 }
214 if ($object->date_echeance < $object->date) {
215 $object->date_echeance = $object->date;
216 }
217 $result = $object->update($user);
218 if ($result < 0) {
219 $error++;
220 setEventMessages($object->error, $object->errors, 'errors');
221 }
222 }
223
224 if ($error) {
225 $db->rollback();
226 } else {
227 $db->commit();
228 }
229 } elseif ($action == 'setmode' && $usercancreate) {
230 // payment mode
231 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
232 } elseif ($action == 'setdatef' && $usercancreate) {
233 $newdate = dol_mktime(0, 0, 0, GETPOSTINT('datefmonth'), GETPOSTINT('datefday'), GETPOSTINT('datefyear'), 'tzserver');
234 if ($newdate > (dol_now('tzuserrel') + getDolGlobalInt('INVOICE_MAX_FUTURE_DELAY'))) {
235 if (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY')) {
236 setEventMessages($langs->trans("WarningInvoiceDateInFuture"), null, 'warnings');
237 } else {
238 setEventMessages($langs->trans("WarningInvoiceDateTooFarInFuture"), null, 'warnings');
239 }
240 }
241
242 $object->date = $newdate;
243 $date_echence_calc = $object->calculate_date_lim_reglement();
244 if (!empty($object->date_echeance) && $object->date_echeance < $date_echence_calc) {
245 $object->date_echeance = $date_echence_calc;
246 }
247 if ($object->date_echeance && $object->date_echeance < $object->date) {
248 $object->date_echeance = $object->date;
249 }
250
251 $result = $object->update($user);
252 if ($result < 0) {
253 dol_print_error($db, $object->error);
254 }
255 } elseif ($action == 'setdate_lim_reglement' && $usercancreate) {
256 $object->date_echeance = dol_mktime(12, 0, 0, GETPOSTINT('date_lim_reglementmonth'), GETPOSTINT('date_lim_reglementday'), GETPOSTINT('date_lim_reglementyear'));
257 if (!empty($object->date_echeance) && $object->date_echeance < $object->date) {
258 $object->date_echeance = $object->date;
259 setEventMessages($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), null, 'warnings');
260 }
261 $result = $object->update($user);
262 if ($result < 0) {
263 dol_print_error($db, $object->error);
264 }
265 }
266}
267
268
269/*
270 * View
271 */
272
273$form = new Form($db);
274
275$now = dol_now();
276
277if ($type == 'bank-transfer') {
278 $title = $langs->trans('SupplierInvoice')." - ".$langs->trans('CreditTransfer');
279 $helpurl = "";
280} else {
281 $title = $langs->trans('InvoiceCustomer')." - ".$langs->trans('StandingOrders');
282 $helpurl = "EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes";
283}
284
285llxHeader('', $title, $helpurl);
286
287
288if ($object->id > 0) {
289 $selleruserevenustamp = $mysoc->useRevenueStamp();
290
291 $totalpaid = $object->getSommePaiement();
292 $totalcreditnotes = $object->getSumCreditNotesUsed();
293 $totaldeposits = $object->getSumDepositsUsed();
294 //print "totalpaid=".$totalpaid." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits;
295
296 // We can also use bcadd to avoid pb with floating points
297 // For example print 239.2 - 229.3 - 9.9; does not return 0.
298 //$resteapayer=bcadd($object->total_ttc,$totalpaid,$conf->global->MAIN_MAX_DECIMALS_TOT);
299 //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
300 $resteapayer = price2num($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
301
302 if ($object->paid) {
303 $resteapayer = 0;
304 }
305
306 if ($type == 'bank-transfer') {
307 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { // Not recommended
308 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
309 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
310 } else {
311 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
312 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
313 }
314
315 $absolute_discount = $object->thirdparty->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
316 $absolute_creditnote = $object->thirdparty->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
317 $absolute_discount = price2num($absolute_discount, 'MT');
318 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
319 } else {
320 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) { // Not recommended
321 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
322 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
323 } else {
324 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
325 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
326 }
327
328 $absolute_discount = $object->thirdparty->getAvailableDiscounts(null, $filterabsolutediscount);
329 $absolute_creditnote = $object->thirdparty->getAvailableDiscounts(null, $filtercreditnote);
330 $absolute_discount = price2num($absolute_discount, 'MT');
331 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
332 }
333
334 $author = new User($db);
335 if (!empty($object->user_creation_id)) {
336 $author->fetch($object->user_creation_id);
337 } elseif (!empty($object->fk_user_author)) { // For backward compatibility
338 $author->fetch($object->fk_user_author);
339 }
340
341 if ($type == 'bank-transfer') {
343 } else {
345 }
346
347 $numopen = 0;
348 $pending = 0;
349 $numclosed = 0;
350
351 // How many Direct debit or Credit transfer open requests ?
352 $listofopendirectdebitorcredittransfer = $object->getListOfOpenDirectDebitOrCreditTransfer($type);
353 $numopen = count($listofopendirectdebitorcredittransfer);
354
355 print dol_get_fiche_head($head, 'standingorders', $title, -1, ($type == 'bank-transfer' ? 'supplier_invoice' : $object->picto));
356
357 // Invoice content
358 if ($type == 'bank-transfer') {
359 $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
360 } else {
361 $linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
362 }
363
364 $morehtmlref = '<div class="refidno">';
365 // Ref customer
366 if ($type == 'bank-transfer') {
367 $morehtmlref .= $form->editfieldkey("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', 0, 1);
368 $morehtmlref .= $form->editfieldval("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', null, null, '', 1);
369 } else {
370 $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_customer, $object, 0, 'string', '', 0, 1);
371 $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_customer, $object, 0, 'string', '', null, null, '', 1);
372 }
373 // Thirdparty
374 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
375 if ($type == 'bank-transfer') {
376 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
377 $morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherBills").'</a>)</div>';
378 }
379 } else {
380 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
381 $morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherBills").'</a>)</div>';
382 }
383 }
384 // Project
385 if (isModEnabled('project')) {
386 $langs->load("projects");
387 $morehtmlref .= '<br>';
388 if (0) { // @phpstan-ignore-line
389 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
390 if ($action != 'classify') {
391 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => ((int) $object->id)], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
392 }
393 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
394 } else {
395 if (!empty($object->fk_project)) {
396 $proj = new Project($db);
397 $proj->fetch($object->fk_project);
398 $morehtmlref .= $proj->getNomUrl(1);
399 if ($proj->title) {
400 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
401 }
402 }
403 }
404 }
405 $morehtmlref .= '</div>';
406
407 $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
408
409 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $moreparam, 0, '', '');
410
411 print '<div class="fichecenter">';
412 print '<div class="fichehalfleft">';
413 print '<div class="underbanner clearboth"></div>';
414
415 print '<table class="border centpercent tableforfield">';
416
417 // Type
418 print '<tr><td class="titlefield fieldname_type">'.$langs->trans('Type').'</td><td colspan="3">';
419 print '<span class="badgeneutral">';
420 print $object->getLibType();
421 print '</span>';
422 if (!empty($object->module_source)) {
423 print ' <span class="opacitymediumbycolor paddingleft">('.$langs->trans("POS").' '.$object->module_source.' - '.$langs->trans("Terminal").' '.$object->pos_source.')</span>';
424 }
425 if ($object->type == $object::TYPE_REPLACEMENT) {
426 if ($type == 'bank-transfer') {
427 $facreplaced = new FactureFournisseur($db);
428 } else {
429 $facreplaced = new Facture($db);
430 }
431 $facreplaced->fetch($object->fk_facture_source);
432 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).'</span>';
433 }
434 if ($object->type == $object::TYPE_CREDIT_NOTE && !empty($object->fk_facture_source)) {
435 if ($type == 'bank-transfer') {
436 $facusing = new FactureFournisseur($db);
437 } else {
438 $facusing = new Facture($db);
439 }
440 $facusing->fetch($object->fk_facture_source);
441 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).'</span>';
442 }
443
444 // Retrieve credit note ids
445 $object->getListIdAvoirFromInvoice();
446
447 if (!empty($object->creditnote_ids)) {
448 $invoicecredits = array();
449 foreach ($object->creditnote_ids as $invoiceid) {
450 if ($type == 'bank-transfer') {
451 $creditnote = new FactureFournisseur($db);
452 } else {
453 $creditnote = new Facture($db);
454 }
455 $creditnote->fetch($invoiceid);
456 $invoicecredits[] = $creditnote->getNomUrl(1);
457 }
458 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("InvoiceHasAvoir");
459 print ' '. (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits);
460 print '</span>';
461 }
462 /*
463 if ($objectidnext > 0) {
464 $facthatreplace=new Facture($db);
465 $facthatreplace->fetch($objectidnext);
466 print ' <span class="opacitymediumbycolor paddingleft">'.str_replace('{s1}', $facthatreplace->getNomUrl(1), $langs->transnoentities("ReplacedByInvoice", '{s1}')).'</span>';
467 }
468 */
469 print '</td></tr>';
470
471 // Relative and absolute discounts
472 print '<!-- Discounts -->'."\n";
473 print '<tr><td>'.$langs->trans('DiscountStillRemaining').'</td><td colspan="3">';
474
475 if ($type == 'bank-transfer') {
476 //$societe = new Fournisseur($db);
477 //$result = $societe->fetch($object->socid);
478 $thirdparty = $object->thirdparty;
479 $discount_type = 1;
480 } else {
481 $thirdparty = $object->thirdparty;
482 $discount_type = 0;
483 }
484 $backtopage = urlencode($_SERVER["PHP_SELF"].'?facid='.$object->id);
485 $cannotApplyDiscount = 1;
486 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
487
488 print '</td></tr>';
489
490 // Label
491 if ($type == 'bank-transfer') {
492 print '<tr>';
493 print '<td>'.$form->editfieldkey("Label", 'label', $object->label, $object, 0).'</td>';
494 print '<td>'.$form->editfieldval("Label", 'label', $object->label, $object, 0).'</td>';
495 print '</tr>';
496 }
497
498 // Date invoice
499 print '<tr><td>';
500 print '<table class="nobordernopadding centpercent"><tr><td>';
501 print $langs->trans('DateInvoice');
502 print '</td>';
503 if ($object->type != $object::TYPE_CREDIT_NOTE && $action != 'editinvoicedate' && $object->status == $object::STATUS_DRAFT && $user->hasRight('facture', 'creer')) {
504 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editinvoicedate&token='.newToken().'&id='.$object->id.'&type='.urlencode($type).'">'.img_edit($langs->trans('SetDate'), 1).'</a></td>';
505 }
506 print '</tr></table>';
507 print '</td><td colspan="3">';
508
509 if ($object->type != $object::TYPE_CREDIT_NOTE) {
510 if ($action == 'editinvoicedate') {
511 print $form->form_date($_SERVER['PHP_SELF'].'?id='.$object->id, $object->date, 'invoicedate', 0, 0, 1, $type);
512 } else {
513 print dol_print_date($object->date, 'day');
514 }
515 } else {
516 print dol_print_date($object->date, 'day');
517 }
518 print '</td>';
519 print '</tr>';
520
521 // Payment condition
522 print '<tr><td>';
523 print '<table class="nobordernopadding centpercent"><tr><td>';
524 print $langs->trans('PaymentConditionsShort');
525 print '</td>';
526 if ($object->type != $object::TYPE_CREDIT_NOTE && $action != 'editconditions' && $object->status == $object::STATUS_DRAFT && $user->hasRight('facture', 'creer')) {
527 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&id='.$object->id.'&type='.urlencode($type).'">'.img_edit($langs->trans('SetConditions'), 1).'</a></td>';
528 }
529 print '</tr></table>';
530 print '</td><td colspan="3">';
531 if ($object->type != $object::TYPE_CREDIT_NOTE) {
532 if ($action == 'editconditions') {
533 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'cond_reglement_id', 0, $type);
534 } else {
535 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'none');
536 }
537 } else {
538 print '&nbsp;';
539 }
540 print '</td></tr>';
541
542 // Date payment term
543 print '<tr><td>';
544 print '<table class="nobordernopadding centpercent"><tr><td>';
545 print $langs->trans('DateMaxPayment');
546 print '</td>';
547 if ($object->type != $object::TYPE_CREDIT_NOTE && $action != 'editpaymentterm' && $object->status == $object::STATUS_DRAFT && $user->hasRight('facture', 'creer')) {
548 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editpaymentterm&token='.newToken().'&id='.$object->id.'&type='.urlencode($type).'">'.img_edit($langs->trans('SetDate'), 1).'</a></td>';
549 }
550 print '</tr></table>';
551 print '</td><td colspan="3">';
552 if ($object->type != $object::TYPE_CREDIT_NOTE) {
553 $duedate = $object->date_lim_reglement;
554 if ($type == 'bank-transfer') {
555 $duedate = $object->date_echeance;
556 }
557
558 if ($action == 'editpaymentterm') {
559 print $form->form_date($_SERVER['PHP_SELF'].'?id='.$object->id, $duedate, 'paymentterm', 0, 0, 1, $type);
560 } else {
561 print dol_print_date($duedate, 'day');
562 if ($object->hasDelay()) {
563 print img_warning($langs->trans('Late'));
564 }
565 }
566 } else {
567 print '&nbsp;';
568 }
569 print '</td></tr>';
570
571 // Payment mode
572 print '<tr><td>';
573 print '<table class="nobordernopadding centpercent"><tr><td>';
574 print $langs->trans('PaymentMode');
575 print '</td>';
576 if ($action != 'editmode' && $object->status == $object::STATUS_DRAFT && $user->hasRight('facture', 'creer')) {
577 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&id='.$object->id.'&type='.urlencode($type).'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
578 }
579 print '</tr></table>';
580 print '</td><td colspan="3">';
581 $filtertype = 'CRDT';
582 if ($type == 'bank-transfer') {
583 $filtertype = 'DBIT';
584 }
585 if ($action == 'editmode') {
586 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', $filtertype, 1, 0, $type);
587 } else {
588 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
589 }
590 print '</td></tr>';
591
592 // Bank Account
593 print '<tr><td class="nowrap">';
594 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
595 print $langs->trans('BankAccount');
596 print '<td>';
597 if (($action != 'editbankaccount') && $user->hasRight('commande', 'creer') && $object->status == $object::STATUS_DRAFT) {
598 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&token='.newToken().'&id='.$object->id.'&type='.urlencode($type).'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
599 }
600 print '</tr></table>';
601 print '</td><td colspan="3">';
602 if ($action == 'editbankaccount') {
603 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
604 } else {
605 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
606 }
607 print '</td>';
608 print '</tr>';
609 print '</table>';
610 print '</div>';
611
612 print '<div class="fichehalfright">';
613 print '<!-- amounts -->'."\n";
614 print '<div class="underbanner clearboth"></div>'."\n";
615
616 print '<table class="border tableforfield centpercent">';
617
618 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
619
620 $sign = 1;
621 if (getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE_SCREEN') && $object->type == $object::TYPE_CREDIT_NOTE) {
622 $sign = -1; // We invert sign for output
623 }
624 print '<tr>';
625 // Amount HT
626 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
627 print '<td class="nowrap amountcard right">' . price($sign * $object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
628 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
629 // Multicurrency Amount HT
630 print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
631 }
632 print '</tr>';
633
634 print '<tr>';
635 // Amount VAT
636 print '<td>' . $langs->trans('AmountVAT') . '</td>';
637 print '<td class="nowrap amountcard right">' . price($sign * $object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
638 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
639 // Multicurrency Amount VAT
640 print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
641 }
642 print '</tr>';
643
644 // Amount Local Taxes
645 if (($mysoc->localtax1_assuj == "1" && $mysoc->useLocalTax(1)) || $object->total_localtax1 != 0) {
646 print '<tr>';
647 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
648 print '<td class="nowrap amountcard right">' . price($sign * $object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
649 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
650 $object->multicurrency_total_localtax1 = (float) price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
651
652 print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
653 }
654 print '</tr>';
655 }
656
657 if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) {
658 print '<tr>';
659 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
660 print '<td class="nowrap amountcard right">' . price($sign * $object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
661 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
662 $object->multicurrency_total_localtax2 = (float) price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
663
664 print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
665 }
666 print '</tr>';
667 }
668
669 // Revenue stamp
670 if ($selleruserevenustamp) { // Test company use revenue stamp
671 print '<tr><td>';
672 print '<table class="nobordernopadding centpercent"><tr><td>';
673 print $langs->trans('RevenueStamp');
674 print '</td>';
675 if ($action != 'editrevenuestamp' && $object->status == $object::STATUS_DRAFT && $user->hasRight('facture', 'creer')) {
676 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editrevenuestamp&token='.newToken().'&facid='.$object->id.'">'.img_edit($langs->trans('SetRevenuStamp'), 1).'</a></td>';
677 }
678 print '</tr></table>';
679 print '</td><td class="nowrap right">';
680 print price($object->revenuestamp, 1, '', 1, - 1, - 1, $conf->currency);
681 print '</td></tr>';
682 }
683
684 print '<tr>';
685 // Amount TTC
686 print '<td>' . $langs->trans('AmountTTC') . '</td>';
687 print '<td class="nowrap amountcard right">' . price($sign * $object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
688 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
689 // Multicurrency Amount TTC
690 print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
691 }
692 print '</tr>';
693
694
695 $resteapayer = price2num($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
696
697 // Hook to change amount for other reasons, e.g. apply cash discount for payment before agreed date
698 $parameters = array('remaintopay' => $resteapayer);
699 $reshook = $hookmanager->executeHooks('finalizeAmountOfInvoice', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
700 if ($reshook > 0) {
701 print $hookmanager->resPrint;
702 if (!empty($remaintopay = $hookmanager->resArray['remaintopay'])) {
703 $resteapayer = $remaintopay;
704 }
705 }
706
707 // TODO Replace this by an include with same code to show already done payment visible in invoice card
708 print '<tr><td>'.$langs->trans('RemainderToPay').'</td><td class="nowrap right">'.price($resteapayer, 1, '', 1, - 1, - 1, $conf->currency).'</td>';
709 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
710 print '<td></td>';
711 }
712 print '</tr>';
713
714 print '</table>';
715
716 print '</div>';
717 print '</div>';
718
719 print '<div class="clearboth"></div>';
720
721
722 print dol_get_fiche_end();
723
724
725 // For which amount ?
726 // Note: The 2 following SQL requests are wrong but it works because we have one record into pfd for one record into pl and for into p for the same fk_facture_fourn.
727 // The table prelevement and prelevement_lignes must be removed in future and merged into prelevement_demande
728 // Step 1: Move field fk_... of llx_prelevement into llx_prelevement_lignes
729 // Step 2: Move field fk_... + status into prelevement_demande.
730 $pending = 0;
731 // Get pending requests open with no transfer receipt yet
732 $sql = "SELECT SUM(pfd.amount) as amount";
733 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
734 if ($type == 'bank-transfer') {
735 $sql .= " WHERE pfd.fk_facture_fourn = ".((int) $object->id);
736 } else {
737 $sql .= " WHERE pfd.fk_facture = ".((int) $object->id);
738 }
739 $sql .= " AND pfd.traite = 0";
740 //$sql .= " AND pfd.type = 'ban'";
741 $resql = $db->query($sql);
742 if ($resql) {
743 $obj = $db->fetch_object($resql);
744 if ($obj) {
745 $pending += (float) $obj->amount;
746 }
747 } else {
749 }
750 // Get pending request with a transfer receipt generated but not yet processed
751 $sqlPending = "SELECT SUM(pl.amount) as amount";
752 $sqlPending .= " FROM ".$db->prefix()."prelevement_lignes as pl";
753 $sqlPending .= " INNER JOIN ".$db->prefix()."prelevement as p ON p.fk_prelevement_lignes = pl.rowid";
754 if ($type == 'bank-transfer') {
755 $sqlPending .= " WHERE p.fk_facture_fourn = ".((int) $object->id);
756 } else {
757 $sqlPending .= " WHERE p.fk_facture = ".((int) $object->id);
758 }
759 $sqlPending .= " AND (pl.statut IS NULL OR pl.statut = 0)";
760 $resPending = $db->query($sqlPending);
761 if ($resPending) {
762 if ($objPending = $db->fetch_object($resPending)) {
763 $pending += (float) $objPending->amount;
764 }
765 }
766 $db->free($resPending);
767
768 /*
769 $sql = "SELECT SUM(pfd.amount) as amount";
770 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
771 if ($type == 'bank-transfer') {
772 $sql .= " WHERE fk_facture_fourn = ".((int) $object->id);
773 } else {
774 $sql .= " WHERE fk_facture = ".((int) $object->id);
775 }
776 $sql .= " AND pfd.traite = 0";
777 $sql .= " AND pfd.type = 'ban'";
778
779 $resql = $db->query($sql);
780 if ($resql) {
781 $obj = $db->fetch_object($resql);
782 if ($obj) {
783 $pendingAmount = $obj->amount;
784 }
785 } else {
786 dol_print_error($db);
787 }
788 */
789
790 /*
791 * Buttons
792 */
793
794 print "\n".'<div class="tabsAction">'."\n";
795
796 $buttonlabel = $langs->trans("MakeWithdrawRequest");
797 $user_perms = $user->hasRight('prelevement', 'bons', 'creer');
798 if ($type == 'bank-transfer') {
799 $buttonlabel = $langs->trans("MakeBankTransferOrder");
800 $user_perms = $user->hasRight('paymentbybanktransfer', 'create');
801 }
802 // Calculate the remaining amount available for new transfer requests
803 // This takes into account pending requests (traite=0) and requests in non-credited transfer receipts
804 $remaintopaylesspendingdebit = $resteapayer - $pending;
805 // Add a transfer request
806 // If WITHDRAW_STRICT_CHECK_AMOUNT is enabled, allow multiple partial requests as long as the total requested amount doesn't exceed the invoice total
807 // Otherwise, use original behavior: block if any request is pending
808 if (getDolGlobalString('WITHDRAW_STRICT_CHECK_AMOUNT')) {
809 // New behavior: check remaining amount
810 $canCreateRequest = ($object->status > $object::STATUS_DRAFT && $object->paid == 0 && $remaintopaylesspendingdebit > 0);
811 } else {
812 // Original behavior: check if no open requests
813 $canCreateRequest = ($object->status > $object::STATUS_DRAFT && $object->paid == 0 && $numopen == 0 && $resteapayer > 0);
814 }
815 if ($canCreateRequest) {
816 if ($user_perms) {
817 $title = $langs->trans("NewStandingOrder");
818 if ($type == 'bank-transfer') {
819 $title = $langs->trans("NewPaymentByBankTransfer");
820 }
821 print '<!-- form to select BAN -->';
822 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
823 print '<input type="hidden" name="token" value="'.newToken().'" />';
824 print '<input type="hidden" name="id" value="'.$object->id.'" />';
825 print '<input type="hidden" name="type" value="'.$type.'" />';
826 print '<input type="hidden" name="action" value="new" />';
827 print '<div class="center formconsumeproduce">';
828 //print $langs->trans('CustomerIBAN').' ';
829 // if societe rib in model invoice, we preselect it
830 $selectedRib = '';
831 if ($object->element == 'invoice' && $object->fk_fac_rec_source) {
832 $facturerec = new FactureRec($db);
833 $facturerec->fetch($object->fk_fac_rec_source);
834 if ($facturerec->fk_societe_rib) {
835 $companyBankAccount = new CompanyBankAccount($db);
836 $res = $companyBankAccount->fetch($facturerec->fk_societe_rib);
837 $selectedRib = $companyBankAccount->id;
838 }
839 }
840 $selectedRib = $form->selectRib($selectedRib, 'accountcustomerid', '(fk_soc:=:'.$object->socid.")", $langs->trans("CustomerIBAN"), '', 1, 'maxwidth500 maxwidth250onsmartphone');
841 $defaultRibId = $object->thirdparty->getDefaultRib();
842 if ($defaultRibId) {
843 $companyBankAccount = new CompanyBankAccount($db);
844 $res = $companyBankAccount->fetch($defaultRibId);
845 if ($res > 0 && !$companyBankAccount->verif()) {
846 print img_warning('Error on default bank number for IBAN : '.$langs->trans($companyBankAccount->error));
847 }
848 } elseif (($type != 'bank-transfer' && $object->mode_reglement_code == 'PRE') || ($type == 'bank-transfer' && $object->mode_reglement_code == 'VIR')) {
849 print img_warning($langs->trans("NoDefaultIBANFound"));
850 }
851 // Bank Transfer Amount
853 print '<br>';
854 } else {
855 print ' &nbsp; &nbsp; ';
856 }
857 print '<label for="withdraw_request_amount">';
858 if ($type == 'bank-transfer') {
859 print $langs->trans('BankTransferAmount');
860 } else {
861 print $langs->trans("WithdrawRequestAmount");
862 }
863 print '</label> ';
864 print '<input type="text" class="right width75" id="withdraw_request_amount" name="withdraw_request_amount" value="'.$remaintopaylesspendingdebit.'">';
865 // Button
866 print '<br><br>';
867 print '<input type="submit" class="butAction small" value="'.$buttonlabel.'" />';
868 print '<br><br>';
869 print '</div>';
870 print '</form>';
871 if (getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT_SHOW_OLD_BUTTON')) { // This is hidden, prefer to use mode enabled with STRIPE_SEPA_DIRECT_DEBIT
872 // TODO Replace this with a checkbox for each payment mode: "Send request to XXX immediately..."
873 print "<br>";
874 // Add stripe sepa button
875 $buttonlabel = $langs->trans("MakeWithdrawRequestStripe");
876 print '<form method="POST" action="">';
877 print '<input type="hidden" name="token" value="'.newToken().'" />';
878 print '<input type="hidden" name="id" value="'.$object->id.'" />';
879 print '<input type="hidden" name="type" value="'.$type.'" />';
880 print '<input type="hidden" name="action" value="new" />';
881 print '<input type="hidden" name="paymenservice" value="stripesepa" />';
882 print '<label for="withdraw_request_amount">'.$langs->trans('BankTransferAmount').' </label>';
883 print '<input type="text" id="withdraw_request_amount" name="withdraw_request_amount" value="'.$remaintopaylesspendingdebit.'" size="9" />';
884 print '<input type="submit" class="butAction small" value="'.$buttonlabel.'" />';
885 print '</form>';
886 }
887 } else {
888 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$buttonlabel.'</a>';
889 }
890 } else {
891 // Different error messages based on the mode
892 if ($object->status > $object::STATUS_DRAFT) {
893 if ($object->paid == 0) {
894 if (getDolGlobalString('WITHDRAW_STRICT_CHECK_AMOUNT')) {
895 // Total amount has already been requested (pending + in transfer receipts)
896 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("AmountRequestedAlreadyReachesTotal")).'">'.$buttonlabel.'</a>';
897 } else {
898 // Original behavior: request already done or amount must be positive
899 if ($numopen > 0) {
900 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("RequestAlreadyDone")).'">'.$buttonlabel.'</a>';
901 } else {
902 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("AmountMustBePositive")).'">'.$buttonlabel.'</a>';
903 }
904 }
905 } else {
906 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("AlreadyPaid")).'">'.$buttonlabel.'</a>';
907 }
908 } else {
909 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("Draft")).'">'.$buttonlabel.'</a>';
910 }
911 }
912 print "</div>\n";
913
914
915 if ($type == 'bank-transfer') {
916 print '<div class="opacitymedium justify">'.$langs->trans("DoCreditTransferBeforePayments");
917 if (isModEnabled('stripe') && getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT')) {
918 print ' '.$langs->trans("DoStandingOrdersBeforePayments2");
919 }
920 print ' '.$langs->trans("DoStandingOrdersBeforePayments3");
921 print '</div><br><br>';
922 } else {
923 print '<div class="opacitymedium justify">'.$langs->trans("DoStandingOrdersBeforePayments");
924 if (isModEnabled('stripe') && getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT')) {
925 print ' '.$langs->trans("DoStandingOrdersBeforePayments2");
926 }
927 print ' '.$langs->trans("DoStandingOrdersBeforePayments3");
928 print '</div><br><br>';
929 }
930
931 /*
932 * Withdrawals
933 */
934
935 print '<div class="div-table-responsive-no-min">';
936 print '<table class="noborder centpercent">';
937
938 print '<tr class="liste_titre">';
939 // Action column
940 if ($conf->main_checkbox_left_column) {
941 print '<td>&nbsp;</td>';
942 }
943 print '<td class="left">'.$langs->trans("ID").'</td>';
944 print '<td class="left">'.$langs->trans("DateRequest").'</td>';
945 print '<td>'.$langs->trans("User").'</td>';
946 print '<td class="center">'.$langs->trans("Amount").'</td>';
947 print '<td class="center">'.$langs->trans("IBAN").'</td>';
948 print '<td class="center">'.$langs->trans("DateProcess").'</td>';
949 if ($type == 'bank-transfer') {
950 print '<td class="">'.$langs->trans("BankTransferReceipt").'</td>';
951 } else {
952 print '<td class="">'.$langs->trans("WithdrawalReceipt").'</td>';
953 }
954 print '<td>&nbsp;</td>';
955 // Action column
956 if (!$conf->main_checkbox_left_column) {
957 print '<td>&nbsp;</td>';
958 }
959 print '</tr>';
960
961 $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande,";
962 $sql .= " pfd.date_traite as date_traite, pfd.amount, pfd.fk_prelevement_bons,";
963 $sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status, pb.amount as pb_amount,";
964 $sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status,";
965 $sql .= " sr.iban_prefix as iban, sr.bic as bic";
966 $sql .= " FROM ".$db->prefix()."prelevement_demande as pfd";
967 $sql .= " LEFT JOIN ".$db->prefix()."user as u on pfd.fk_user_demande = u.rowid";
968 $sql .= " LEFT JOIN ".$db->prefix()."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons";
969 $sql .= " LEFT JOIN ".$db->prefix()."societe_rib as sr ON sr.rowid = pfd.fk_societe_rib";
970 if ($type == 'bank-transfer') {
971 $sql .= " WHERE fk_facture_fourn = ".((int) $object->id);
972 } else {
973 $sql .= " WHERE fk_facture = ".((int) $object->id);
974 }
975 $sql .= " AND pfd.traite = 0";
976 $sql .= " AND pfd.type = 'ban'";
977 $sql .= " ORDER BY pfd.date_demande DESC";
978
979 $resql = $db->query($sql);
980
981 $num = 0;
982 if ($resql) {
983 $i = 0;
984
985 $tmpuser = new User($db);
986
987 $num = $db->num_rows($resql);
988 while ($i < $num) {
989 $obj = $db->fetch_object($resql);
990
991 $tmpuser->id = $obj->user_id;
992 $tmpuser->login = $obj->login;
993 $tmpuser->ref = $obj->login;
994 $tmpuser->email = $obj->email;
995 $tmpuser->lastname = $obj->lastname;
996 $tmpuser->firstname = $obj->firstname;
997 $tmpuser->statut = $obj->user_status;
998 $tmpuser->status = $obj->user_status;
999
1000 print '<tr class="oddeven">';
1001
1002 // Action column
1003 if ($conf->main_checkbox_left_column) {
1004 print '<td class="center">';
1005 print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete&token='.newToken().'&did='.$obj->rowid.'&type='.urlencode($type).'">';
1006 print img_delete();
1007 print '</a>';
1008 print '</td>';
1009 }
1010
1011 // ID
1012 print '<td class="nowraponall">'.$obj->rowid."</td>\n";
1013
1014 // Date
1015 print '<td class="nowraponall">'.dol_print_date($db->jdate($obj->date_demande), 'dayhour')."</td>\n";
1016
1017 // User
1018 print '<td class="tdoverflowmax125">';
1019 print $tmpuser->getNomUrl(-1, '', 0, 0, 0, 0, 'login');
1020 print '</td>';
1021
1022 // Amount
1023 print '<td class="center"><span class="amount">'.price($obj->amount).'</span></td>';
1024
1025 // Iban
1026 print '<td class="center"><span class="iban">';
1027 print dolDecrypt($obj->iban);
1028 if ($obj->iban && $obj->bic) {
1029 print " / ";
1030 }
1031 print $obj->bic;
1032 print '</span></td>';
1033
1034 // Date process
1035 print '<td class="center"><span class="opacitymedium">'.$langs->trans("OrderWaiting").'</span></td>';
1036
1037 // Link to make payment now
1038 print '<td class="minwidth75">';
1039 if ($obj->fk_prelevement_bons > 0) {
1040 $withdrawreceipt = new BonPrelevement($db);
1041 $withdrawreceipt->id = $obj->fk_prelevement_bons;
1042 $withdrawreceipt->ref = $obj->ref;
1043 $withdrawreceipt->date_trans = $db->jdate($obj->date_trans);
1044 $withdrawreceipt->date_credit = $db->jdate($obj->date_credit);
1045 $withdrawreceipt->date_creation = $db->jdate($obj->datec);
1046 $withdrawreceipt->statut = $obj->status;
1047 $withdrawreceipt->status = $obj->status;
1048 $withdrawreceipt->amount = $obj->pb_amount;
1049 //$withdrawreceipt->credite = $db->jdate($obj->credite);
1050
1051 print $withdrawreceipt->getNomUrl(1);
1052 }
1053
1054 if ($type != 'bank-transfer') {
1055 if (getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT')) {
1056 $langs->load("stripe");
1057 if ($obj->fk_prelevement_bons > 0) {
1058 print ' &nbsp; ';
1059 }
1060 print '<a href="'.$_SERVER["PHP_SELF"].'?action=sepastripedirectdebit&paymentservice=stripesepa&token='.newToken().'&did='.$obj->rowid.'&id='.$object->id.'&type='.urlencode($type).'">'.img_picto('', 'stripe', 'class="pictofixedwidth"').$langs->trans("RequestDirectDebitWithStripe").'</a>';
1061 }
1062 } else {
1063 if (getDolGlobalString('STRIPE_SEPA_CREDIT_TRANSFER')) {
1064 $langs->load("stripe");
1065 if ($obj->fk_prelevement_bons > 0) {
1066 print ' &nbsp; ';
1067 }
1068 print '<a href="'.$_SERVER["PHP_SELF"].'?action=sepastripecredittransfer&paymentservice=stripesepa&token='.newToken().'&did='.$obj->rowid.'&id='.$object->id.'&type='.urlencode($type).'">'.img_picto('', 'stripe', 'class="pictofixedwidth"').$langs->trans("RequesCreditTransferWithStripe").'</a>';
1069 }
1070 }
1071 print '</td>';
1072
1073 // Withraw ref
1074 print '<td class="">';
1075 //print '<span class="opacitymedium">'.$langs->trans("OrderWaiting").'</span>';
1076 print '</td>';
1077
1078 // Action column
1079 if (!$conf->main_checkbox_left_column) {
1080 print '<td class="center">';
1081 print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete&token='.newToken().'&did='.$obj->rowid.'&type='.urlencode($type).'">';
1082 print img_delete();
1083 print '</a></td>';
1084 }
1085
1086 print "</tr>\n";
1087 $i++;
1088 }
1089
1090 $db->free($resql);
1091 } else {
1093 }
1094
1095
1096 // Past requests
1097
1098 $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande, pfd.date_traite, pfd.fk_prelevement_bons, pfd.amount, pfd.fk_societe_rib, pfd.ext_payment_id, pfd.ext_payment_site,";
1099 $sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status, pb.fk_bank_account, pb.amount as pb_amount,";
1100 $sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status, u.photo as user_photo,";
1101 $sql .= " sr.iban_prefix as iban, sr.bic as bic";
1102 $sql .= " FROM ".$db->prefix()."prelevement_demande as pfd";
1103 $sql .= " LEFT JOIN ".$db->prefix()."user as u on pfd.fk_user_demande = u.rowid";
1104 $sql .= " LEFT JOIN ".$db->prefix()."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons";
1105 $sql .= " LEFT JOIN ".$db->prefix()."societe_rib as sr ON sr.rowid = pfd.fk_societe_rib";
1106 if ($type == 'bank-transfer') {
1107 $sql .= " WHERE fk_facture_fourn = ".((int) $object->id);
1108 } else {
1109 $sql .= " WHERE fk_facture = ".((int) $object->id);
1110 }
1111 $sql .= " AND pfd.traite = 1";
1112 $sql .= " AND pfd.type = 'ban'";
1113 //$sql .= " AND pfd.entity IN (".getEntity('prelevement_demande').")"; // Disabled because the filter on fk_facture... should be enough.
1114 $sql .= " ORDER BY pfd.date_demande DESC";
1115
1116 $resql = $db->query($sql);
1117 if ($resql) {
1118 $num = $db->num_rows($resql);
1119 $numclosed = $num;
1120 $i = 0;
1121
1122 $tmpuser = new User($db);
1123
1124 while ($i < $num) {
1125 $obj = $db->fetch_object($resql);
1126
1127 $tmpuser->id = $obj->user_id;
1128 $tmpuser->login = $obj->login;
1129 $tmpuser->ref = $obj->login;
1130 $tmpuser->email = $obj->email;
1131 $tmpuser->lastname = $obj->lastname;
1132 $tmpuser->firstname = $obj->firstname;
1133 $tmpuser->statut = $obj->user_status;
1134 $tmpuser->status = $obj->user_status;
1135 $tmpuser->photo = $obj->user_photo;
1136
1137 print '<tr class="oddeven">';
1138
1139 // Action column
1140 if ($conf->main_checkbox_left_column) {
1141 print '<td>&nbsp;</td>';
1142 }
1143
1144 // ID
1145 print '<td class="nowraponall">'.$obj->rowid."</td>\n";
1146
1147 // Date
1148 print '<td class="nowraponall">'.dol_print_date($db->jdate($obj->date_demande), 'day', 'tzuserrel')."</td>\n";
1149
1150 // User
1151 print '<td class="tdoverflowmax125">';
1152 print $tmpuser->getNomUrl(-1, '', 0, 0, 0, 0, 'login');
1153 print '</td>';
1154
1155 // Amount
1156 print '<td class="center"><span class="amount">'.price($obj->amount).'</span></td>';
1157
1158 // Iban
1159 print '<td class="center"><span class="iban">';
1160 print dolDecrypt($obj->iban);
1161 if ($obj->iban && $obj->bic) {
1162 print " / ";
1163 }
1164 print $obj->bic;
1165 print '</span></td>';
1166
1167 // Date process
1168 print '<td class="center nowraponall">'.dol_print_date($db->jdate($obj->date_traite), 'dayhour', 'tzuserrel')."</td>\n";
1169
1170 // Link to payment request done
1171 print '<td class="minwidth75">';
1172 if ($obj->fk_prelevement_bons > 0) {
1173 $withdrawreceipt = new BonPrelevement($db);
1174 $withdrawreceipt->id = $obj->fk_prelevement_bons;
1175 $withdrawreceipt->ref = $obj->ref;
1176 $withdrawreceipt->date_trans = $db->jdate($obj->date_trans);
1177 $withdrawreceipt->date_credit = $db->jdate($obj->date_credit);
1178 $withdrawreceipt->date_creation = $db->jdate($obj->datec);
1179 $withdrawreceipt->statut = $obj->status;
1180 $withdrawreceipt->status = $obj->status;
1181 $withdrawreceipt->fk_bank_account = $obj->fk_bank_account;
1182 $withdrawreceipt->amount = $obj->pb_amount;
1183 //$withdrawreceipt->credite = $db->jdate($obj->credite);
1184
1185 print $withdrawreceipt->getNomUrl(1);
1186 print ' ';
1187 print $withdrawreceipt->getLibStatut(2);
1188
1189 // Show the bank account
1190 $fk_bank_account = $withdrawreceipt->fk_bank_account;
1191 if (empty($fk_bank_account)) {
1192 $fk_bank_account = ($object->type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
1193 }
1194 if ($fk_bank_account > 0) {
1195 $bankaccount = new Account($db);
1196 $result = $bankaccount->fetch($fk_bank_account);
1197 if ($result > 0) {
1198 print ' - ';
1199 print $bankaccount->getNomUrl(1);
1200 }
1201 }
1202 if (!empty($obj->ext_payment_id) || !empty($obj->ext_payment_site)) {
1203 print ' - <span class="small opacitymedium">';
1204 print $obj->ext_payment_id.'/'.$obj->ext_payment_site;
1205 print '</span>';
1206 }
1207 }
1208 print "</td>\n";
1209
1210 //
1211 print '<td>&nbsp;</td>';
1212
1213 // Action column
1214 if (!$conf->main_checkbox_left_column) {
1215 print '<td>&nbsp;</td>';
1216 }
1217
1218 print "</tr>\n";
1219 $i++;
1220 }
1221
1222 if (!$numopen && !$numclosed) {
1223 print '<tr class="oddeven"><td colspan="9"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
1224 }
1225
1226 $db->free($resql);
1227 } else {
1229 }
1230
1231 print "</table>";
1232 print '</div>';
1233}
1234
1235// End of page
1236llxFooter();
1237$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
Class to manage bank accounts.
Class to manage withdrawal receipts.
Class to manage bank accounts description of third parties.
Class to manage suppliers invoices.
Class to manage invoices.
const STATUS_DRAFT
Draft status.
Class to manage invoice templates.
Class to manage generation of HTML components Only common components must be here.
Class to manage projects.
Class to manage Dolibarr users.
global $mysoc
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
facturefourn_prepare_head(FactureFournisseur $object)
Prepare array with list of tabs.
Definition fourn.lib.php:38
dol_now($mode='gmt')
Return date for now.
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...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
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.
getDolOptimizeSmallScreen()
Return if render must be optimized for small screen.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
facture_prepare_head($object)
Initialize the array of tabs for customer invoice.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.