dolibarr 23.0.4
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-2025 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 // If invoice is a down payment, we also convert down payment to discount
522 if ($invoice->type == Facture::TYPE_DEPOSIT) {
523 $amount_ht = $amount_tva = $amount_ttc = array();
524 $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
525 '
526 @phan-var-force array<string,float> $amount_ht
527 @phan-var-force array<string,float> $amount_tva
528 @phan-var-force array<string,float> $amount_ttc
529 @phan-var-force array<string,float> $multicurrency_amount_ht
530 @phan-var-force array<string,float> $multicurrency_amount_tva
531 @phan-var-force array<string,float> $multicurrency_amount_ttc
532 ';
533
534 // Insert one discount by VAT rate category
535 $discount = new DiscountAbsolute($this->db);
536 $discount->fetch(0, $invoice->id);
537 if (empty($discount->id)) { // If the invoice was not yet converted into a discount (this may have been done manually before we come here)
538 $discount->description = '(DEPOSIT)';
539 $discount->fk_soc = $invoice->socid;
540 $discount->socid = $invoice->socid;
541 $discount->fk_facture_source = $invoice->id;
542
543 // Loop on each vat rate
544 // Bucket by tva_tx and vat_src_code so the generated discount keeps the source VAT code
545 $i = 0;
546 foreach ($invoice->lines as $line) {
547 if ($line->product_type != 9 && $line->total_ht != 0) { // no need to create discount if amount is null or is special product
548 $key = $line->tva_tx.'|'.(string) $line->vat_src_code;
549 if (!array_key_exists($key, $amount_ht)) {
550 $amount_ht[$key] = 0.0;
551 $amount_tva[$key] = 0.0;
552 $amount_ttc[$key] = 0.0;
553 $multicurrency_amount_ht[$key] = 0.0;
554 $multicurrency_amount_tva[$key] = 0.0;
555 $multicurrency_amount_ttc[$key] = 0.0;
556 }
557 $amount_ht[$key] += $line->total_ht;
558 $amount_tva[$key] += $line->total_tva;
559 $amount_ttc[$key] += $line->total_ttc;
560 $multicurrency_amount_ht[$key] += $line->multicurrency_total_ht;
561 $multicurrency_amount_tva[$key] += $line->multicurrency_total_tva;
562 $multicurrency_amount_ttc[$key] += $line->multicurrency_total_ttc;
563 $i++;
564 }
565 }
566
567 foreach ($amount_ht as $key => $xxx) {
568 $parts = explode('|', (string) $key, 2);
569 $tva_tx = $parts[0];
570 $vat_src_code = isset($parts[1]) ? $parts[1] : '';
571 $discount->amount_ht = abs($amount_ht[$key]);
572 $discount->total_ht = abs($amount_ht[$key]);
573 $discount->amount_tva = abs($amount_tva[$key]);
574 $discount->total_tva = abs($amount_tva[$key]);
575 $discount->amount_ttc = abs($amount_ttc[$key]);
576 $discount->total_ttc = abs($amount_ttc[$key]);
577 $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$key]);
578 $discount->multicurrency_total_ht = abs($multicurrency_amount_ht[$key]);
579 $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$key]);
580 $discount->multicurrency_total_tva = abs($multicurrency_amount_tva[$key]);
581 $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$key]);
582 $discount->multicurrency_total_ttc = abs($multicurrency_amount_ttc[$key]);
583 $discount->tva_tx = abs((float) $tva_tx);
584 $discount->vat_src_code = $vat_src_code;
585
586 $result = $discount->create($user);
587 if ($result < 0) {
588 $error++;
589 break;
590 }
591 }
592 }
593
594 if ($error) {
595 $this->error = $discount->error;
596 $this->errors = $discount->errors;
597 $error++;
598 }
599 }
600
601 // Set invoice to paid
602 if (!$error) {
603 $invoice->context['actionmsgmore'] = 'Invoice set to paid by the payment->create() of payment '.$this->ref.' because the remain to pay is 0';
604
605 $result = $invoice->setPaid($user, '', '');
606 if ($result < 0) {
607 $this->error = $invoice->error;
608 $this->errors = $invoice->errors;
609 $error++;
610 }
611 }
612 }
613 }
614
615 // Regenerate documents of invoices
616 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
617 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);
618
619 $newlang = '';
620 $outputlangs = $langs;
621 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
622 $invoice->fetch_thirdparty();
623 $newlang = $invoice->thirdparty->default_lang;
624 }
625 if (!empty($newlang)) {
626 $outputlangs = new Translate("", $conf);
627 $outputlangs->setDefaultLang($newlang);
628 }
629
630 $hidedetails = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0;
631 $hidedesc = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0;
632 $hideref = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0;
633
634 $ret = $invoice->fetch($facid); // Reload to get new records
635
636 $result = $invoice->generateDocument($invoice->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
637
638 dol_syslog(get_class($this).'::create Regenerate end result='.$result, LOG_DEBUG);
639
640 $this->warnings = $invoice->warnings;
641
642 if ($result < 0) {
643 $this->error = $invoice->error;
644 $this->errors = $invoice->errors;
645 $error++;
646 }
647 }
648 } else {
649 $this->error = $this->db->lasterror();
650 $error++;
651 }
652 } else {
653 dol_syslog(get_class($this).'::Create Amount line '.$key.' not a number. We discard it.');
654 }
655 }
656
657 dol_syslog(get_class($this).'::create Now we call the triggers if no error (error = '.$error.')', LOG_DEBUG);
658
659 if (!$error) { // All payments into $this->amounts were recorded without errors
660 // Appel des triggers
661 $result = $this->call_trigger('PAYMENT_CUSTOMER_CREATE', $user);
662 if ($result < 0) {
663 $error++;
664 }
665 // Fin appel triggers
666 }
667 } else {
668 $this->error = $this->db->lasterror();
669 $error++;
670 }
671
672 if (!$error) {
673 // Set some properties that may be used by other process after calling the create
674 $this->amount = $total;
675 $this->total = $total; // deprecated
676 $this->multicurrency_amount = $mtotal;
677 $this->multicurrency_currency = $currencyofinvoices;
678
679 $this->db->commit();
680 return $this->id;
681 } else {
682 $this->db->rollback();
683 return -1;
684 }
685 }
686
687
697 public function delete($user, $notrigger = 0)
698 {
699 $bank_line_id = $this->bank_line;
700
701 $this->db->begin();
702
703 // Verifier si paiement porte pas sur une facture classee
704 // Si c'est le cas, on refuse la suppression
705 $billsarray = $this->getBillsArray('f.fk_statut > 1');
706 if (is_array($billsarray)) {
707 if (count($billsarray)) {
708 $this->error = "ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible";
709 $this->db->rollback();
710 return -1;
711 }
712 } else {
713 $this->db->rollback();
714 return -2;
715 }
716
717 // Delete bank urls. If payment is on a conciliated line, return error.
718 if ($bank_line_id > 0) {
719 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
720 $accline = new AccountLine($this->db);
721
722 $result = $accline->fetch($bank_line_id);
723 if ($result == 0) {
724 $accline->id = $accline->rowid = $bank_line_id; // If not found, we set artificially rowid to allow delete of llx_bank_url
725 }
726
727 // Delete bank account url lines linked to payment
728 $result = $accline->delete_urls($user);
729 if ($result < 0) {
730 $this->error = $accline->error;
731 $this->db->rollback();
732 return -3;
733 }
734
735 // Delete bank account lines linked to payment
736 $result = $accline->delete($user);
737 if ($result < 0) {
738 $this->error = $accline->error;
739 $this->db->rollback();
740 return -4;
741 }
742 }
743
744 if (!$notrigger) {
745 // Call triggers
746 $result = $this->call_trigger('PAYMENT_CUSTOMER_DELETE', $user);
747 if ($result < 0) {
748 $this->db->rollback();
749 return -1;
750 }
751 // End call triggers
752 }
753
754 $this->deleteExtraFields();
755 // Delete payment (into paiement_facture and paiement)
756 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement_facture';
757 $sql .= ' WHERE fk_paiement = '.((int) $this->id);
758 dol_syslog($sql);
759 $result = $this->db->query($sql);
760 if ($result) {
761 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement';
762 $sql .= " WHERE rowid = ".((int) $this->id);
763 dol_syslog($sql);
764 $result = $this->db->query($sql);
765 if (!$result) {
766 $this->error = $this->db->lasterror();
767 $this->db->rollback();
768 return -3;
769 }
770
771 $this->db->commit();
772 return 1;
773 } else {
774 $this->error = $this->db->error;
775 $this->db->rollback();
776 return -5;
777 }
778 }
779
780
796 public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0, $accountancycode = '', $addbankurl = '')
797 {
798 global $conf, $user;
799
800 $error = 0;
801 $bank_line_id = 0;
802
803 // Note: ->amount (amount in company currency) ant multicurrency_amount (amount in )was set by the ->create beforecalling this.
804 // The create had also checked that currency of payment is same than currency of bank account
805
806 if (isModEnabled("bank")) {
807 if ($accountid <= 0) {
808 $this->error = 'Bad value for parameter accountid='.$accountid;
809 dol_syslog(get_class($this).'::addPaymentToBank '.$this->error, LOG_ERR);
810 return -1;
811 }
812
813 $this->fk_account = $accountid;
814
815 dol_syslog("addPaymentToBank ".$user->id.", ".$mode.", ".$label.", ".$this->fk_account.", ".$emetteur_nom.", ".$emetteur_banque);
816
817 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
818 $acc = new Account($this->db);
819 $result = $acc->fetch($this->fk_account);
820 if ($result < 0) {
821 $this->error = $acc->error;
822 $this->errors = $acc->errors;
823 $error++;
824 return -1;
825 }
826
827 $this->db->begin();
828
829 $totalamount = $this->amount;
830 $totalamount_main_currency = null;
831 if (empty($totalamount)) {
832 $totalamount = $this->total; // For backward compatibility
833 }
834
835 // this->amount is amount of payment in company currency
836 // this->multicurrency_amount of payment in other currency
837 // this->multicurrency_currency is the currency of the payment (may be same than the company one)
838 if ($this->multicurrency_currency == $conf->currency) {
839 if ($this->amount != $this->multicurrency_amount) {
840 // Add protection, should not happen
841 $error++;
842 $this->error = 'Payment in same currency than company but this->amount != this->multicurrency_amount';
843 }
844 }
845
846 // 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)
847 if ($conf->currency != $acc->currency_code) {
848 $totalamount = $this->multicurrency_amount; // We will insert into llx_bank.amount in foreign currency of invoice
849 $totalamount_main_currency = $this->amount; // We will also save the amount in main currency into column llx_bank.amount_main_currency
850 }
851
852 if ($mode == 'payment_supplier') {
853 $totalamount = -$totalamount;
854 if (isset($totalamount_main_currency)) {
855 $totalamount_main_currency = -$totalamount_main_currency;
856 }
857 }
858
859 // Insert payment into llx_bank
860 $bank_line_id = $acc->addline(
861 $this->datepaye,
862 $this->paiementcode ? $this->paiementcode : $this->paiementid, // Payment mode code ('CB', 'CHQ' or 'VIR' for example). Use payment id if not defined for backward compatibility.
863 $label,
864 $totalamount, // Sign must be positive when we receive money (customer payment), negative when you give money (supplier invoice or credit note)
865 $this->num_payment,
866 0,
867 $user,
868 $emetteur_nom,
869 $emetteur_banque,
870 $accountancycode,
871 0,
872 '',
873 (float) $totalamount_main_currency
874 );
875
876 // Mise a jour fk_bank dans llx_paiement
877 // On connait ainsi le paiement qui a genere l'ecriture bancaire
878 if ($bank_line_id > 0) {
879 $result = $this->update_fk_bank($bank_line_id);
880 if ($result <= 0) {
881 $error++;
882 dol_print_error($this->db);
883 }
884
885 // Add link 'payment', 'payment_supplier' in bank_url between payment and bank transaction
886 if (!$error) {
887 $url = '';
888 if ($mode == 'payment') {
889 $url = DOL_URL_ROOT.'/compta/paiement/card.php?id=';
890 }
891 if ($mode == 'payment_supplier') {
892 $url = DOL_URL_ROOT.'/fourn/paiement/card.php?id=';
893 }
894 if ($url) {
895 $result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode);
896 if ($result <= 0) {
897 $error++;
898 dol_print_error($this->db);
899 }
900 }
901 }
902
903 // Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment)
904 if (!$error) {
905 $linkaddedforthirdparty = array();
906 foreach ($this->amounts as $key => $value) { // We should have invoices always for same third party but we loop in case of.
907 // Skip the invoices that were listed but not paid, the same way create() does. Without this,
908 // a 'company' link is added to the bank line for a third party that received no payment.
909 if (!is_numeric($value) || $value == 0) {
910 continue;
911 }
912 if ($mode == 'payment') {
913 $fac = new Facture($this->db);
914 $fac->fetch($key);
915 $fac->fetch_thirdparty();
916 if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty @phan-suppress-current-line PhanPossiblyUndeclaredVariable
917 $result = $acc->add_url_line(
918 $bank_line_id,
919 $fac->thirdparty->id,
920 DOL_URL_ROOT.'/comm/card.php?socid=',
921 (string) $fac->thirdparty->name,
922 'company'
923 );
924 if ($result <= 0) {
925 $error++;
926 dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
927 }
928 $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
929 }
930 }
931 if ($mode == 'payment_supplier') {
932 $fac = new FactureFournisseur($this->db);
933 $fac->fetch($key);
934 $fac->fetch_thirdparty();
935 if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty
936 $result = $acc->add_url_line(
937 $bank_line_id,
938 $fac->thirdparty->id,
939 DOL_URL_ROOT.'/fourn/card.php?socid=',
940 (string) $fac->thirdparty->name,
941 'company'
942 );
943 if ($result <= 0) {
944 $error++;
945 dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
946 }
947 $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
948 }
949 }
950 }
951 }
952
953 // Add a link to the Direct Debit ('direct-debit') or Credit transfer ('credit-transfer') file in bank_url
954 if (!$error && $addbankurl && in_array($addbankurl, array('direct-debit', 'credit-transfer'))) {
955 $result = $acc->add_url_line(
956 $bank_line_id,
957 $this->id_prelevement,
958 DOL_URL_ROOT.'/compta/prelevement/card.php?id=',
959 $this->num_payment,
960 $addbankurl
961 );
962 }
963
964 // Add link to the Direct Debit if invoice refused ('InvoiceRefused') in bank_url
965 if (!$error && $label == '(InvoiceRefused)') {
966 $result = $acc->add_url_line(
967 $bank_line_id,
968 $this->id_prelevement,
969 DOL_URL_ROOT.'/compta/prelevement/card.php?id=',
970 $this->num_prelevement,
971 'withdraw'
972 );
973 }
974
975 if (!$error && !$notrigger) {
976 // Appel des triggers
977 $result = $this->call_trigger('PAYMENT_ADD_TO_BANK', $user);
978 if ($result < 0) {
979 $error++;
980 }
981 // Fin appel triggers
982 }
983 } else {
984 $this->error = $acc->error;
985 $this->errors = $acc->errors;
986 $error++;
987 }
988
989 if (!$error) {
990 $this->db->commit();
991 } else {
992 $this->db->rollback();
993 }
994 }
995
996 if (!$error) {
997 return $bank_line_id;
998 } else {
999 return -1;
1000 }
1001 }
1002
1003
1004 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1011 public function update_fk_bank($id_bank)
1012 {
1013 // phpcs:enable
1014 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' set fk_bank = '.((int) $id_bank);
1015 $sql .= " WHERE rowid = ".((int) $this->id);
1016
1017 dol_syslog(get_class($this).'::update_fk_bank', LOG_DEBUG);
1018 $result = $this->db->query($sql);
1019 if ($result) {
1020 return 1;
1021 } else {
1022 $this->error = $this->db->lasterror();
1023 dol_syslog(get_class($this).'::update_fk_bank '.$this->error);
1024 return -1;
1025 }
1026 }
1027
1028 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1035 public function update_date($date)
1036 {
1037 // phpcs:enable
1038 $error = 0;
1039
1040 if (!empty($date) && $this->statut != 1) {
1041 $this->db->begin();
1042
1043 dol_syslog(get_class($this)."::update_date with date = ".$date, LOG_DEBUG);
1044
1045 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1046 $sql .= " SET datep = '".$this->db->idate($date)."'";
1047 $sql .= " WHERE rowid = ".((int) $this->id);
1048
1049 $result = $this->db->query($sql);
1050 if (!$result) {
1051 $error++;
1052 $this->error = 'Error -1 '.$this->db->error();
1053 }
1054
1055 $type = $this->element;
1056
1057 $sql = "UPDATE ".MAIN_DB_PREFIX.'bank';
1058 $sql .= " SET dateo = '".$this->db->idate($date)."', datev = '".$this->db->idate($date)."'";
1059 $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).")";
1060 $sql .= " AND rappro = 0";
1061
1062 $result = $this->db->query($sql);
1063 if (!$result) {
1064 $error++;
1065 $this->error = 'Error -1 '.$this->db->error();
1066 }
1067
1068 if (!$error) {
1069 $this->datepaye = $date;
1070 $this->date = $date;
1071
1072 $this->db->commit();
1073 return 0;
1074 } else {
1075 $this->db->rollback();
1076 return -2;
1077 }
1078 }
1079 return -1; //no date given or already validated
1080 }
1081
1082 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1089 public function update_num($num_payment)
1090 {
1091 // phpcs:enable
1092 if (!empty($num_payment) && $this->statut != 1) {
1093 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1094 $sql .= " SET num_paiement = '".$this->db->escape($num_payment)."'";
1095 $sql .= " WHERE rowid = ".((int) $this->id);
1096
1097 dol_syslog(get_class($this)."::update_num", LOG_DEBUG);
1098 $result = $this->db->query($sql);
1099 if ($result) {
1100 $this->num_payment = $this->db->escape($num_payment);
1101 return 0;
1102 } else {
1103 $this->error = 'Error -1 '.$this->db->error();
1104 return -2;
1105 }
1106 }
1107 return -1; //no num given or already validated
1108 }
1109
1117 public function valide($user = null)
1118 {
1119 return $this->validate($user);
1120 }
1121
1128 public function validate($user = null)
1129 {
1130 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET statut = 1 WHERE rowid = '.((int) $this->id);
1131
1132 dol_syslog(get_class($this).'::valide', LOG_DEBUG);
1133 $result = $this->db->query($sql);
1134 if ($result) {
1135 return 1;
1136 } else {
1137 $this->error = $this->db->lasterror();
1138 dol_syslog(get_class($this).'::valide '.$this->error);
1139 return -1;
1140 }
1141 }
1142
1149 public function reject($user = null)
1150 {
1151 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET statut = 2 WHERE rowid = '.((int) $this->id);
1152
1153 dol_syslog(get_class($this).'::reject', LOG_DEBUG);
1154 $result = $this->db->query($sql);
1155 if ($result) {
1156 return 1;
1157 } else {
1158 $this->error = $this->db->lasterror();
1159 dol_syslog(get_class($this).'::reject '.$this->error);
1160 return -1;
1161 }
1162 }
1163
1170 public function info($id)
1171 {
1172 $sql = 'SELECT p.rowid, p.datec, p.fk_user_creat, p.fk_user_modif, p.tms';
1173 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p';
1174 $sql .= ' WHERE p.rowid = '.((int) $id);
1175
1176 dol_syslog(get_class($this).'::info', LOG_DEBUG);
1177 $result = $this->db->query($sql);
1178
1179 if ($result) {
1180 if ($this->db->num_rows($result)) {
1181 $obj = $this->db->fetch_object($result);
1182
1183 $this->id = $obj->rowid;
1184
1185 $this->user_creation_id = $obj->fk_user_creat;
1186 $this->user_modification_id = $obj->fk_user_modif;
1187 $this->date_creation = $this->db->jdate($obj->datec);
1188 $this->date_modification = $this->db->jdate($obj->tms);
1189 }
1190 $this->db->free($result);
1191 } else {
1192 dol_print_error($this->db);
1193 }
1194 }
1195
1203 public function getBillsArray($filter = '')
1204 {
1205 $sql = 'SELECT pf.fk_facture';
1206 $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
1207 $sql .= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.((int) $this->id);
1208 if ($filter) {
1209 $sql .= ' AND '.$filter;
1210 }
1211 $resql = $this->db->query($sql);
1212 if ($resql) {
1213 $i = 0;
1214 $num = $this->db->num_rows($resql);
1215 $billsarray = array();
1216
1217 while ($i < $num) {
1218 $obj = $this->db->fetch_object($resql);
1219 $billsarray[$i] = $obj->fk_facture;
1220 $i++;
1221 }
1222
1223 return $billsarray;
1224 } else {
1225 $this->error = $this->db->error();
1226 dol_syslog(get_class($this).'::getBillsArray Error '.$this->error.' -', LOG_DEBUG);
1227 return -1;
1228 }
1229 }
1230
1237 public function getAmountsArray()
1238 {
1239 $sql = 'SELECT pf.fk_facture, pf.amount';
1240 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
1241 $sql .= ' WHERE pf.fk_paiement = '.((int) $this->id);
1242 $resql = $this->db->query($sql);
1243 if ($resql) {
1244 $i = 0;
1245 $num = $this->db->num_rows($resql);
1246 $amounts = array();
1247
1248 while ($i < $num) {
1249 $obj = $this->db->fetch_object($resql);
1250 $amounts[$obj->fk_facture] = $obj->amount;
1251 $i++;
1252 }
1253
1254 return $amounts;
1255 } else {
1256 $this->error = $this->db->error();
1257 dol_syslog(get_class($this).'::getAmountsArray Error '.$this->error.' -', LOG_DEBUG);
1258 return -1;
1259 }
1260 }
1261
1270 public function getNextNumRef($soc, $mode = 'next')
1271 {
1272 global $conf, $db, $langs;
1273 $langs->load("bills");
1274
1275 // Clean parameters (if not defined or using deprecated value)
1276 if (!getDolGlobalString('PAYMENT_ADDON')) {
1277 $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
1278 } elseif (getDolGlobalString('PAYMENT_ADDON') == 'ant') {
1279 $conf->global->PAYMENT_ADDON = 'mod_payment_ant';
1280 } elseif (getDolGlobalString('PAYMENT_ADDON') == 'cicada') {
1281 $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
1282 }
1283
1284 if (getDolGlobalString('PAYMENT_ADDON')) {
1285 $mybool = false;
1286
1287 $file = getDolGlobalString('PAYMENT_ADDON') . ".php";
1288 $classname = getDolGlobalString('PAYMENT_ADDON');
1289
1290 // Include file with class
1291 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1292
1293 foreach ($dirmodels as $reldir) {
1294 $dir = dol_buildpath($reldir."core/modules/payment/");
1295
1296 // Load file with numbering class (if found)
1297 if (is_file($dir.$file) && is_readable($dir.$file)) {
1298 $mybool = (include_once $dir.$file) || $mybool;
1299 }
1300 }
1301
1302 // For compatibility
1303 if (!$mybool) {
1304 $file = getDolGlobalString('PAYMENT_ADDON') . ".php";
1305 $classname = "mod_payment_" . getDolGlobalString('PAYMENT_ADDON');
1306 $classname = preg_replace('/\-.*$/', '', $classname);
1307 // Include file with class
1308 foreach ($conf->file->dol_document_root as $dirroot) {
1309 $dir = $dirroot."/core/modules/payment/";
1310
1311 // Load file with numbering class (if found)
1312 if (is_file($dir.$file) && is_readable($dir.$file)) {
1313 $mybool = (include_once $dir.$file) || $mybool;
1314 }
1315 }
1316 }
1317
1318 if (!$mybool) {
1319 dol_print_error(null, "Failed to include file ".$file);
1320 return '';
1321 }
1322
1323 $obj = new $classname();
1324 '@phan-var-force ModeleNumRefPayments $obj';
1325
1326 $numref = $obj->getNextValue($soc, $this);
1327
1332 if ($mode != 'last' && !$numref) {
1333 dol_print_error($db, "Payment::getNextNumRef ".$obj->error);
1334 return "";
1335 }
1336
1337 return $numref;
1338 } else {
1339 $langs->load("errors");
1340 print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Invoice"));
1341 return "";
1342 }
1343 }
1344
1350 public function getWay()
1351 {
1352 $way = 'dolibarr';
1353 if (isModEnabled('multicurrency')) {
1354 foreach ($this->multicurrency_amounts as $value) {
1355 if (!empty($value)) { // one value found into multicurrency_amounts so payment is in invoice currency
1356 $way = 'customer';
1357 break;
1358 }
1359 }
1360 }
1361
1362 return $way;
1363 }
1364
1373 public function initAsSpecimen($option = '')
1374 {
1375 global $user, $langs, $conf;
1376
1377 $now = dol_now();
1378 $arraynow = dol_getdate($now);
1379 $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1380
1381 // Initialize parameters
1382 $this->id = 0;
1383 $this->ref = 'SPECIMEN';
1384 $this->specimen = 1;
1385 $this->facid = 1;
1386 $this->datepaye = $nownotime;
1387
1388 return 1;
1389 }
1390
1391
1402 public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0, $morecss = '')
1403 {
1404 global $conf, $langs, $hookmanager;
1405
1406 if (!empty($conf->dol_no_mouse_hover)) {
1407 $notooltip = 1; // Force disable tooltips
1408 }
1409
1410 $result = '';
1411
1412 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Payment").'</u><br>';
1413 $label .= '<strong>'.$langs->trans("Ref").':</strong> '.$this->ref;
1414 $dateofpayment = ($this->datepaye ? $this->datepaye : $this->date);
1415 if ($dateofpayment) {
1416 $label .= '<br><strong>'.$langs->trans("Date").':</strong> ';
1417 $tmparray = dol_getdate($dateofpayment);
1418 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
1419 $label .= dol_print_date($dateofpayment, 'day');
1420 } else { // Hours was set to real date of payment (special case for POS for example)
1421 $label .= dol_print_date($dateofpayment, 'dayhour', 'tzuser');
1422 }
1423 }
1424 if ($this->amount) {
1425 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
1426 }
1427 if ($mode == 'withlistofinvoices') {
1428 $arraybill = $this->getBillsArray();
1429 if (is_array($arraybill) && count($arraybill) > 0) {
1430 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1431 $facturestatic = new Facture($this->db);
1432 foreach ($arraybill as $billid) {
1433 $facturestatic->fetch($billid);
1434 $label .= '<br> '.$facturestatic->getNomUrl(1, '', 0, 0, '', 1).' '.$facturestatic->getLibStatut(2, -1);
1435 }
1436 }
1437 }
1438
1439 $linkclose = '';
1440 if (empty($notooltip)) {
1441 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1442 $label = $langs->trans("Payment");
1443 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1444 }
1445 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
1446 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1447 } else {
1448 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1449 }
1450
1451 $url = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$this->id;
1452
1453 $linkstart = '<a href="'.$url.'"';
1454 $linkstart .= $linkclose.'>';
1455 $linkend = '</a>';
1456
1457 $result .= $linkstart;
1458 if ($withpicto) {
1459 $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);
1460 }
1461 if ($withpicto && $withpicto != 2) {
1462 $result .= ($this->ref ? $this->ref : $this->id);
1463 }
1464 $result .= $linkend;
1465 global $action;
1466 $hookmanager->initHooks(array($this->element . 'dao'));
1467 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1468 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1469 if ($reshook > 0) {
1470 $result = $hookmanager->resPrint;
1471 } else {
1472 $result .= $hookmanager->resPrint;
1473 }
1474 return $result;
1475 }
1476
1483 public function getLibStatut($mode = 0)
1484 {
1485 return $this->LibStatut($this->statut, $mode);
1486 }
1487
1488 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1496 public function LibStatut($status, $mode = 0)
1497 {
1498 // phpcs:enable
1499 global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage
1500
1501 $langs->load('compta');
1502 /*if ($mode == 0)
1503 {
1504 if ($status == 0) return $langs->trans('ToValidate');
1505 if ($status == 1) return $langs->trans('Validated');
1506 }
1507 if ($mode == 1)
1508 {
1509 if ($status == 0) return $langs->trans('ToValidate');
1510 if ($status == 1) return $langs->trans('Validated');
1511 }
1512 if ($mode == 2)
1513 {
1514 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
1515 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
1516 }
1517 if ($mode == 3)
1518 {
1519 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1');
1520 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4');
1521 }
1522 if ($mode == 4)
1523 {
1524 if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
1525 if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
1526 }
1527 if ($mode == 5)
1528 {
1529 if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1');
1530 if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
1531 }
1532 if ($mode == 6)
1533 {
1534 if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1');
1535 if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
1536 }*/
1537 return '';
1538 }
1539
1540 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1548 public function fetch_thirdparty($force_thirdparty_id = 0)
1549 {
1550 // phpcs:enable
1551 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1552
1553 if (empty($force_thirdparty_id)) {
1554 $billsarray = $this->getBillsArray(); // From payment, the fk_soc isn't available, we should load the first supplier invoice to get him
1555 if (!empty($billsarray)) {
1556 $invoice = new Facture($this->db);
1557 if ($invoice->fetch($billsarray[0]) > 0) {
1558 $force_thirdparty_id = $invoice->socid;
1559 }
1560 }
1561 }
1562
1563 return parent::fetch_thirdparty($force_thirdparty_id);
1564 }
1565
1566
1572 public function isReconciled()
1573 {
1574 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1575 $accountline = new AccountLine($this->db);
1576 $accountline->fetch($this->bank_line);
1577 return $accountline->rappro ? true : false;
1578 }
1579}
$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.
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.
if(getDolGlobalString( 'TAKEPOS_SHOW_CUSTOMER')) print $langs trans('Date')." left 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 PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:471
if(getDolGlobalString( 'TAKEPOS_SHOW_CUSTOMER')) print $langs trans('Date')." left 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 PaymentTypeShortLIQ right SELECT p pos_change as p datep as date
Definition receipt.php:469