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