dolibarr 24.0.0-beta
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 if ($mode == 'payment') {
910 $fac = new Facture($this->db);
911 $fac->fetch($key);
912 $fac->fetch_thirdparty();
913 if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty @phan-suppress-current-line PhanPossiblyUndeclaredVariable
914 $result = $acc->add_url_line(
915 $bank_line_id,
916 $fac->thirdparty->id,
917 DOL_URL_ROOT.'/comm/card.php?socid=',
918 (string) $fac->thirdparty->name,
919 'company'
920 );
921 if ($result <= 0) {
922 $error++;
923 dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
924 }
925 $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
926 }
927 }
928 if ($mode == 'payment_supplier') {
929 $fac = new FactureFournisseur($this->db);
930 $fac->fetch($key);
931 $fac->fetch_thirdparty();
932 if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty
933 $result = $acc->add_url_line(
934 $bank_line_id,
935 $fac->thirdparty->id,
936 DOL_URL_ROOT.'/fourn/card.php?socid=',
937 (string) $fac->thirdparty->name,
938 'company'
939 );
940 if ($result <= 0) {
941 $error++;
942 dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
943 }
944 $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
945 }
946 }
947 }
948 }
949
950 // Add a link to the Direct Debit ('direct-debit') or Credit transfer ('credit-transfer') file in bank_url
951 if (!$error && $addbankurl && in_array($addbankurl, array('direct-debit', 'credit-transfer'))) {
952 $result = $acc->add_url_line(
953 $bank_line_id,
954 $this->id_prelevement,
955 DOL_URL_ROOT.'/compta/prelevement/card.php?id=',
956 $this->num_payment,
957 $addbankurl
958 );
959 }
960
961 // Add link to the Direct Debit if invoice refused ('InvoiceRefused') in bank_url
962 if (!$error && $label == '(InvoiceRefused)') {
963 $result = $acc->add_url_line(
964 $bank_line_id,
965 $this->id_prelevement,
966 DOL_URL_ROOT.'/compta/prelevement/card.php?id=',
967 $this->num_prelevement,
968 'withdraw'
969 );
970 }
971
972 if (!$error && !$notrigger) {
973 // Appel des triggers
974 $result = $this->call_trigger('PAYMENT_ADD_TO_BANK', $user);
975 if ($result < 0) {
976 $error++;
977 }
978 // Fin appel triggers
979 }
980 } else {
981 $this->error = $acc->error;
982 $this->errors = $acc->errors;
983 $error++;
984 }
985
986 if (!$error) {
987 $this->db->commit();
988 } else {
989 $this->db->rollback();
990 }
991 }
992
993 if (!$error) {
994 return $bank_line_id;
995 } else {
996 return -1;
997 }
998 }
999
1000
1001 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1008 public function update_fk_bank($id_bank)
1009 {
1010 // phpcs:enable
1011 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' set fk_bank = '.((int) $id_bank);
1012 $sql .= " WHERE rowid = ".((int) $this->id);
1013
1014 dol_syslog(get_class($this).'::update_fk_bank', LOG_DEBUG);
1015 $result = $this->db->query($sql);
1016 if ($result) {
1017 return 1;
1018 } else {
1019 $this->error = $this->db->lasterror();
1020 dol_syslog(get_class($this).'::update_fk_bank '.$this->error);
1021 return -1;
1022 }
1023 }
1024
1025 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1032 public function update_date($date)
1033 {
1034 // phpcs:enable
1035 $error = 0;
1036
1037 if (!empty($date) && $this->statut != 1) {
1038 $this->db->begin();
1039
1040 dol_syslog(get_class($this)."::update_date with date = ".$date, LOG_DEBUG);
1041
1042 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1043 $sql .= " SET datep = '".$this->db->idate($date)."'";
1044 $sql .= " WHERE rowid = ".((int) $this->id);
1045
1046 $result = $this->db->query($sql);
1047 if (!$result) {
1048 $error++;
1049 $this->error = 'Error -1 '.$this->db->error();
1050 }
1051
1052 $type = $this->element;
1053
1054 $sql = "UPDATE ".MAIN_DB_PREFIX.'bank';
1055 $sql .= " SET dateo = '".$this->db->idate($date)."', datev = '".$this->db->idate($date)."'";
1056 $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).")";
1057 $sql .= " AND rappro = 0";
1058
1059 $result = $this->db->query($sql);
1060 if (!$result) {
1061 $error++;
1062 $this->error = 'Error -1 '.$this->db->error();
1063 }
1064
1065 if (!$error) {
1066 $this->datepaye = $date;
1067 $this->date = $date;
1068
1069 $this->db->commit();
1070 return 0;
1071 } else {
1072 $this->db->rollback();
1073 return -2;
1074 }
1075 }
1076 return -1; //no date given or already validated
1077 }
1078
1079 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1086 public function update_num($num_payment)
1087 {
1088 // phpcs:enable
1089 if (!empty($num_payment) && $this->statut != 1) {
1090 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1091 $sql .= " SET num_paiement = '".$this->db->escape($num_payment)."'";
1092 $sql .= " WHERE rowid = ".((int) $this->id);
1093
1094 dol_syslog(get_class($this)."::update_num", LOG_DEBUG);
1095 $result = $this->db->query($sql);
1096 if ($result) {
1097 $this->num_payment = $this->db->escape($num_payment);
1098 return 0;
1099 } else {
1100 $this->error = 'Error -1 '.$this->db->error();
1101 return -2;
1102 }
1103 }
1104 return -1; //no num given or already validated
1105 }
1106
1114 public function valide($user = null)
1115 {
1116 return $this->validate($user);
1117 }
1118
1125 public function validate($user = null)
1126 {
1127 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET statut = 1 WHERE rowid = '.((int) $this->id);
1128
1129 dol_syslog(get_class($this).'::valide', LOG_DEBUG);
1130 $result = $this->db->query($sql);
1131 if ($result) {
1132 return 1;
1133 } else {
1134 $this->error = $this->db->lasterror();
1135 dol_syslog(get_class($this).'::valide '.$this->error);
1136 return -1;
1137 }
1138 }
1139
1146 public function reject($user = null)
1147 {
1148 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET statut = 2 WHERE rowid = '.((int) $this->id);
1149
1150 dol_syslog(get_class($this).'::reject', LOG_DEBUG);
1151 $result = $this->db->query($sql);
1152 if ($result) {
1153 return 1;
1154 } else {
1155 $this->error = $this->db->lasterror();
1156 dol_syslog(get_class($this).'::reject '.$this->error);
1157 return -1;
1158 }
1159 }
1160
1167 public function info($id)
1168 {
1169 $sql = 'SELECT p.rowid, p.datec, p.fk_user_creat, p.fk_user_modif, p.tms';
1170 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p';
1171 $sql .= ' WHERE p.rowid = '.((int) $id);
1172
1173 dol_syslog(get_class($this).'::info', LOG_DEBUG);
1174 $result = $this->db->query($sql);
1175
1176 if ($result) {
1177 if ($this->db->num_rows($result)) {
1178 $obj = $this->db->fetch_object($result);
1179
1180 $this->id = $obj->rowid;
1181
1182 $this->user_creation_id = $obj->fk_user_creat;
1183 $this->user_modification_id = $obj->fk_user_modif;
1184 $this->date_creation = $this->db->jdate($obj->datec);
1185 $this->date_modification = $this->db->jdate($obj->tms);
1186 }
1187 $this->db->free($result);
1188 } else {
1189 dol_print_error($this->db);
1190 }
1191 }
1192
1200 public function getBillsArray($filter = '')
1201 {
1202 $sql = 'SELECT pf.fk_facture';
1203 $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
1204 $sql .= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.((int) $this->id);
1205 if ($filter) {
1206 $sql .= forgeSQLFromUniversalSearchCriteria($filter);
1207 }
1208 $resql = $this->db->query($sql);
1209 if ($resql) {
1210 $i = 0;
1211 $num = $this->db->num_rows($resql);
1212 $billsarray = array();
1213
1214 while ($i < $num) {
1215 $obj = $this->db->fetch_object($resql);
1216 $billsarray[$i] = $obj->fk_facture;
1217 $i++;
1218 }
1219
1220 return $billsarray;
1221 } else {
1222 $this->error = $this->db->error();
1223 dol_syslog(get_class($this).'::getBillsArray Error '.$this->error.' -', LOG_DEBUG);
1224 return -1;
1225 }
1226 }
1227
1234 public function getAmountsArray()
1235 {
1236 $sql = 'SELECT pf.fk_facture, pf.amount';
1237 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
1238 $sql .= ' WHERE pf.fk_paiement = '.((int) $this->id);
1239 $resql = $this->db->query($sql);
1240 if ($resql) {
1241 $i = 0;
1242 $num = $this->db->num_rows($resql);
1243 $amounts = array();
1244
1245 while ($i < $num) {
1246 $obj = $this->db->fetch_object($resql);
1247 $amounts[$obj->fk_facture] = $obj->amount;
1248 $i++;
1249 }
1250
1251 return $amounts;
1252 } else {
1253 $this->error = $this->db->error();
1254 dol_syslog(get_class($this).'::getAmountsArray Error '.$this->error.' -', LOG_DEBUG);
1255 return -1;
1256 }
1257 }
1258
1267 public function getNextNumRef($soc, $mode = 'next')
1268 {
1269 global $conf, $db, $langs;
1270 $langs->load("bills");
1271
1272 // Clean parameters (if not defined or using deprecated value)
1273 if (!getDolGlobalString('PAYMENT_ADDON')) {
1274 $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
1275 } elseif (getDolGlobalString('PAYMENT_ADDON') == 'ant') {
1276 $conf->global->PAYMENT_ADDON = 'mod_payment_ant';
1277 } elseif (getDolGlobalString('PAYMENT_ADDON') == 'cicada') {
1278 $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
1279 }
1280
1281 if (getDolGlobalString('PAYMENT_ADDON')) {
1282 $mybool = false;
1283
1284 $file = getDolGlobalString('PAYMENT_ADDON') . ".php";
1285 $classname = getDolGlobalString('PAYMENT_ADDON');
1286
1287 // Include file with class
1288 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1289
1290 foreach ($dirmodels as $reldir) {
1291 $dir = dol_buildpath($reldir."core/modules/payment/");
1292
1293 // Load file with numbering class (if found)
1294 if (is_file($dir.$file) && is_readable($dir.$file)) {
1295 $mybool = (include_once $dir.$file) || $mybool;
1296 }
1297 }
1298
1299 // For compatibility
1300 if (!$mybool) {
1301 $file = getDolGlobalString('PAYMENT_ADDON') . ".php";
1302 $classname = "mod_payment_" . getDolGlobalString('PAYMENT_ADDON');
1303 $classname = preg_replace('/\-.*$/', '', $classname);
1304 // Include file with class
1305 foreach ($conf->file->dol_document_root as $dirroot) {
1306 $dir = $dirroot."/core/modules/payment/";
1307
1308 // Load file with numbering class (if found)
1309 if (is_file($dir.$file) && is_readable($dir.$file)) {
1310 $mybool = (include_once $dir.$file) || $mybool;
1311 }
1312 }
1313 }
1314
1315 if (!$mybool) {
1316 dol_print_error(null, "Failed to include file ".$file);
1317 return '';
1318 }
1319
1320 $obj = new $classname();
1321 '@phan-var-force ModeleNumRefPayments $obj';
1322
1323 $numref = $obj->getNextValue($soc, $this);
1324
1329 if ($mode != 'last' && !$numref) {
1330 dol_print_error($db, "Payment::getNextNumRef ".$obj->error);
1331 return "";
1332 }
1333
1334 return $numref;
1335 } else {
1336 $langs->load("errors");
1337 print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Invoice"));
1338 return "";
1339 }
1340 }
1341
1347 public function getWay()
1348 {
1349 $way = 'dolibarr';
1350 if (isModEnabled('multicurrency')) {
1351 foreach ($this->multicurrency_amounts as $value) {
1352 if (!empty($value)) { // one value found into multicurrency_amounts so payment is in invoice currency
1353 $way = 'customer';
1354 break;
1355 }
1356 }
1357 }
1358
1359 return $way;
1360 }
1361
1370 public function initAsSpecimen($option = '')
1371 {
1372 global $user, $langs, $conf;
1373
1374 $now = dol_now();
1375 $arraynow = dol_getdate($now);
1376 $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1377
1378 // Initialize parameters
1379 $this->id = 0;
1380 $this->ref = 'SPECIMEN';
1381 $this->specimen = 1;
1382 $this->facid = 1;
1383 $this->datepaye = $nownotime;
1384
1385 return 1;
1386 }
1387
1388
1399 public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0, $morecss = '')
1400 {
1401 global $conf, $langs, $hookmanager;
1402
1403 if (!empty($conf->dol_no_mouse_hover)) {
1404 $notooltip = 1; // Force disable tooltips
1405 }
1406
1407 $result = '';
1408
1409 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Payment").'</u><br>';
1410 $label .= '<strong>'.$langs->trans("Ref").':</strong> '.$this->ref;
1411 $dateofpayment = ($this->datepaye ? $this->datepaye : $this->date);
1412 if ($dateofpayment) {
1413 $label .= '<br><strong>'.$langs->trans("Date").':</strong> ';
1414 $tmparray = dol_getdate($dateofpayment);
1415 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
1416 $label .= dol_print_date($dateofpayment, 'day');
1417 } else { // Hours was set to real date of payment (special case for POS for example)
1418 $label .= dol_print_date($dateofpayment, 'dayhour', 'tzuser');
1419 }
1420 }
1421 if ($this->amount) {
1422 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
1423 }
1424 if ($mode == 'withlistofinvoices') {
1425 $arraybill = $this->getBillsArray();
1426 if (is_array($arraybill) && count($arraybill) > 0) {
1427 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1428 $facturestatic = new Facture($this->db);
1429 foreach ($arraybill as $billid) {
1430 $facturestatic->fetch($billid);
1431 $label .= '<br> '.$facturestatic->getNomUrl(1, '', 0, 0, '', 1).' '.$facturestatic->getLibStatut(2, -1);
1432 }
1433 }
1434 }
1435
1436 $linkclose = '';
1437 if (empty($notooltip)) {
1438 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1439 $label = $langs->trans("Payment");
1440 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1441 }
1442 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
1443 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1444 } else {
1445 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1446 }
1447
1448 $url = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$this->id;
1449
1450 $linkstart = '<a href="'.$url.'"';
1451 $linkstart .= $linkclose.'>';
1452 $linkend = '</a>';
1453
1454 $result .= $linkstart;
1455 if ($withpicto) {
1456 $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);
1457 }
1458 if ($withpicto && $withpicto != 2) {
1459 $result .= ($this->ref ? $this->ref : $this->id);
1460 }
1461 $result .= $linkend;
1462 global $action;
1463 $hookmanager->initHooks(array($this->element . 'dao'));
1464 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1465 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1466 if ($reshook > 0) {
1467 $result = $hookmanager->resPrint;
1468 } else {
1469 $result .= $hookmanager->resPrint;
1470 }
1471 return $result;
1472 }
1473
1480 public function getLibStatut($mode = 0)
1481 {
1482 return $this->LibStatut($this->statut, $mode);
1483 }
1484
1485 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1493 public function LibStatut($status, $mode = 0)
1494 {
1495 // phpcs:enable
1496 global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage
1497
1498 $langs->load('compta');
1499 /*if ($mode == 0)
1500 {
1501 if ($status == 0) return $langs->trans('ToValidate');
1502 if ($status == 1) return $langs->trans('Validated');
1503 }
1504 if ($mode == 1)
1505 {
1506 if ($status == 0) return $langs->trans('ToValidate');
1507 if ($status == 1) return $langs->trans('Validated');
1508 }
1509 if ($mode == 2)
1510 {
1511 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
1512 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
1513 }
1514 if ($mode == 3)
1515 {
1516 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1');
1517 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4');
1518 }
1519 if ($mode == 4)
1520 {
1521 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
1522 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
1523 }
1524 if ($mode == 5)
1525 {
1526 if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1');
1527 if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
1528 }
1529 if ($mode == 6)
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 return '';
1535 }
1536
1537 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1545 public function fetch_thirdparty($force_thirdparty_id = 0)
1546 {
1547 // phpcs:enable
1548 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1549
1550 if (empty($force_thirdparty_id)) {
1551 $billsarray = $this->getBillsArray(); // From payment, the fk_soc isn't available, we should load the first supplier invoice to get him
1552 if (!empty($billsarray)) {
1553 $invoice = new Facture($this->db);
1554 if ($invoice->fetch($billsarray[0]) > 0) {
1555 $force_thirdparty_id = $invoice->socid;
1556 }
1557 }
1558 }
1559
1560 return parent::fetch_thirdparty($force_thirdparty_id);
1561 }
1562
1563
1569 public function isReconciled()
1570 {
1571 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1572 $accountline = new AccountLine($this->db);
1573 $accountline->fetch($this->bank_line);
1574 return $accountline->rappro ? true : false;
1575 }
1576}
$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.
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:489
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:487