dolibarr 24.0.2
paiement.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
5 * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
6 * Copyright (C) 2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
7 * Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
8 * Copyright (C) 2015 Juanjo Menent <jmenent@2byte.es>
9 * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
10 * Copyright (C) 2018 Thibault FOUCART <support@ptibogxiv.net>
11 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2020 Andreu Bisquerra Gaya <jove@bisquerra.com>
13 * Copyright (C) 2021 OpenDsi <support@open-dsi.fr>
14 * Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com>
15 * Copyright (C) 2023 Sylvain Legrand <technique@infras.fr>
16 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <https://www.gnu.org/licenses/>.
30 */
31
37require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
38require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
39
40
45{
49 public $element = 'payment';
50
54 public $table_element = 'paiement';
55
59 public $picto = 'payment';
60
64 public $facid;
65
69 public $socid;
70
74 public $datepaye;
75
79 public $date;
80
86 public $total;
87
93 public $montant;
94
98 public $amount;
99
103 public $multicurrency_amount;
104
108 public $multicurrency_currency;
109
113 public $amounts = array();
114
118 public $multicurrency_amounts = array();
119
123 public $multicurrency_tx = array();
124
128 public $multicurrency_code = array();
129
133 public $pos_change = 0.0;
134
138 public $author;
139
143 public $paiementid;
144
148 public $paiementcode;
149
153 public $type_label;
154
158 public $type_code;
159
165 public $num_paiement;
166
171 public $num_payment;
172
176 public $id_prelevement;
177
181 public $num_prelevement;
182
186 public $ext_payment_id;
187
191 public $ext_payment_site;
192
198 public $bank_account;
199
203 public $fk_account;
204
208 public $bank_line;
209
210 // fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...)
211 // fk_paiement dans llx_paiement_facture est le rowid du paiement
215 public $fk_paiement; // Type of payment
216
220 public $ref_ext;
221
222
228 public function __construct($db)
229 {
230 $this->db = $db;
231 }
232
241 public function fetch($id, $ref = '', $fk_bank = 0)
242 {
243 $sql = 'SELECT p.rowid, p.ref, p.ref_ext, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank, p.multicurrency_amount,';
244 $sql .= ' c.code as type_code, c.libelle as type_label,';
245 $sql .= ' p.num_paiement as num_payment, p.note,';
246 $sql .= ' b.fk_account';
247 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
248 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
249 $sql .= ' WHERE p.entity IN ('.getEntity('invoice').')';
250 if ($id > 0) {
251 $sql .= ' AND p.rowid = '.((int) $id);
252 } elseif ($ref) {
253 $sql .= " AND p.ref = '".$this->db->escape($ref)."'";
254 } elseif ($fk_bank) {
255 $sql .= ' AND p.fk_bank = '.((int) $fk_bank);
256 }
257
258 $resql = $this->db->query($sql);
259 if ($resql) {
260 if ($this->db->num_rows($resql)) {
261 $obj = $this->db->fetch_object($resql);
262
263 $this->id = $obj->rowid;
264 $this->ref = $obj->ref ? $obj->ref : $obj->rowid;
265 $this->ref_ext = $obj->ref_ext;
266 $this->date = $this->db->jdate($obj->dp);
267 $this->datepaye = $this->db->jdate($obj->dp);
268 $this->num_payment = $obj->num_payment;
269 $this->montant = $obj->amount; // deprecated
270 $this->amount = $obj->amount;
271 $this->multicurrency_amount = $obj->multicurrency_amount;
272 $this->note = $obj->note;
273 $this->note_private = $obj->note;
274 $this->type_label = $obj->type_label;
275 $this->type_code = $obj->type_code;
276 $this->statut = $obj->statut;
277 $this->ext_payment_id = $obj->ext_payment_id;
278 $this->ext_payment_site = $obj->ext_payment_site;
279
280 $this->bank_account = $obj->fk_account; // deprecated
281 $this->fk_account = $obj->fk_account;
282 $this->bank_line = $obj->fk_bank;
283
284 $this->fetch_optionals();
285 $this->db->free($resql);
286 return 1;
287 } else {
288 $this->db->free($resql);
289 return 0;
290 }
291 } else {
292 dol_print_error($this->db);
293 return -1;
294 }
295 }
296
309 public function create($user, $closepaidinvoices = 0, $thirdparty = null)
310 {
311 global $conf, $langs;
312
313 $error = 0;
314 $way = $this->getWay(); // 'dolibarr' to use amount, 'customer' to use foreign multicurrency amount
315
316 $now = dol_now();
317
318 // Clean parameters
319 $totalamount = 0;
320 $totalamount_converted = 0;
321 $atleastonepaymentnotnull = 0;
322
323 if ($way == 'dolibarr') { // Payments were entered into the column of main currency
324 $amounts = &$this->amounts;
325 $amounts_to_update = &$this->multicurrency_amounts;
326 } else { // Payments were entered into the column of foreign currency
327 $amounts = &$this->multicurrency_amounts;
328 $amounts_to_update = &$this->amounts;
329 }
330
331 $currencyofpayment = '';
332 $currencyofinvoices = '';
333 $currencytxofpayment = '';
334
335 foreach ($amounts as $key => $value) { // How payment is dispatched. $key is ID of invoice
336 if (empty($value)) {
337 continue;
338 }
339 $value_converted = false;
340 $tmparray = MultiCurrency::getInvoiceRate($key, 'facture');
341 $invoice_multicurrency_tx = $tmparray['invoice_multicurrency_tx'];
342 $invoice_multicurrency_code = $tmparray['invoice_multicurrency_code'];
343
344 // $key is id of invoice, $value is amount, $way is 'dolibarr' if amount is in main currency, 'customer' if in foreign currency
345 if ($invoice_multicurrency_tx) {
346 if ($way == 'dolibarr') {
347 $value_converted = (float) price2num($value * $invoice_multicurrency_tx, 'MU');
348 } else {
349 $value_converted = (float) price2num($value / $invoice_multicurrency_tx, 'MU');
350 }
351 } else {
352 $invoice_multicurrency_tx = false;
353 }
354
355 // Add controls of input validity
356 if ($value_converted === false) {
357 // We failed to find the conversion for one invoice
358 $this->error = $langs->trans('FailedToFoundTheConversionRateForInvoice');
359 return -1;
360 }
361
362 // Set the currency of the invoice
363 $currencyofinvoiceforthisline = empty($this->multicurrency_code[$key]) ? $invoice_multicurrency_code : $this->multicurrency_code[$key];
364 // If a payment was entered into the section of the foreign currency of invoice, we want to pay in the currency of invoice
365 $currencyofpaymentforthisline = empty($this->multicurrency_amounts[$key]) ? $conf->currency : $this->multicurrency_code[$key];
366
367 //var_dump("Invoice ID: ".$key.", amount in company cur:".$this->amounts[$key]." amount in invoice cur:".$this->multicurrency_amounts[$key]." => currencyofinvoice= ".$currencyofinvoiceforthisline." - currencyofpaymentforthisline =".$currencyofpaymentforthisline);
368
369 if (empty($currencyofinvoices)) {
370 $currencyofinvoices = $currencyofinvoiceforthisline;
371 } elseif ($currencyofinvoices != $currencyofinvoiceforthisline) {
372 // If we have invoices with different currencies in the payment, we stop here
373 $this->error = 'ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment';
374 return -1;
375 }
376
377 if (empty($currencyofpayment)) {
378 $currencyofpayment = $currencyofpaymentforthisline;
379 } elseif ($currencyofpayment != $currencyofpaymentforthisline) {
380 // If we have invoices with different currencies in the payment, we stop here
381 $this->error = 'ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment';
382 return -1;
383 }
384
385 if (empty($currencytxofpayment)) {
386 $currencytxofpayment = isset($this->multicurrency_tx[$key]) ? $this->multicurrency_tx[$key] : "";
387 }
388
389 $totalamount_converted += $value_converted; // Total in currency of the invoice
390 $amounts_to_update[$key] = price2num($value_converted, 'MT');
391
392 $newvalue = price2num($value, 'MT');
393 $amounts[$key] = $newvalue;
394 $totalamount += $newvalue;
395 if (!empty($newvalue)) {
396 $atleastonepaymentnotnull++;
397 }
398
399 //var_dump('currencytxofpayment = '.$currencytxofpayment." totalamount_converted =".$totalamount_converted);
400 //print '<br>';
401 }
402
403 if (empty($currencyofpayment)) { // Should not happen. For the case the multicurrency_code was not saved into invoices
404 $currencyofpayment = $conf->currency;
405 }
406
407 if (!empty($currencyofpayment && !empty($this->fk_account))) {
408 // We must check that the currency of invoices is the same than the currency of the bank
409 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
410 $bankaccount = new Account($this->db);
411 $bankaccount->fetch((int) $this->fk_account);
412 $bankcurrencycode = empty($bankaccount->currency_code) ? $conf->currency : $bankaccount->currency_code;
413
414 if ($bankcurrencycode != $conf->currency) {
415 // If we try to pay on a bank with a different currency
416 if ($bankcurrencycode != $currencyofinvoices && $currencyofinvoices != $conf->currency) {
417 $langs->load("errors");
418 $this->error = $langs->trans('ErrorYouTryToPayInvoicesInACurrencyFromBankWithAnotherCurrency', $currencyofinvoices, $bankcurrencycode);
419 return -1;
420 }
421 if ($bankcurrencycode != $currencyofpayment && $currencyofpayment != $conf->currency) {
422 $langs->load("errors");
423 $this->error = $langs->trans('ErrorYouTryToPayInvoicesInACurrencyFromBankWithAnotherCurrency', $currencyofpayment, $bankcurrencycode);
424 return -1;
425 }
426 } else {
427 // No problem in this case
428 }
429 }
430
431 $totalamount = (float) price2num($totalamount, 'MT');
432 $totalamount_converted = (float) price2num($totalamount_converted, 'MT');
433
434 // Check parameters
435 if (empty($totalamount) && empty($atleastonepaymentnotnull)) { // We accept negative amounts for withdraw reject but not empty arrays
436 $this->errors[] = 'TotalAmountEmpty';
437 $this->error = $langs->trans('TotalAmountEmpty');
438 return -1;
439 }
440
441 dol_syslog(get_class($this)."::create insert paiement (closepaidinvoices = ".$closepaidinvoices.")", LOG_DEBUG);
442
443 $this->db->begin();
444
445 $this->ref = $this->getNextNumRef(is_object($thirdparty) ? $thirdparty : '');
446
447 if (empty($this->ref_ext)) {
448 $this->ref_ext = '';
449 }
450
451 if ($way == 'dolibarr') {
452 $total = $totalamount;
453 $mtotal = $totalamount_converted;
454 } else {
455 $total = $totalamount_converted;
456 $mtotal = $totalamount;
457 }
458
459 $num_payment = $this->num_payment;
460 $note = ($this->note_private ? $this->note_private : $this->note);
461
462 $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, ref_ext, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat, pos_change)";
463 $sql .= " VALUES (".((int) $conf->entity).", '".$this->db->escape($this->ref)."', '".$this->db->escape($this->ref_ext)."', '".$this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".((float) $total).", ".((float) $mtotal).", ".((int) $this->paiementid).", ";
464 $sql .= "'".$this->db->escape($num_payment)."', '".$this->db->escape($note)."', ".($this->ext_payment_id ? "'".$this->db->escape($this->ext_payment_id)."'" : "null").", ".($this->ext_payment_site ? "'".$this->db->escape($this->ext_payment_site)."'" : "null").", ".((int) $user->id).", ".((float) $this->pos_change).")";
465
466 $resql = $this->db->query($sql);
467 if ($resql) {
468 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'paiement');
469
470 // Insert links amount / invoices
471 foreach ($this->amounts as $key => $amount) {
472 $facid = $key;
473 if (is_numeric($amount) && $amount != 0) {
474 $amount = price2num($amount);
475 $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement_facture (fk_facture, fk_paiement, amount, multicurrency_amount, multicurrency_code, multicurrency_tx)";
476 $sql .= " VALUES (".((int) $facid).", ".((int) $this->id).", ".((float) $amount).", ".((float) $this->multicurrency_amounts[$key]).", ".($currencyofpayment ? "'".$this->db->escape($currencyofpayment)."'" : 'NULL').", ".(!empty($this->multicurrency_tx) ? (float) $currencytxofpayment : 1).")";
477
478 dol_syslog(get_class($this).'::create Amount line '.$key.' insert paiement_facture', LOG_DEBUG);
479 $resql = $this->db->query($sql);
480 if ($resql) {
481 $invoice = new Facture($this->db);
482 $invoice->fetch($facid);
483
484 // If we want to closed paid invoices
485 if ($closepaidinvoices) {
486 $paiement = $invoice->getSommePaiement();
487 $creditnotes = $invoice->getSumCreditNotesUsed();
488 $deposits = $invoice->getSumDepositsUsed();
489 $alreadypayed = price2num($paiement + $creditnotes + $deposits, 'MT');
490 $remaintopay = price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT');
491
492 //var_dump($invoice->total_ttc.' - '.$paiement.' -'.$creditnotes.' - '.$deposits.' - '.$remaintopay);exit;
493
494 //Invoice types that are eligible for changing status to paid
495 $affected_types = array(
501 );
502
503 if (!in_array($invoice->type, $affected_types)) {
504 dol_syslog("Invoice ".$facid." is not a standard, nor replacement invoice, nor credit note, nor deposit invoice, nor situation invoice. We do nothing more.");
505 } elseif ($remaintopay) {
506 // hook to have an option to automatically close a closable invoice with less payment than the total amount (e.g. agreed cash discount terms)
507 global $hookmanager;
508 $hookmanager->initHooks(array('paymentdao'));
509 $parameters = array('facid' => $facid, 'invoice' => $invoice, 'remaintopay' => $remaintopay);
510 $action = 'CLOSEPAIDINVOICE';
511 $reshook = $hookmanager->executeHooks('createPayment', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
512 if ($reshook < 0) {
513 $this->errors[] = $hookmanager->error;
514 $this->error = $hookmanager->error;
515 $error++;
516 } elseif ($reshook == 0) {
517 dol_syslog("Remain to pay for invoice " . $facid . " not null. We do nothing more.");
518 }
519 // } else if ($mustwait) dol_syslog("There is ".$mustwait." differed payment to process, we do nothing more.");
520 } else {
521 // Here $remaintopay is 0.
522
523 // If invoice is a down payment, we also convert down payment to discount
524 if ($invoice->type == Facture::TYPE_DEPOSIT) {
525 $amount_ht = $amount_tva = $amount_ttc = array();
526 $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
527 '
528 @phan-var-force array<string,float> $amount_ht
529 @phan-var-force array<string,float> $amount_tva
530 @phan-var-force array<string,float> $amount_ttc
531 @phan-var-force array<string,float> $multicurrency_amount_ht
532 @phan-var-force array<string,float> $multicurrency_amount_tva
533 @phan-var-force array<string,float> $multicurrency_amount_ttc
534 ';
535
536 // Insert one discount by VAT rate category
537 $discount = new DiscountAbsolute($this->db);
538 $discount->fetch(0, $invoice->id);
539 if (empty($discount->id)) { // If the invoice was not yet converted into a discount (this may have been done manually before we come here)
540 $discount->description = '(DEPOSIT)';
541 $discount->fk_soc = $invoice->socid;
542 $discount->socid = $invoice->socid;
543 $discount->fk_facture_source = $invoice->id;
544
545 // Loop on each vat rate
546 // Bucket by tva_tx and vat_src_code so the generated discount keeps the source VAT code
547 $i = 0;
548 foreach ($invoice->lines as $line) {
549 if ($line->product_type != 9 && $line->total_ht != 0) { // no need to create discount if amount is null or is special product
550 $key = $line->tva_tx.'|'.(string) $line->vat_src_code;
551 if (!array_key_exists($key, $amount_ht)) {
552 $amount_ht[$key] = 0.0;
553 $amount_tva[$key] = 0.0;
554 $amount_ttc[$key] = 0.0;
555 $multicurrency_amount_ht[$key] = 0.0;
556 $multicurrency_amount_tva[$key] = 0.0;
557 $multicurrency_amount_ttc[$key] = 0.0;
558 }
559 $amount_ht[$key] += $line->total_ht;
560 $amount_tva[$key] += $line->total_tva;
561 $amount_ttc[$key] += $line->total_ttc;
562 $multicurrency_amount_ht[$key] += $line->multicurrency_total_ht;
563 $multicurrency_amount_tva[$key] += $line->multicurrency_total_tva;
564 $multicurrency_amount_ttc[$key] += $line->multicurrency_total_ttc;
565 $i++;
566 }
567 }
568
569 foreach ($amount_ht as $keyfordiscount => $xxx) {
570 $parts = explode('|', (string) $keyfordiscount, 2);
571 $tva_tx = $parts[0];
572 $vat_src_code = isset($parts[1]) ? $parts[1] : '';
573 $discount->amount_ht = abs($amount_ht[$keyfordiscount]);
574 $discount->total_ht = abs($amount_ht[$keyfordiscount]);
575 $discount->amount_tva = abs($amount_tva[$keyfordiscount]);
576 $discount->total_tva = abs($amount_tva[$keyfordiscount]);
577 $discount->amount_ttc = abs($amount_ttc[$keyfordiscount]);
578 $discount->total_ttc = abs($amount_ttc[$keyfordiscount]);
579 $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$keyfordiscount]);
580 $discount->multicurrency_total_ht = abs($multicurrency_amount_ht[$keyfordiscount]);
581 $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$keyfordiscount]);
582 $discount->multicurrency_total_tva = abs($multicurrency_amount_tva[$keyfordiscount]);
583 $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$keyfordiscount]);
584 $discount->multicurrency_total_ttc = abs($multicurrency_amount_ttc[$keyfordiscount]);
585 $discount->tva_tx = abs((float) $tva_tx);
586 $discount->vat_src_code = $vat_src_code;
587
588 $result = $discount->create($user);
589 if ($result < 0) {
590 $error++;
591 break;
592 }
593 }
594 }
595
596 if ($error) {
597 $this->error = $discount->error;
598 $this->errors = $discount->errors;
599 $error++;
600 }
601 }
602
603 // Set invoice to paid
604 if (!$error) {
605 $invoice->context['actionmsgmore'] = 'Invoice set to paid by the payment->create() of payment '.$this->ref.' because the remain to pay is 0';
606
607 $result = $invoice->setPaid($user, '', '');
608 if ($result < 0) {
609 $this->error = $invoice->error;
610 $this->errors = $invoice->errors;
611 $error++;
612 }
613 }
614 }
615 }
616
617 // Regenerate documents of invoices
618 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
619 dol_syslog(get_class($this).'::create Regenerate the document after inserting payment for thirdparty default_lang='.(is_object($invoice->thirdparty) ? $invoice->thirdparty->default_lang : 'null'), LOG_DEBUG);
620
621 $newlang = '';
622 $outputlangs = $langs;
623 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
624 $invoice->fetch_thirdparty();
625 $newlang = $invoice->thirdparty->default_lang;
626 }
627 if (!empty($newlang)) {
628 $outputlangs = new Translate("", $conf);
629 $outputlangs->setDefaultLang($newlang);
630 }
631
632 $hidedetails = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0;
633 $hidedesc = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0;
634 $hideref = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0;
635
636 $ret = $invoice->fetch($facid); // Reload to get new records
637
638 $result = $invoice->generateDocument($invoice->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
639
640 dol_syslog(get_class($this).'::create Regenerate end result='.$result, LOG_DEBUG);
641
642 $this->warnings = $invoice->warnings;
643
644 if ($result < 0) {
645 $this->error = $invoice->error;
646 $this->errors = $invoice->errors;
647 $error++;
648 }
649 }
650 } else {
651 $this->error = $this->db->lasterror();
652 $error++;
653 }
654 } else {
655 dol_syslog(get_class($this).'::Create Amount line '.$key.' not a number. We discard it.');
656 }
657 }
658
659 dol_syslog(get_class($this).'::create Now we call the triggers if no error (error = '.$error.')', LOG_DEBUG);
660
661 if (!$error) { // All payments into $this->amounts were recorded without errors
662 // Appel des triggers
663 $result = $this->call_trigger('PAYMENT_CUSTOMER_CREATE', $user);
664 if ($result < 0) {
665 $error++;
666 }
667 // Fin appel triggers
668 }
669 } else {
670 $this->error = $this->db->lasterror();
671 $error++;
672 }
673
674 if (!$error) {
675 // Set some properties that may be used by other process after calling the create
676 $this->amount = $total;
677 $this->total = $total; // deprecated
678 $this->multicurrency_amount = $mtotal;
679 $this->multicurrency_currency = $currencyofinvoices;
680
681 $this->db->commit();
682 return $this->id;
683 } else {
684 $this->db->rollback();
685 return -1;
686 }
687 }
688
689
699 public function delete($user, $notrigger = 0)
700 {
701 $bank_line_id = $this->bank_line;
702
703 $this->db->begin();
704
705 // Check if payment is completely paid, if payments are shared, we refuse deletion.
706 // TODO Check also if partially paid
707 $billsarray = $this->getBillsArray('f.fk_statut:>:1');
708 if (is_array($billsarray)) {
709 if (count($billsarray)) {
710 $this->error = "ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible";
711 $this->db->rollback();
712 return -1;
713 }
714 } else {
715 $this->db->rollback();
716 return -2;
717 }
718
719 // Delete bank urls. If payment is on a conciliated line, return error.
720 if ($bank_line_id > 0) {
721 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
722 $accline = new AccountLine($this->db);
723
724 $result = $accline->fetch($bank_line_id);
725 if ($result == 0) {
726 $accline->id = $accline->rowid = $bank_line_id; // If not found, we set artificially rowid to allow delete of llx_bank_url
727 }
728
729 // Delete bank account url lines linked to payment
730 $result = $accline->delete_urls($user);
731 if ($result < 0) {
732 $this->error = $accline->error;
733 $this->db->rollback();
734 return -3;
735 }
736
737 // Delete bank account lines linked to payment
738 $result = $accline->delete($user);
739 if ($result < 0) {
740 $this->error = $accline->error;
741 $this->db->rollback();
742 return -4;
743 }
744 }
745
746 if (!$notrigger) {
747 // Call triggers
748 $result = $this->call_trigger('PAYMENT_CUSTOMER_DELETE', $user);
749 if ($result < 0) {
750 $this->db->rollback();
751 return -1;
752 }
753 // End call triggers
754 }
755
756 $this->deleteExtraFields();
757 // Delete payment (into paiement_facture and paiement)
758 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement_facture';
759 $sql .= ' WHERE fk_paiement = '.((int) $this->id);
760 dol_syslog($sql);
761 $result = $this->db->query($sql);
762 if ($result) {
763 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement';
764 $sql .= " WHERE rowid = ".((int) $this->id);
765 dol_syslog($sql);
766 $result = $this->db->query($sql);
767 if (!$result) {
768 $this->error = $this->db->lasterror();
769 $this->db->rollback();
770 return -3;
771 }
772
773 $this->db->commit();
774 return 1;
775 } else {
776 $this->error = $this->db->error;
777 $this->db->rollback();
778 return -5;
779 }
780 }
781
782
798 public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0, $accountancycode = '', $addbankurl = '')
799 {
800 global $conf, $user;
801
802 $error = 0;
803 $bank_line_id = 0;
804
805 // Note: ->amount (amount in company currency) ant multicurrency_amount (amount in )was set by the ->create beforecalling this.
806 // The create had also checked that currency of payment is same than currency of bank account
807
808 if (isModEnabled("bank")) {
809 if ($accountid <= 0) {
810 $this->error = 'Bad value for parameter accountid='.$accountid;
811 dol_syslog(get_class($this).'::addPaymentToBank '.$this->error, LOG_ERR);
812 return -1;
813 }
814
815 $this->fk_account = $accountid;
816
817 dol_syslog("addPaymentToBank ".$user->id.", ".$mode.", ".$label.", ".$this->fk_account.", ".$emetteur_nom.", ".$emetteur_banque);
818
819 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
820 $acc = new Account($this->db);
821 $result = $acc->fetch($this->fk_account);
822 if ($result < 0) {
823 $this->error = $acc->error;
824 $this->errors = $acc->errors;
825 $error++;
826 return -1;
827 }
828
829 $this->db->begin();
830
831 $totalamount = $this->amount;
832 $totalamount_main_currency = null;
833 if (empty($totalamount)) {
834 $totalamount = $this->total; // For backward compatibility
835 }
836
837 // this->amount is amount of payment in company currency
838 // this->multicurrency_amount of payment in other currency
839 // this->multicurrency_currency is the currency of the payment (may be same than the company one)
840 if ($this->multicurrency_currency == $conf->currency) {
841 if ($this->amount != $this->multicurrency_amount) {
842 // Add protection, should not happen
843 $error++;
844 $this->error = 'Payment in same currency than company but this->amount != this->multicurrency_amount';
845 }
846 }
847
848 // if company currency != bank currency, then we received an amount in customer currency (currently I don't manage the case : my currency is USD, the customer currency is EUR and he paid me in GBP. Seems no sense for me)
849 if ($conf->currency != $acc->currency_code) {
850 $totalamount = $this->multicurrency_amount; // We will insert into llx_bank.amount in foreign currency of invoice
851 $totalamount_main_currency = $this->amount; // We will also save the amount in main currency into column llx_bank.amount_main_currency
852 }
853
854 if ($mode == 'payment_supplier') {
855 $totalamount = -$totalamount;
856 if (isset($totalamount_main_currency)) {
857 $totalamount_main_currency = -$totalamount_main_currency;
858 }
859 }
860
861 // Insert payment into llx_bank
862 $bank_line_id = $acc->addline(
863 $this->datepaye,
864 $this->paiementcode ? $this->paiementcode : $this->paiementid, // Payment mode code ('CB', 'CHQ' or 'VIR' for example). Use payment id if not defined for backward compatibility.
865 $label,
866 $totalamount, // Sign must be positive when we receive money (customer payment), negative when you give money (supplier invoice or credit note)
867 $this->num_payment,
868 0,
869 $user,
870 $emetteur_nom,
871 $emetteur_banque,
872 $accountancycode,
873 0,
874 '',
875 (float) $totalamount_main_currency
876 );
877
878 // Mise a jour fk_bank dans llx_paiement
879 // On connait ainsi le paiement qui a genere l'ecriture bancaire
880 if ($bank_line_id > 0) {
881 $result = $this->update_fk_bank($bank_line_id);
882 if ($result <= 0) {
883 $error++;
884 dol_print_error($this->db);
885 }
886
887 // Add link 'payment', 'payment_supplier' in bank_url between payment and bank transaction
888 if (!$error) {
889 $url = '';
890 if ($mode == 'payment') {
891 $url = DOL_URL_ROOT.'/compta/paiement/card.php?id=';
892 }
893 if ($mode == 'payment_supplier') {
894 $url = DOL_URL_ROOT.'/fourn/paiement/card.php?id=';
895 }
896 if ($url) {
897 $result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode);
898 if ($result <= 0) {
899 $error++;
900 dol_print_error($this->db);
901 }
902 }
903 }
904
905 // Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment)
906 if (!$error) {
907 $linkaddedforthirdparty = array();
908 foreach ($this->amounts as $key => $value) { // We should have invoices always for same third party but we loop in case of.
909 // Skip the invoices that were listed but not paid, the same way create() does. Without this,
910 // a 'company' link is added to the bank line for a third party that received no payment.
911 if (!is_numeric($value) || $value == 0) {
912 continue;
913 }
914 if ($mode == 'payment') {
915 $fac = new Facture($this->db);
916 $fac->fetch($key);
917 $fac->fetch_thirdparty();
918 if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty @phan-suppress-current-line PhanPossiblyUndeclaredVariable
919 $result = $acc->add_url_line(
920 $bank_line_id,
921 $fac->thirdparty->id,
922 DOL_URL_ROOT.'/comm/card.php?socid=',
923 (string) $fac->thirdparty->name,
924 'company'
925 );
926 if ($result <= 0) {
927 $error++;
928 dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
929 }
930 $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
931 }
932 }
933 if ($mode == 'payment_supplier') {
934 $fac = new FactureFournisseur($this->db);
935 $fac->fetch($key);
936 $fac->fetch_thirdparty();
937 if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty
938 $result = $acc->add_url_line(
939 $bank_line_id,
940 $fac->thirdparty->id,
941 DOL_URL_ROOT.'/fourn/card.php?socid=',
942 (string) $fac->thirdparty->name,
943 'company'
944 );
945 if ($result <= 0) {
946 $error++;
947 dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
948 }
949 $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
950 }
951 }
952 }
953 }
954
955 // Add a link to the Direct Debit ('direct-debit') or Credit transfer ('credit-transfer') file in bank_url
956 if (!$error && $addbankurl && in_array($addbankurl, array('direct-debit', 'credit-transfer'))) {
957 $result = $acc->add_url_line(
958 $bank_line_id,
959 $this->id_prelevement,
960 DOL_URL_ROOT.'/compta/prelevement/card.php?id=',
961 $this->num_payment,
962 $addbankurl
963 );
964 }
965
966 // Add link to the Direct Debit if invoice refused ('InvoiceRefused') in bank_url
967 if (!$error && $label == '(InvoiceRefused)') {
968 $result = $acc->add_url_line(
969 $bank_line_id,
970 $this->id_prelevement,
971 DOL_URL_ROOT.'/compta/prelevement/card.php?id=',
972 $this->num_prelevement,
973 'withdraw'
974 );
975 }
976
977 if (!$error && !$notrigger) {
978 // Appel des triggers
979 $result = $this->call_trigger('PAYMENT_ADD_TO_BANK', $user);
980 if ($result < 0) {
981 $error++;
982 }
983 // Fin appel triggers
984 }
985 } else {
986 $this->error = $acc->error;
987 $this->errors = $acc->errors;
988 $error++;
989 }
990
991 if (!$error) {
992 $this->db->commit();
993 } else {
994 $this->db->rollback();
995 }
996 }
997
998 if (!$error) {
999 return $bank_line_id;
1000 } else {
1001 return -1;
1002 }
1003 }
1004
1005
1006 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1013 public function update_fk_bank($id_bank)
1014 {
1015 // phpcs:enable
1016 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' set fk_bank = '.((int) $id_bank);
1017 $sql .= " WHERE rowid = ".((int) $this->id);
1018
1019 dol_syslog(get_class($this).'::update_fk_bank', LOG_DEBUG);
1020 $result = $this->db->query($sql);
1021 if ($result) {
1022 return 1;
1023 } else {
1024 $this->error = $this->db->lasterror();
1025 dol_syslog(get_class($this).'::update_fk_bank '.$this->error);
1026 return -1;
1027 }
1028 }
1029
1030 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1037 public function update_date($date)
1038 {
1039 // phpcs:enable
1040 $error = 0;
1041
1042 if (!empty($date) && $this->statut != 1) {
1043 $this->db->begin();
1044
1045 dol_syslog(get_class($this)."::update_date with date = ".$date, LOG_DEBUG);
1046
1047 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1048 $sql .= " SET datep = '".$this->db->idate($date)."'";
1049 $sql .= " WHERE rowid = ".((int) $this->id);
1050
1051 $result = $this->db->query($sql);
1052 if (!$result) {
1053 $error++;
1054 $this->error = 'Error -1 '.$this->db->error();
1055 }
1056
1057 $type = $this->element;
1058
1059 $sql = "UPDATE ".MAIN_DB_PREFIX.'bank';
1060 $sql .= " SET dateo = '".$this->db->idate($date)."', datev = '".$this->db->idate($date)."'";
1061 $sql .= " WHERE rowid IN (SELECT fk_bank FROM ".MAIN_DB_PREFIX."bank_url WHERE type = '".$this->db->escape($type)."' AND url_id = ".((int) $this->id).")";
1062 $sql .= " AND rappro = 0";
1063
1064 $result = $this->db->query($sql);
1065 if (!$result) {
1066 $error++;
1067 $this->error = 'Error -1 '.$this->db->error();
1068 }
1069
1070 if (!$error) {
1071 $this->datepaye = $date;
1072 $this->date = $date;
1073
1074 $this->db->commit();
1075 return 0;
1076 } else {
1077 $this->db->rollback();
1078 return -2;
1079 }
1080 }
1081 return -1; //no date given or already validated
1082 }
1083
1084 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1091 public function update_num($num_payment)
1092 {
1093 // phpcs:enable
1094 if (!empty($num_payment) && $this->statut != 1) {
1095 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1096 $sql .= " SET num_paiement = '".$this->db->escape($num_payment)."'";
1097 $sql .= " WHERE rowid = ".((int) $this->id);
1098
1099 dol_syslog(get_class($this)."::update_num", LOG_DEBUG);
1100 $result = $this->db->query($sql);
1101 if ($result) {
1102 $this->num_payment = $this->db->escape($num_payment);
1103 return 0;
1104 } else {
1105 $this->error = 'Error -1 '.$this->db->error();
1106 return -2;
1107 }
1108 }
1109 return -1; //no num given or already validated
1110 }
1111
1119 public function valide($user = null)
1120 {
1121 return $this->validate($user);
1122 }
1123
1130 public function validate($user = null)
1131 {
1132 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET statut = 1 WHERE rowid = '.((int) $this->id);
1133
1134 dol_syslog(get_class($this).'::valide', LOG_DEBUG);
1135 $result = $this->db->query($sql);
1136 if ($result) {
1137 return 1;
1138 } else {
1139 $this->error = $this->db->lasterror();
1140 dol_syslog(get_class($this).'::valide '.$this->error);
1141 return -1;
1142 }
1143 }
1144
1151 public function reject($user = null)
1152 {
1153 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET statut = 2 WHERE rowid = '.((int) $this->id);
1154
1155 dol_syslog(get_class($this).'::reject', LOG_DEBUG);
1156 $result = $this->db->query($sql);
1157 if ($result) {
1158 return 1;
1159 } else {
1160 $this->error = $this->db->lasterror();
1161 dol_syslog(get_class($this).'::reject '.$this->error);
1162 return -1;
1163 }
1164 }
1165
1172 public function info($id)
1173 {
1174 $sql = 'SELECT p.rowid, p.datec, p.fk_user_creat, p.fk_user_modif, p.tms';
1175 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p';
1176 $sql .= ' WHERE p.rowid = '.((int) $id);
1177
1178 dol_syslog(get_class($this).'::info', LOG_DEBUG);
1179 $result = $this->db->query($sql);
1180
1181 if ($result) {
1182 if ($this->db->num_rows($result)) {
1183 $obj = $this->db->fetch_object($result);
1184
1185 $this->id = $obj->rowid;
1186
1187 $this->user_creation_id = $obj->fk_user_creat;
1188 $this->user_modification_id = $obj->fk_user_modif;
1189 $this->date_creation = $this->db->jdate($obj->datec);
1190 $this->date_modification = $this->db->jdate($obj->tms);
1191 }
1192 $this->db->free($result);
1193 } else {
1194 dol_print_error($this->db);
1195 }
1196 }
1197
1205 public function getBillsArray($filter = '')
1206 {
1207 $sql = 'SELECT pf.fk_facture';
1208 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'facture as f'; // We keep link on invoice to allow use of some filters on invoice
1209 $sql .= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.((int) $this->id);
1210 if ($filter) {
1211 $sql .= forgeSQLFromUniversalSearchCriteria($filter);
1212 }
1213 $resql = $this->db->query($sql);
1214 if ($resql) {
1215 $i = 0;
1216 $num = $this->db->num_rows($resql);
1217 $billsarray = array();
1218
1219 while ($i < $num) {
1220 $obj = $this->db->fetch_object($resql);
1221 $billsarray[$i] = $obj->fk_facture;
1222 $i++;
1223 }
1224
1225 return $billsarray;
1226 } else {
1227 $this->error = $this->db->error();
1228 dol_syslog(get_class($this).'::getBillsArray Error '.$this->error.' -', LOG_DEBUG);
1229 return -1;
1230 }
1231 }
1232
1239 public function getAmountsArray()
1240 {
1241 $sql = 'SELECT pf.fk_facture, pf.amount';
1242 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
1243 $sql .= ' WHERE pf.fk_paiement = '.((int) $this->id);
1244 $resql = $this->db->query($sql);
1245 if ($resql) {
1246 $i = 0;
1247 $num = $this->db->num_rows($resql);
1248 $amounts = array();
1249
1250 while ($i < $num) {
1251 $obj = $this->db->fetch_object($resql);
1252 $amounts[$obj->fk_facture] = $obj->amount;
1253 $i++;
1254 }
1255
1256 return $amounts;
1257 } else {
1258 $this->error = $this->db->error();
1259 dol_syslog(get_class($this).'::getAmountsArray Error '.$this->error.' -', LOG_DEBUG);
1260 return -1;
1261 }
1262 }
1263
1272 public function getNextNumRef($soc, $mode = 'next')
1273 {
1274 global $conf, $db, $langs;
1275 $langs->load("bills");
1276
1277 // Clean parameters (if not defined or using deprecated value)
1278 if (!getDolGlobalString('PAYMENT_ADDON')) {
1279 $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
1280 } elseif (getDolGlobalString('PAYMENT_ADDON') == 'ant') {
1281 $conf->global->PAYMENT_ADDON = 'mod_payment_ant';
1282 } elseif (getDolGlobalString('PAYMENT_ADDON') == 'cicada') {
1283 $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
1284 }
1285
1286 if (getDolGlobalString('PAYMENT_ADDON')) {
1287 $mybool = false;
1288
1289 $file = getDolGlobalString('PAYMENT_ADDON') . ".php";
1290 $classname = getDolGlobalString('PAYMENT_ADDON');
1291
1292 // Include file with class
1293 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1294
1295 foreach ($dirmodels as $reldir) {
1296 $dir = dol_buildpath($reldir."core/modules/payment/");
1297
1298 // Load file with numbering class (if found)
1299 if (is_file($dir.$file) && is_readable($dir.$file)) {
1300 $mybool = (include_once $dir.$file) || $mybool;
1301 }
1302 }
1303
1304 // For compatibility
1305 if (!$mybool) {
1306 $file = getDolGlobalString('PAYMENT_ADDON') . ".php";
1307 $classname = "mod_payment_" . getDolGlobalString('PAYMENT_ADDON');
1308 $classname = preg_replace('/\-.*$/', '', $classname);
1309 // Include file with class
1310 foreach ($conf->file->dol_document_root as $dirroot) {
1311 $dir = $dirroot."/core/modules/payment/";
1312
1313 // Load file with numbering class (if found)
1314 if (is_file($dir.$file) && is_readable($dir.$file)) {
1315 $mybool = (include_once $dir.$file) || $mybool;
1316 }
1317 }
1318 }
1319
1320 if (!$mybool) {
1321 dol_print_error(null, "Failed to include file ".$file);
1322 return '';
1323 }
1324
1325 $obj = new $classname();
1326 '@phan-var-force ModeleNumRefPayments $obj';
1327
1328 $numref = $obj->getNextValue($soc, $this);
1329
1334 if ($mode != 'last' && !$numref) {
1335 dol_print_error($db, "Payment::getNextNumRef ".$obj->error);
1336 return "";
1337 }
1338
1339 return $numref;
1340 } else {
1341 $langs->load("errors");
1342 print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Invoice"));
1343 return "";
1344 }
1345 }
1346
1352 public function getWay()
1353 {
1354 $way = 'dolibarr';
1355 if (isModEnabled('multicurrency')) {
1356 foreach ($this->multicurrency_amounts as $value) {
1357 if (!empty($value)) { // one value found into multicurrency_amounts so payment is in invoice currency
1358 $way = 'customer';
1359 break;
1360 }
1361 }
1362 }
1363
1364 return $way;
1365 }
1366
1375 public function initAsSpecimen($option = '')
1376 {
1377 global $user, $langs, $conf;
1378
1379 $now = dol_now();
1380 $arraynow = dol_getdate($now);
1381 $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1382
1383 // Initialize parameters
1384 $this->id = 0;
1385 $this->ref = 'SPECIMEN';
1386 $this->specimen = 1;
1387 $this->facid = 1;
1388 $this->datepaye = $nownotime;
1389
1390 return 1;
1391 }
1392
1393
1404 public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0, $morecss = '')
1405 {
1406 global $conf, $langs, $hookmanager;
1407
1408 if (!empty($conf->dol_no_mouse_hover)) {
1409 $notooltip = 1; // Force disable tooltips
1410 }
1411
1412 $result = '';
1413
1414 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Payment").'</u><br>';
1415 $label .= '<strong>'.$langs->trans("Ref").':</strong> '.$this->ref;
1416 $dateofpayment = ($this->datepaye ? $this->datepaye : $this->date);
1417 if ($dateofpayment) {
1418 $label .= '<br><strong>'.$langs->trans("Date").':</strong> ';
1419 $tmparray = dol_getdate($dateofpayment);
1420 if ($tmparray['seconds'] == 0 && $tmparray['minutes'] == 0 && ($tmparray['hours'] == 0 || $tmparray['hours'] == 12)) { // We set hours to 0:00 or 12:00 because we don't know it
1421 $label .= dol_print_date($dateofpayment, 'day');
1422 } else { // Hours was set to real date of payment (special case for POS for example)
1423 $label .= dol_print_date($dateofpayment, 'dayhour', 'tzuser');
1424 }
1425 }
1426 if ($this->amount) {
1427 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
1428 }
1429 if ($mode == 'withlistofinvoices') {
1430 $arraybill = $this->getBillsArray();
1431 if (is_array($arraybill) && count($arraybill) > 0) {
1432 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1433 $facturestatic = new Facture($this->db);
1434 foreach ($arraybill as $billid) {
1435 $facturestatic->fetch($billid);
1436 $label .= '<br> '.$facturestatic->getNomUrl(1, '', 0, 0, '', 1).' '.$facturestatic->getLibStatut(2, -1);
1437 }
1438 }
1439 }
1440
1441 $linkclose = '';
1442 if (empty($notooltip)) {
1443 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1444 $label = $langs->trans("Payment");
1445 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1446 }
1447 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
1448 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1449 } else {
1450 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1451 }
1452
1453 $url = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$this->id;
1454
1455 $linkstart = '<a href="'.$url.'"';
1456 $linkstart .= $linkclose.'>';
1457 $linkend = '</a>';
1458
1459 $result .= $linkstart;
1460 if ($withpicto) {
1461 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1462 }
1463 if ($withpicto && $withpicto != 2) {
1464 $result .= ($this->ref ? $this->ref : $this->id);
1465 }
1466 $result .= $linkend;
1467 global $action;
1468 $hookmanager->initHooks(array($this->element . 'dao'));
1469 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1470 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1471 if ($reshook > 0) {
1472 $result = $hookmanager->resPrint;
1473 } else {
1474 $result .= $hookmanager->resPrint;
1475 }
1476 return $result;
1477 }
1478
1485 public function getLibStatut($mode = 0)
1486 {
1487 return $this->LibStatut($this->statut, $mode);
1488 }
1489
1490 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1498 public function LibStatut($status, $mode = 0)
1499 {
1500 // phpcs:enable
1501 global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage
1502
1503 $langs->load('compta');
1504 /*if ($mode == 0)
1505 {
1506 if ($status == 0) return $langs->trans('ToValidate');
1507 if ($status == 1) return $langs->trans('Validated');
1508 }
1509 if ($mode == 1)
1510 {
1511 if ($status == 0) return $langs->trans('ToValidate');
1512 if ($status == 1) return $langs->trans('Validated');
1513 }
1514 if ($mode == 2)
1515 {
1516 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
1517 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
1518 }
1519 if ($mode == 3)
1520 {
1521 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1');
1522 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4');
1523 }
1524 if ($mode == 4)
1525 {
1526 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
1527 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
1528 }
1529 if ($mode == 5)
1530 {
1531 if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1');
1532 if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
1533 }
1534 if ($mode == 6)
1535 {
1536 if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1');
1537 if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
1538 }*/
1539 return '';
1540 }
1541
1542 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1550 public function fetch_thirdparty($force_thirdparty_id = 0)
1551 {
1552 // phpcs:enable
1553 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1554
1555 if (empty($force_thirdparty_id)) {
1556 $billsarray = $this->getBillsArray(); // From payment, the fk_soc isn't available, we should load the first supplier invoice to get him
1557 if (!empty($billsarray)) {
1558 $invoice = new Facture($this->db);
1559 if ($invoice->fetch($billsarray[0]) > 0) {
1560 $force_thirdparty_id = $invoice->socid;
1561 }
1562 }
1563 }
1564
1565 return parent::fetch_thirdparty($force_thirdparty_id);
1566 }
1567
1568
1574 public function isReconciled()
1575 {
1576 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1577 $accountline = new AccountLine($this->db);
1578 $accountline->fetch($this->bank_line);
1579 return $accountline->rappro ? true : false;
1580 }
1581}
$object ref
Definition info.php:90
Class to manage bank accounts.
Class to manage bank transaction lines.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteExtraFields()
Delete all extra fields values for the current object.
Class to manage absolute discounts.
Class to manage suppliers invoices.
Class to manage invoices.
const TYPE_REPLACEMENT
Replacement invoice.
const TYPE_STANDARD
Standard invoice.
const TYPE_SITUATION
Situation invoice.
const TYPE_DEPOSIT
Deposit invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
static getInvoiceRate($fk_facture, $table='facture')
Get current invoite rate.
Class to manage payments of customer invoices.
addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger=0, $accountancycode='', $addbankurl='')
Add a record into bank for payment + links between this bank record and sources of payment.
__construct($db)
Constructor.
update_num($num_payment)
Updates the payment number.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id into this->thirdparty.
create($user, $closepaidinvoices=0, $thirdparty=null)
Create payment of invoices into database.
getAmountsArray()
Return list of amounts of payments.
getNomUrl($withpicto=0, $option='', $mode='withlistofinvoices', $notooltip=0, $morecss='')
Return clickable name (with picto eventually)
isReconciled()
Return if payment is reconciled.
fetch($id, $ref='', $fk_bank=0)
Load payment from database.
update_fk_bank($id_bank)
Update the link between the Payment and the line generated in llx_bank.
getWay()
get the right way of payment
validate($user=null)
Validate payment.
reject($user=null)
Reject payment.
initAsSpecimen($option='')
Initialise an instance with random values.
LibStatut($status, $mode=0)
Return the label of a given status.
update_date($date)
Updates the payment date.
getNextNumRef($soc, $mode='next')
Return next reference of customer invoice not already used (or last reference) according to numbering...
getBillsArray($filter='')
Return list of invoices the payment is related to.
valide($user=null)
Validate payment.
info($id)
Information sur l'objet.
getLibStatut($mode=0)
Return the label of the status.
Class to manage translations.
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.
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...
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)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0, $forbiddenfields=array())
forgeSQLFromUniversalSearchCriteria
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
print $langs trans('Date')." left Ref Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:494
print $langs trans('Date')." left Ref Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as date
Definition receipt.php:492