dolibarr  16.0.1
facture-rec.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
7  * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
9  * Copyright (C) 2017-2020 Frédéric France <frederic.france@netlogic.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
23  */
24 
31 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
35 
36 
41 {
42  const TRIGGER_PREFIX = 'BILLREC';
46  public $element = 'facturerec';
47 
51  public $table_element = 'facture_rec';
52 
56  public $table_element_line = 'facturedet_rec';
57 
61  public $fk_element = 'fk_facture';
62 
66  public $picto = 'bill';
67 
71  public $entity;
72 
76  protected $table_ref_field = 'titre';
77 
81  public $title;
82 
83  public $socid;
84  public $number;
85  public $date;
86  public $remise;
87  public $remise_absolue;
88  public $remise_percent;
89 
94  public $total;
95 
100  public $tva;
101 
102  public $date_last_gen;
103  public $date_when;
104  public $nb_gen_done;
105  public $nb_gen_max;
106 
107  public $user_author;
108 
112  public $frequency;
113 
117  public $unit_frequency;
118 
119  public $rang;
120  public $special_code;
121 
122  public $usenewprice = 0;
123 
124  public $date_lim_reglement;
125  public $cond_reglement_code; // Code in llx_c_paiement
126  public $mode_reglement_code; // Code in llx_c_paiement
127 
128  public $suspended; // status
129 
130  public $auto_validate; // 0 to create in draft, 1 to create and validate the new invoice
131  public $generate_pdf; // 1 to generate PDF on invoice generation (default)
132 
137  public $brouillon;
138 
139 
164  // BEGIN MODULEBUILDER PROPERTIES
168  public $fields = array(
169  'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
170  'titre' =>array('type'=>'varchar(100)', 'label'=>'Titre', 'enabled'=>1, 'showoncombobox' => 1, 'visible'=>-1, 'position'=>15),
171  'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>20, 'index'=>1),
172  'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>25),
173  'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>30),
174  //'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
175  'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
176  //'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
177  //'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
178  'total_tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>55, 'isameasure'=>1),
179  'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'isameasure'=>1),
180  'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>65, 'isameasure'=>1),
181  'total_ht' =>array('type'=>'double(24,8)', 'label'=>'Total', 'enabled'=>1, 'visible'=>-1, 'position'=>70, 'isameasure'=>1),
182  'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>75, 'isameasure'=>1),
183  'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
184  'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>85),
185  'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Fk cond reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
186  'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'Fk mode reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
187  'date_lim_reglement' =>array('type'=>'date', 'label'=>'Date lim reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
188  'note_private' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>105),
189  'note_public' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>110),
190  'modelpdf' =>array('type'=>'varchar(255)', 'label'=>'Modelpdf', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
191  'date_last_gen' =>array('type'=>'varchar(7)', 'label'=>'Last gen', 'enabled'=>1, 'visible'=>-1, 'position'=>120),
192  'unit_frequency' =>array('type'=>'varchar(2)', 'label'=>'Unit frequency', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
193  'date_when' =>array('type'=>'datetime', 'label'=>'Date when', 'enabled'=>1, 'visible'=>-1, 'position'=>130),
194  'date_last_gen' =>array('type'=>'datetime', 'label'=>'Date last gen', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
195  'nb_gen_done' =>array('type'=>'integer', 'label'=>'Nb gen done', 'enabled'=>1, 'visible'=>-1, 'position'=>140),
196  'nb_gen_max' =>array('type'=>'integer', 'label'=>'Nb gen max', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
197  'frequency' =>array('type'=>'integer', 'label'=>'Frequency', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
198  'usenewprice' =>array('type'=>'integer', 'label'=>'UseNewPrice', 'enabled'=>1, 'visible'=>0, 'position'=>155),
199  'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>160, 'isameasure'=>1),
200  'auto_validate' =>array('type'=>'integer', 'label'=>'Auto validate', 'enabled'=>1, 'visible'=>-1, 'position'=>165),
201  'generate_pdf' =>array('type'=>'integer', 'label'=>'Generate pdf', 'enabled'=>1, 'visible'=>-1, 'position'=>170),
202  'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>'$conf->banque->enabled', 'visible'=>-1, 'position'=>175),
203  'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
204  'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
205  'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>190, 'isameasure'=>1),
206  'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>195, 'isameasure'=>1),
207  'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>200, 'isameasure'=>1),
208  'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>205, 'isameasure'=>1),
209  'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>210),
210  'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>215),
211  'suspended' =>array('type'=>'integer', 'label'=>'Suspended', 'enabled'=>1, 'visible'=>-1, 'position'=>225),
212  );
213  // END MODULEBUILDER PROPERTIES
214 
215  const STATUS_NOTSUSPENDED = 0;
216  const STATUS_SUSPENDED = 1;
217 
218 
219 
225  public function __construct(DoliDB $db)
226  {
227  $this->db = $db;
228  }
229 
238  public function create($user, $facid, $notrigger = 0)
239  {
240  global $conf;
241 
242  $error = 0;
243  $now = dol_now();
244 
245  // Clean parameters
246  $this->titre = trim(isset($this->titre) ? $this->titre : $this->title); // deprecated
247  $this->title = trim($this->title);
248  $this->usenewprice = empty($this->usenewprice) ? 0 : $this->usenewprice;
249  if (empty($this->suspended)) {
250  $this->suspended = 0;
251  }
252 
253  // No frequency defined then no next date to execution
254  if (empty($this->frequency)) {
255  $this->frequency = 0;
256  $this->date_when = null;
257  }
258 
259  $this->frequency = abs($this->frequency);
260  $this->nb_gen_done = 0;
261  $this->nb_gen_max = empty($this->nb_gen_max) ? 0 : $this->nb_gen_max;
262  $this->auto_validate = empty($this->auto_validate) ? 0 : $this->auto_validate;
263  $this->generate_pdf = empty($this->generate_pdf) ? 0 : $this->generate_pdf;
264 
265  $this->db->begin();
266 
267  // Charge facture modele
268  $facsrc = new Facture($this->db);
269  $result = $facsrc->fetch($facid);
270  if ($result > 0) {
271  // On positionne en mode brouillon la facture
272  $this->brouillon = 1;
273  $this->fk_soc = $facsrc->socid;
274 
275  $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture_rec (";
276  $sql .= "titre";
277  $sql .= ", fk_soc";
278  $sql .= ", entity";
279  $sql .= ", datec";
280  $sql .= ", amount";
281  $sql .= ", remise";
282  $sql .= ", note_private";
283  $sql .= ", note_public";
284  $sql .= ", modelpdf";
285  $sql .= ", fk_user_author";
286  $sql .= ", fk_projet";
287  $sql .= ", fk_account";
288  $sql .= ", fk_cond_reglement";
289  $sql .= ", fk_mode_reglement";
290  $sql .= ", usenewprice";
291  $sql .= ", frequency";
292  $sql .= ", unit_frequency";
293  $sql .= ", date_when";
294  $sql .= ", date_last_gen";
295  $sql .= ", nb_gen_done";
296  $sql .= ", nb_gen_max";
297  $sql .= ", auto_validate";
298  $sql .= ", generate_pdf";
299  $sql .= ", fk_multicurrency";
300  $sql .= ", multicurrency_code";
301  $sql .= ", multicurrency_tx";
302  $sql .= ", suspended";
303  $sql .= ") VALUES (";
304  $sql .= "'".$this->db->escape($this->titre ? $this->titre : $this->title)."'";
305  $sql .= ", ".((int) $this->fk_soc);
306  $sql .= ", ".((int) $conf->entity);
307  $sql .= ", '".$this->db->idate($now)."'";
308  $sql .= ", ".(!empty($facsrc->total_ttc) ? ((float) $facsrc->total_ttc) : '0');
309  $sql .= ", ".(!empty($facsrc->remise_absolue) ? ((float) $this->remise_absolue) : '0');
310  $sql .= ", ".(!empty($this->note_private) ? ("'".$this->db->escape($this->note_private)."'") : "NULL");
311  $sql .= ", ".(!empty($this->note_public) ? ("'".$this->db->escape($this->note_public)."'") : "NULL");
312  $sql .= ", ".(!empty($this->model_pdf) ? ("'".$this->db->escape($this->model_pdf)."'") : "NULL");
313  $sql .= ", ".((int) $user->id);
314  $sql .= ", ".(!empty($this->fk_project) ? ((int) $this->fk_project) : "null");
315  $sql .= ", ".(!empty($facsrc->fk_account) ? ((int) $facsrc->fk_account) : "null");
316  $sql .= ", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) : "null");
317  $sql .= ", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) : "null");
318  $sql .= ", ".((int) $this->usenewprice);
319  $sql .= ", ".((int) $this->frequency);
320  $sql .= ", '".$this->db->escape($this->unit_frequency)."'";
321  $sql .= ", ".(!empty($this->date_when) ? "'".$this->db->idate($this->date_when)."'" : 'NULL');
322  $sql .= ", ".(!empty($this->date_last_gen) ? "'".$this->db->idate($this->date_last_gen)."'" : 'NULL');
323  $sql .= ", ".((int) $this->nb_gen_done);
324  $sql .= ", ".((int) $this->nb_gen_max);
325  $sql .= ", ".((int) $this->auto_validate);
326  $sql .= ", ".((int) $this->generate_pdf);
327  $sql .= ", ".((int) $facsrc->fk_multicurrency);
328  $sql .= ", '".$this->db->escape($facsrc->multicurrency_code)."'";
329  $sql .= ", ".((float) $facsrc->multicurrency_tx);
330  $sql .= ", ".((int) $this->suspended);
331  $sql .= ")";
332 
333  if ($this->db->query($sql)) {
334  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."facture_rec");
335 
336  // Fields used into addline later
337  $this->fk_multicurrency = $facsrc->fk_multicurrency;
338  $this->multicurrency_code = $facsrc->multicurrency_code;
339  $this->multicurrency_tx = $facsrc->multicurrency_tx;
340 
341  // Add lines
342  $num = count($facsrc->lines);
343  for ($i = 0; $i < $num; $i++) {
344  $tva_tx = $facsrc->lines[$i]->tva_tx;
345  if (!empty($facsrc->lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) {
346  $tva_tx .= ' ('.$facsrc->lines[$i]->vat_src_code.')';
347  }
348 
349  $default_start_fill = getDolGlobalInt('INVOICEREC_SET_AUTOFILL_DATE_START');
350  $default_end_fill = getDolGlobalInt('INVOICEREC_SET_AUTOFILL_DATE_END');
351 
352  $result_insert = $this->addline(
353  $facsrc->lines[$i]->desc,
354  $facsrc->lines[$i]->subprice,
355  $facsrc->lines[$i]->qty,
356  $tva_tx,
357  $facsrc->lines[$i]->localtax1_tx,
358  $facsrc->lines[$i]->localtax2_tx,
359  $facsrc->lines[$i]->fk_product,
360  $facsrc->lines[$i]->remise_percent,
361  'HT',
362  $facsrc->lines[$i]->info_bits,
363  '',
364  0,
365  $facsrc->lines[$i]->product_type,
366  $facsrc->lines[$i]->rang,
367  $facsrc->lines[$i]->special_code,
368  $facsrc->lines[$i]->label,
369  $facsrc->lines[$i]->fk_unit,
370  $facsrc->lines[$i]->multicurrency_subprice,
371  $default_start_fill,
372  $default_end_fill,
373  null,
374  $facsrc->lines[$i]->pa_ht
375  );
376 
377  if ($result_insert < 0) {
378  $error++;
379  } else {
380  $objectline = new FactureLigneRec($this->db);
381 
382  $result2 = $objectline->fetch($result_insert);
383  if ($result2 > 0) {
384  // Extrafields
385  if (method_exists($facsrc->lines[$i], 'fetch_optionals')) {
386  $facsrc->lines[$i]->fetch_optionals($facsrc->lines[$i]->id);
387  $objectline->array_options = $facsrc->lines[$i]->array_options;
388  }
389 
390  $result = $objectline->insertExtraFields();
391  if ($result < 0) {
392  $error++;
393  }
394  } elseif ($result2 < 0) {
395  $this->errors[] = $objectline->error;
396  $error++;
397  }
398  }
399  }
400 
401  if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) { // To use new linkedObjectsIds instead of old linked_objects
402  $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds
403  }
404 
405  // Add object linked
406  if (!$error && $this->id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
407  foreach ($this->linked_objects as $origin => $tmp_origin_id) {
408  if (is_array($tmp_origin_id)) { // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
409  foreach ($tmp_origin_id as $origin_id) {
410  $ret = $this->add_object_linked($origin, $origin_id);
411  if (!$ret) {
412  $this->error = $this->db->lasterror();
413  $error++;
414  }
415  }
416  } else // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
417  {
418  $origin_id = $tmp_origin_id;
419  $ret = $this->add_object_linked($origin, $origin_id);
420  if (!$ret) {
421  $this->error = $this->db->lasterror();
422  $error++;
423  }
424  }
425  }
426  }
427 
428  if (!$error) {
429  $result = $this->insertExtraFields();
430  if ($result < 0) {
431  $error++;
432  }
433  }
434 
435  if (!$error && !$notrigger) {
436  // Call trigger
437  $result = $this->call_trigger('BILLREC_CREATE', $user);
438  if ($result < 0) {
439  $this->db->rollback();
440  return -2;
441  }
442  // End call triggers
443  }
444 
445  if ($error) {
446  $this->db->rollback();
447  return -3;
448  } else {
449  $this->db->commit();
450  return $this->id;
451  }
452  } else {
453  $this->error = $this->db->lasterror();
454  $this->db->rollback();
455  return -2;
456  }
457  } else {
458  $this->db->rollback();
459  return -1;
460  }
461  }
462 
463 
471  public function update(User $user, $notrigger = 0)
472  {
473  global $conf;
474 
475  $error = 0;
476 
477  $sql = "UPDATE ".MAIN_DB_PREFIX."facture_rec SET";
478  $sql .= " entity = ".((int) $this->entity).",";
479  $sql .= " titre = '".$this->db->escape($this->title)."',";
480  $sql .= " suspended = ".((int) $this->suspended).",";
481  $sql .= " fk_soc = ".((int) $this->socid).",";
482  $sql .= " total_tva = ".((float) $this->total_tva).",";
483  $sql .= " localtax1 = ".((float) $this->localtax1).",";
484  $sql .= " localtax2 = ".((float) $this->localtax2).",";
485  $sql .= " total_ht = ".((float) $this->total_ht).",";
486  $sql .= " total_ttc = ".((float) $this->total_ttc).",";
487  $sql .= " remise_percent = ".((float) $this->remise_percent);
488  // TODO Add missing fields
489  $sql .= " WHERE rowid = ".((int) $this->id);
490 
491  $this->db->begin();
492 
493  dol_syslog(get_class($this)."::update", LOG_DEBUG);
494 
495  $resql = $this->db->query($sql);
496  if ($resql) {
497  if (!$error) {
498  $result = $this->insertExtraFields();
499  if ($result < 0) {
500  $error++;
501  }
502  }
503 
504  if (!$error && !$notrigger) {
505  // Call trigger
506  $result = $this->call_trigger('BILLREC_MODIFY', $user);
507  if ($result < 0) {
508  $this->db->rollback();
509  return -2;
510  }
511  // End call triggers
512  }
513  $this->db->commit();
514  return 1;
515  } else {
516  $this->error = $this->db->lasterror();
517  $this->db->rollback();
518  return -1;
519  }
520  }
521 
530  public function fetch($rowid, $ref = '', $ref_ext = '')
531  {
532  dol_syslog('FactureRec::fetch', LOG_DEBUG);
533 
534  $sql = 'SELECT f.rowid, f.entity, f.titre as title, f.suspended, f.fk_soc, f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc';
535  $sql .= ', f.remise_percent, f.remise_absolue, f.remise';
536  $sql .= ', f.date_lim_reglement as dlr';
537  $sql .= ', f.note_private, f.note_public, f.fk_user_author';
538  $sql .= ', f.modelpdf as model_pdf';
539  $sql .= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet as fk_project';
540  $sql .= ', f.fk_account';
541  $sql .= ', f.frequency, f.unit_frequency, f.date_when, f.date_last_gen, f.nb_gen_done, f.nb_gen_max, f.usenewprice, f.auto_validate';
542  $sql .= ', f.generate_pdf';
543  $sql .= ", f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc";
544  $sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
545  $sql .= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
546  //$sql.= ', el.fk_source';
547  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_rec as f';
548  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
549  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
550  //$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = f.rowid AND el.targettype = 'facture'";
551  $sql .= ' WHERE f.entity IN ('.getEntity('invoice').')';
552  if ($rowid) {
553  $sql .= ' AND f.rowid = '.((int) $rowid);
554  } elseif ($ref) {
555  $sql .= " AND f.titre = '".$this->db->escape($ref)."'";
556  } else {
557  $sql .= ' AND f.rowid = 0';
558  }
559  /* This field are not used for template invoice
560  if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'";
561  */
562 
563  $result = $this->db->query($sql);
564  if ($result) {
565  if ($this->db->num_rows($result)) {
566  $obj = $this->db->fetch_object($result);
567 
568  $this->id = $obj->rowid;
569  $this->entity = $obj->entity;
570  $this->titre = $obj->title; // deprecated
571  $this->title = $obj->title;
572  $this->ref = $obj->title;
573  $this->suspended = $obj->suspended;
574  $this->remise_percent = $obj->remise_percent;
575  $this->remise_absolue = $obj->remise_absolue;
576  $this->remise = $obj->remise;
577  $this->total_ht = $obj->total_ht;
578  $this->total_tva = $obj->total_tva;
579  $this->total_localtax1 = $obj->localtax1;
580  $this->total_localtax2 = $obj->localtax2;
581  $this->total_ttc = $obj->total_ttc;
582  $this->socid = $obj->fk_soc;
583  $this->date_lim_reglement = $this->db->jdate($obj->dlr);
584  $this->mode_reglement_id = $obj->fk_mode_reglement;
585  $this->mode_reglement_code = $obj->mode_reglement_code;
586  $this->mode_reglement = $obj->mode_reglement_libelle;
587  $this->cond_reglement_id = $obj->fk_cond_reglement;
588  $this->cond_reglement_code = $obj->cond_reglement_code;
589  $this->cond_reglement = $obj->cond_reglement_libelle;
590  $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
591  $this->fk_project = $obj->fk_project;
592  $this->fk_account = $obj->fk_account;
593  $this->note_private = $obj->note_private;
594  $this->note_public = $obj->note_public;
595  $this->user_author = $obj->fk_user_author;
596  $this->modelpdf = $obj->model_pdf; // deprecated
597  $this->model_pdf = $obj->model_pdf;
598  //$this->special_code = $obj->special_code;
599  $this->frequency = $obj->frequency;
600  $this->unit_frequency = $obj->unit_frequency;
601  $this->date_when = $this->db->jdate($obj->date_when);
602  $this->date_last_gen = $this->db->jdate($obj->date_last_gen);
603  $this->nb_gen_done = $obj->nb_gen_done;
604  $this->nb_gen_max = $obj->nb_gen_max;
605  $this->usenewprice = $obj->usenewprice;
606  $this->auto_validate = $obj->auto_validate;
607  $this->generate_pdf = $obj->generate_pdf;
608 
609  // Multicurrency
610  $this->fk_multicurrency = $obj->fk_multicurrency;
611  $this->multicurrency_code = $obj->multicurrency_code;
612  $this->multicurrency_tx = $obj->multicurrency_tx;
613  $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
614  $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
615  $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
616 
617  if ($this->statut == self::STATUS_DRAFT) {
618  $this->brouillon = 1;
619  }
620 
621  // Retrieve all extrafield
622  // fetch optionals attributes and labels
623  $this->fetch_optionals();
624 
625  /*
626  * Lines
627  */
628  $result = $this->fetch_lines();
629  if ($result < 0) {
630  $this->error = $this->db->lasterror();
631  return -3;
632  }
633  return 1;
634  } else {
635  $this->error = 'Bill with id '.$rowid.' or ref '.$ref.' not found';
636  dol_syslog('Facture::Fetch Error '.$this->error, LOG_ERR);
637  return -2;
638  }
639  } else {
640  $this->error = $this->db->error();
641  return -1;
642  }
643  }
644 
645 
651  public function getLinesArray()
652  {
653  return $this->fetch_lines();
654  }
655 
656 
657  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
663  public function fetch_lines()
664  {
665  // phpcs:enable
666 
667  $this->lines = array();
668 
669  // Retrieve all extrafield for line
670  // fetch optionals attributes and labels
671  /*if (!is_object($extrafields)) {
672  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
673  $extrafields = new ExtraFields($this->db);
674  }
675  $extrafields->fetch_name_optionals_label($this->table_element_line, true);
676  */
677 
678  dol_syslog('FactureRec::fetch_lines', LOG_DEBUG);
679 
680  $sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx, ';
681  $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise, l.remise_percent, l.subprice,';
682  $sql .= ' l.info_bits, l.date_start_fill, l.date_end_fill, l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price, l.buy_price_ht as pa_ht,';
683  $sql .= ' l.rang, l.special_code,';
684  $sql .= ' l.fk_unit, l.fk_contract_line,';
685  $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
686  $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
687  $sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet_rec as l';
688  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
689  $sql .= ' WHERE l.fk_facture = '.((int) $this->id);
690  $sql .= ' ORDER BY l.rang';
691 
692  $result = $this->db->query($sql);
693  if ($result) {
694  $num = $this->db->num_rows($result);
695  $i = 0;
696  while ($i < $num) {
697  $objp = $this->db->fetch_object($result);
698  $line = new FactureLigneRec($this->db);
699 
700  $line->id = $objp->rowid;
701  $line->rowid = $objp->rowid;
702  $line->desc = $objp->description; // Description line
703  $line->description = $objp->description; // Description line
704  $line->ref = $objp->product_ref; // Ref product
705  $line->product_ref = $objp->product_ref; // Ref product
706  $line->libelle = $objp->product_label; // deprecated
707  $line->product_label = $objp->product_label; // Label product
708  $line->product_desc = $objp->product_desc; // Description product
709  $line->product_type = $objp->product_type; // Type of line
710  $line->fk_product_type = $objp->fk_product_type; // Type of product
711  $line->qty = $objp->qty;
712  $line->subprice = $objp->subprice;
713 
714  $line->label = $objp->custom_label; // @deprecated
715 
716  $line->vat_src_code = $objp->vat_src_code;
717  $line->tva_tx = $objp->tva_tx;
718  $line->localtax1_tx = $objp->localtax1_tx;
719  $line->localtax2_tx = $objp->localtax2_tx;
720  $line->localtax1_type = $objp->localtax1_type;
721  $line->localtax2_type = $objp->localtax2_type;
722  $line->remise_percent = $objp->remise_percent;
723  //$line->fk_remise_except = $objp->fk_remise_except;
724  $line->fk_product = $objp->fk_product;
725  $line->date_start_fill = $objp->date_start_fill;
726  $line->date_end_fill = $objp->date_end_fill;
727  $line->info_bits = $objp->info_bits;
728  $line->total_ht = $objp->total_ht;
729  $line->total_tva = $objp->total_tva;
730  $line->total_ttc = $objp->total_ttc;
731 
732  //$line->code_ventilation = $objp->fk_code_ventilation;
733 
734  $line->fk_product_fournisseur_price = $objp->fk_product_fournisseur_price;
735  $line->fk_fournprice = $objp->fk_product_fournisseur_price; // For backward compatibility
736 
737  $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $objp->fk_product_fournisseur_price, $objp->pa_ht);
738 
739  $line->buyprice = $marginInfos[0];
740  $line->pa_ht = $marginInfos[0]; // For backward compatibility
741  $line->marge_tx = $marginInfos[1];
742  $line->marque_tx = $marginInfos[2];
743  $line->rang = $objp->rang;
744  $line->special_code = $objp->special_code;
745  $line->fk_unit = $objp->fk_unit;
746  $line->fk_contract_line = $objp->fk_contract_line;
747 
748  // Ne plus utiliser
749  $line->price = $objp->price;
750  $line->remise = $objp->remise;
751 
752  $line->fetch_optionals();
753 
754  // Multicurrency
755  $line->fk_multicurrency = $objp->fk_multicurrency;
756  $line->multicurrency_code = $objp->multicurrency_code;
757  $line->multicurrency_subprice = $objp->multicurrency_subprice;
758  $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
759  $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
760  $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
761 
762  $this->lines[$i] = $line;
763 
764  $i++;
765  }
766 
767  $this->db->free($result);
768  return 1;
769  } else {
770  $this->error = $this->db->lasterror();
771  return -3;
772  }
773  }
774 
775 
784  public function delete(User $user, $notrigger = 0, $idwarehouse = -1)
785  {
786  $rowid = $this->id;
787 
788  dol_syslog(get_class($this)."::delete rowid=".((int) $rowid), LOG_DEBUG);
789 
790  $error = 0;
791  $this->db->begin();
792 
793  $main = MAIN_DB_PREFIX.'facturedet_rec';
794  $ef = $main."_extrafields";
795 
796  $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM ".$main." WHERE fk_facture = ".((int) $rowid).")";
797  $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet_rec WHERE fk_facture = ".((int) $rowid);
798 
799  if ($this->db->query($sqlef) && $this->db->query($sql)) {
800  $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_rec WHERE rowid = ".((int) $rowid);
801  dol_syslog($sql);
802  if ($this->db->query($sql)) {
803  // Delete linked object
804  $res = $this->deleteObjectLinked();
805  if ($res < 0) {
806  $error = -3;
807  }
808  // Delete extrafields
809  $res = $this->deleteExtraFields();
810  if ($res < 0) {
811  $error = -4;
812  }
813  } else {
814  $this->error = $this->db->lasterror();
815  $error = -1;
816  }
817  } else {
818  $this->error = $this->db->lasterror();
819  $error = -2;
820  }
821  if (!$error && !$notrigger) {
822  // Call trigger
823  $result = $this->call_trigger('BILLREC_DELETE', $user);
824  if ($result < 0) {
825  $error++;
826  }
827  // End call triggers
828  }
829  if (!$error) {
830  $this->db->commit();
831  return 1;
832  } else {
833  $this->db->rollback();
834  return $error;
835  }
836  }
837 
838 
866  public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $price_base_type = 'HT', $info_bits = 0, $fk_remise_except = '', $pu_ttc = 0, $type = 0, $rang = -1, $special_code = 0, $label = '', $fk_unit = null, $pu_ht_devise = 0, $date_start_fill = 0, $date_end_fill = 0, $fk_fournprice = null, $pa_ht = 0)
867  {
868  global $mysoc;
869 
870  $facid = $this->id;
871 
872  dol_syslog(get_class($this)."::addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,txlocaltax1=$txlocaltax1,txlocaltax2=$txlocaltax2,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit,pu_ht_devise=$pu_ht_devise,date_start_fill=$date_start_fill,date_end_fill=$date_end_fill,pa_ht=$pa_ht", LOG_DEBUG);
873  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
874 
875  // Check parameters
876  if ($type < 0) {
877  return -1;
878  }
879 
880  $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
881 
882  // Clean vat code
883  $reg = array();
884  $vat_src_code = '';
885  if (preg_match('/\((.*)\)/', $txtva, $reg)) {
886  $vat_src_code = $reg[1];
887  $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate.
888  }
889 
890  if ($this->brouillon) {
891  // Clean parameters
892  $remise_percent = price2num($remise_percent);
893  if (empty($remise_percent)) {
894  $remise_percent = 0;
895  }
896  $qty = price2num($qty);
897  $pu_ht = price2num($pu_ht);
898  $pu_ttc = price2num($pu_ttc);
899  if (!preg_match('/\((.*)\)/', $txtva)) {
900  $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
901  }
902  $txlocaltax1 = price2num($txlocaltax1);
903  $txlocaltax2 = price2num($txlocaltax2);
904  if (empty($txtva)) {
905  $txtva = 0;
906  }
907  if (empty($txlocaltax1)) {
908  $txlocaltax1 = 0;
909  }
910  if (empty($txlocaltax2)) {
911  $txlocaltax2 = 0;
912  }
913  if (empty($info_bits)) {
914  $info_bits = 0;
915  }
916 
917  if ($price_base_type == 'HT') {
918  $pu = $pu_ht;
919  } else {
920  $pu = $pu_ttc;
921  }
922 
923  // Calcul du total TTC et de la TVA pour la ligne a partir de
924  // qty, pu, remise_percent et txtva
925  // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
926  // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
927 
928  $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
929  $total_ht = $tabprice[0];
930  $total_tva = $tabprice[1];
931  $total_ttc = $tabprice[2];
932  $total_localtax1 = $tabprice[9];
933  $total_localtax2 = $tabprice[10];
934  $pu_ht = $tabprice[3];
935 
936  // MultiCurrency
937  $multicurrency_total_ht = $tabprice[16];
938  $multicurrency_total_tva = $tabprice[17];
939  $multicurrency_total_ttc = $tabprice[18];
940  $pu_ht_devise = $tabprice[19];
941 
942  $product_type = $type;
943  if ($fk_product) {
944  $product = new Product($this->db);
945  $result = $product->fetch($fk_product);
946  $product_type = $product->type;
947  }
948 
949  // Rank to use
950  $ranktouse = $rang;
951  if ($ranktouse == -1) {
952  $rangmax = $this->line_max(0);
953  $ranktouse = $rangmax + 1;
954  }
955 
956  $sql = "INSERT INTO ".MAIN_DB_PREFIX."facturedet_rec (";
957  $sql .= "fk_facture";
958  $sql .= ", label";
959  $sql .= ", description";
960  $sql .= ", price";
961  $sql .= ", qty";
962  $sql .= ", tva_tx";
963  $sql .= ", vat_src_code";
964  $sql .= ", localtax1_tx";
965  $sql .= ", localtax1_type";
966  $sql .= ", localtax2_tx";
967  $sql .= ", localtax2_type";
968  $sql .= ", fk_product";
969  $sql .= ", product_type";
970  $sql .= ", remise_percent";
971  $sql .= ", subprice";
972  $sql .= ", remise";
973  $sql .= ", total_ht";
974  $sql .= ", total_tva";
975  $sql .= ", total_localtax1";
976  $sql .= ", total_localtax2";
977  $sql .= ", total_ttc";
978  $sql .= ", date_start_fill";
979  $sql .= ", date_end_fill";
980  $sql .= ", fk_product_fournisseur_price";
981  $sql .= ", buy_price_ht";
982  $sql .= ", info_bits";
983  $sql .= ", rang";
984  $sql .= ", special_code";
985  $sql .= ", fk_unit";
986  $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
987  $sql .= ") VALUES (";
988  $sql .= " ".((int) $facid);
989  $sql .= ", ".(!empty($label) ? "'".$this->db->escape($label)."'" : "null");
990  $sql .= ", '".$this->db->escape($desc)."'";
991  $sql .= ", ".price2num($pu_ht);
992  $sql .= ", ".price2num($qty);
993  $sql .= ", ".price2num($txtva);
994  $sql .= ", '".$this->db->escape($vat_src_code)."'";
995  $sql .= ", ".price2num($txlocaltax1);
996  $sql .= ", '".$this->db->escape(isset($localtaxes_type[0]) ? $localtaxes_type[0] : '')."'";
997  $sql .= ", ".price2num($txlocaltax2);
998  $sql .= ", '".$this->db->escape(isset($localtaxes_type[2]) ? $localtaxes_type[2] : '')."'";
999  $sql .= ", ".(!empty($fk_product) ? "'".$this->db->escape($fk_product)."'" : "null");
1000  $sql .= ", ".((int) $product_type);
1001  $sql .= ", ".price2num($remise_percent);
1002  $sql .= ", ".price2num($pu_ht);
1003  $sql .= ", null";
1004  $sql .= ", ".price2num($total_ht);
1005  $sql .= ", ".price2num($total_tva);
1006  $sql .= ", ".price2num($total_localtax1);
1007  $sql .= ", ".price2num($total_localtax2);
1008  $sql .= ", ".price2num($total_ttc);
1009  $sql .= ", ".(int) $date_start_fill;
1010  $sql .= ", ".(int) $date_end_fill;
1011  $sql .= ", ".($fk_fournprice > 0 ? $fk_fournprice : 'null');
1012  $sql .= ", ".($pa_ht ? price2num($pa_ht) : 0);
1013  $sql .= ", ".((int) $info_bits);
1014  $sql .= ", ".((int) $ranktouse);
1015  $sql .= ", ".((int) $special_code);
1016  $sql .= ", ".($fk_unit ? ((int) $fk_unit) : "null");
1017  $sql .= ", ".(int) $this->fk_multicurrency;
1018  $sql .= ", '".$this->db->escape($this->multicurrency_code)."'";
1019  $sql .= ", ".price2num($pu_ht_devise, 'CU');
1020  $sql .= ", ".price2num($multicurrency_total_ht, 'CT');
1021  $sql .= ", ".price2num($multicurrency_total_tva, 'CT');
1022  $sql .= ", ".price2num($multicurrency_total_ttc, 'CT');
1023  $sql .= ")";
1024 
1025  dol_syslog(get_class($this)."::addline", LOG_DEBUG);
1026  if ($this->db->query($sql)) {
1027  $lineId = $this->db->last_insert_id(MAIN_DB_PREFIX."facturedet_rec");
1028  $this->id = $facid;
1029  $this->update_price();
1030  return $lineId;
1031  } else {
1032  $this->error = $this->db->lasterror();
1033  return -1;
1034  }
1035  }
1036  }
1037 
1067  public function updateline($rowid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $price_base_type = 'HT', $info_bits = 0, $fk_remise_except = '', $pu_ttc = 0, $type = 0, $rang = -1, $special_code = 0, $label = '', $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $date_start_fill = 0, $date_end_fill = 0, $fk_fournprice = null, $pa_ht = 0)
1068  {
1069  global $mysoc;
1070 
1071  $facid = $this->id;
1072 
1073  dol_syslog(get_class($this)."::updateline facid=".$facid." rowid=$rowid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, type=$type, fk_unit=$fk_unit, pu_ht_devise=$pu_ht_devise", LOG_DEBUG);
1074  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
1075 
1076  // Clean parameters
1077  if (empty($remise_percent)) {
1078  $remise_percent = 0;
1079  }
1080 
1081  // Check parameters
1082  if ($type < 0) {
1083  return -1;
1084  }
1085 
1086  if ($this->brouillon) {
1087  // Clean parameters
1088  $remise_percent = price2num($remise_percent);
1089  $qty = price2num($qty);
1090  if (empty($info_bits)) {
1091  $info_bits = 0;
1092  }
1093  $pu_ht = price2num($pu_ht);
1094  $pu_ttc = price2num($pu_ttc);
1095  $pu_ht_devise = price2num($pu_ht_devise);
1096  if (!preg_match('/\((.*)\)/', $txtva)) {
1097  $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
1098  }
1099  $txlocaltax1 = price2num($txlocaltax1);
1100  $txlocaltax2 = price2num($txlocaltax2);
1101  if (empty($txlocaltax1)) {
1102  $txlocaltax1 = 0;
1103  }
1104  if (empty($txlocaltax2)) {
1105  $txlocaltax2 = 0;
1106  }
1107 
1108  if (empty($this->multicurrency_subprice)) {
1109  $this->multicurrency_subprice = 0;
1110  }
1111  if (empty($this->multicurrency_total_ht)) {
1112  $this->multicurrency_total_ht = 0;
1113  }
1114  if (empty($this->multicurrency_total_tva)) {
1115  $this->multicurrency_total_tva = 0;
1116  }
1117  if (empty($this->multicurrency_total_ttc)) {
1118  $this->multicurrency_total_ttc = 0;
1119  }
1120 
1121  if ($price_base_type == 'HT') {
1122  $pu = $pu_ht;
1123  } else {
1124  $pu = $pu_ttc;
1125  }
1126 
1127  // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
1128  // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1129  // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1130 
1131  $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
1132 
1133  // Clean vat code
1134  $vat_src_code = '';
1135  $reg = array();
1136  if (preg_match('/\((.*)\)/', $txtva, $reg)) {
1137  $vat_src_code = $reg[1];
1138  $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate.
1139  }
1140 
1141  $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
1142 
1143  $total_ht = $tabprice[0];
1144  $total_tva = $tabprice[1];
1145  $total_ttc = $tabprice[2];
1146  $total_localtax1 = $tabprice[9];
1147  $total_localtax2 = $tabprice[10];
1148  $pu_ht = $tabprice[3];
1149  $pu_tva = $tabprice[4];
1150  $pu_ttc = $tabprice[5];
1151 
1152  // MultiCurrency
1153  $multicurrency_total_ht = $tabprice[16];
1154  $multicurrency_total_tva = $tabprice[17];
1155  $multicurrency_total_ttc = $tabprice[18];
1156  $pu_ht_devise = $tabprice[19];
1157 
1158  $product_type = $type;
1159  if ($fk_product) {
1160  $product = new Product($this->db);
1161  $result = $product->fetch($fk_product);
1162  $product_type = $product->type;
1163  }
1164 
1165  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET ";
1166  $sql .= "fk_facture = ".((int) $facid);
1167  $sql .= ", label=".(!empty($label) ? "'".$this->db->escape($label)."'" : "null");
1168  $sql .= ", description='".$this->db->escape($desc)."'";
1169  $sql .= ", price=".price2num($pu_ht);
1170  $sql .= ", qty=".price2num($qty);
1171  $sql .= ", tva_tx=".price2num($txtva);
1172  $sql .= ", vat_src_code='".$this->db->escape($vat_src_code)."'";
1173  $sql .= ", localtax1_tx=".((float) $txlocaltax1);
1174  $sql .= ", localtax1_type='".$this->db->escape($localtaxes_type[0])."'";
1175  $sql .= ", localtax2_tx=".((float) $txlocaltax2);
1176  $sql .= ", localtax2_type='".$this->db->escape($localtaxes_type[2])."'";
1177  $sql .= ", fk_product=".(!empty($fk_product) ? "'".$this->db->escape($fk_product)."'" : "null");
1178  $sql .= ", product_type=".((int) $product_type);
1179  $sql .= ", remise_percent='".price2num($remise_percent)."'";
1180  $sql .= ", subprice='".price2num($pu_ht)."'";
1181  $sql .= ", total_ht='".price2num($total_ht)."'";
1182  $sql .= ", total_tva='".price2num($total_tva)."'";
1183  $sql .= ", total_localtax1='".price2num($total_localtax1)."'";
1184  $sql .= ", total_localtax2='".price2num($total_localtax2)."'";
1185  $sql .= ", total_ttc='".price2num($total_ttc)."'";
1186  $sql .= ", date_start_fill=".((int) $date_start_fill);
1187  $sql .= ", date_end_fill=".((int) $date_end_fill);
1188  $sql .= ", fk_product_fournisseur_price=".($fk_fournprice > 0 ? $fk_fournprice : 'null');
1189  $sql .= ", buy_price_ht=".($pa_ht ? price2num($pa_ht) : 0);
1190  $sql .= ", info_bits=".((int) $info_bits);
1191  $sql .= ", rang=".((int) $rang);
1192  $sql .= ", special_code=".((int) $special_code);
1193  $sql .= ", fk_unit=".($fk_unit ? "'".$this->db->escape($fk_unit)."'" : "null");
1194  $sql .= ', multicurrency_subprice = '.price2num($pu_ht_devise);
1195  $sql .= ', multicurrency_total_ht = '.price2num($multicurrency_total_ht);
1196  $sql .= ', multicurrency_total_tva = '.price2num($multicurrency_total_tva);
1197  $sql .= ', multicurrency_total_ttc = '.price2num($multicurrency_total_ttc);
1198  $sql .= " WHERE rowid = ".((int) $rowid);
1199 
1200  dol_syslog(get_class($this)."::updateline", LOG_DEBUG);
1201  if ($this->db->query($sql)) {
1202  $this->id = $facid;
1203  $this->update_price();
1204  return 1;
1205  } else {
1206  $this->error = $this->db->lasterror();
1207  return -1;
1208  }
1209  }
1210  }
1211 
1212 
1218  public function getNextDate()
1219  {
1220  if (empty($this->date_when)) {
1221  return false;
1222  }
1223  return dol_time_plus_duree($this->date_when, $this->frequency, $this->unit_frequency);
1224  }
1225 
1231  public function isMaxNbGenReached()
1232  {
1233  $ret = false;
1234  if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) {
1235  $ret = true;
1236  }
1237  return $ret;
1238  }
1239 
1246  public function strikeIfMaxNbGenReached($ret)
1247  {
1248  // Special case to strike the date
1249  return ($this->isMaxNbGenReached() ? '<strike>' : '').$ret.($this->isMaxNbGenReached() ? '</strike>' : '');
1250  }
1251 
1263  public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0, $notrigger = 0)
1264  {
1265  global $conf, $langs, $db, $user, $hookmanager;
1266 
1267  $error = 0;
1268  $nb_create = 0;
1269 
1270  // Load translation files required by the page
1271  $langs->loadLangs(array("main", "bills"));
1272 
1273  $now = dol_now();
1274  $tmparray = dol_getdate($now);
1275  $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
1276 
1277  dol_syslog("createRecurringInvoices restrictioninvoiceid=".$restrictioninvoiceid." forcevalidation=".$forcevalidation);
1278 
1279  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_rec';
1280  $sql .= ' WHERE frequency > 0'; // A recurring invoice is an invoice with a frequency
1281  $sql .= " AND (date_when IS NULL OR date_when <= '".$this->db->idate($today)."')";
1282  $sql .= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)';
1283  $sql .= ' AND suspended = 0';
1284  $sql .= ' AND entity = '.$conf->entity; // MUST STAY = $conf->entity here
1285  if ($restrictioninvoiceid > 0) {
1286  $sql .= ' AND rowid = '.((int) $restrictioninvoiceid);
1287  }
1288  $sql .= $this->db->order('entity', 'ASC');
1289  //print $sql;exit;
1290  $parameters = array(
1291  'restrictioninvoiceid' => $restrictioninvoiceid,
1292  'forcevalidation' => $forcevalidation,
1293  );
1294  $reshook = $hookmanager->executeHooks('beforeCreationOfRecurringInvoices', $parameters, $sql); // note that $sql might be modified by hooks
1295 
1296  $resql = $this->db->query($sql);
1297  if ($resql) {
1298  $i = 0;
1299  $num = $this->db->num_rows($resql);
1300 
1301  if ($num) {
1302  $this->output .= $langs->trans("FoundXQualifiedRecurringInvoiceTemplate", $num)."\n";
1303  } else {
1304  $this->output .= $langs->trans("NoQualifiedRecurringInvoiceTemplateFound");
1305  }
1306 
1307  $saventity = $conf->entity;
1308 
1309  while ($i < $num) { // Loop on each template invoice. If $num = 0, test is false at first pass.
1310  $line = $this->db->fetch_object($resql);
1311 
1312  $this->db->begin();
1313 
1314  $invoiceidgenerated = 0;
1315 
1316  $facture = null;
1317  $facturerec = new FactureRec($this->db);
1318  $facturerec->fetch($line->rowid);
1319 
1320  if ($facturerec->id > 0) {
1321  // Set entity context
1322  $conf->entity = $facturerec->entity;
1323 
1324  dol_syslog("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref.", entity=".$facturerec->entity);
1325 
1326  $facture = new Facture($this->db);
1327  $facture->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice
1328  $facture->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice
1329 
1330  $facture->type = self::TYPE_STANDARD;
1331  $facture->brouillon = 1;
1332  $facture->statut = self::STATUS_DRAFT;
1333  $facture->status = self::STATUS_DRAFT;
1334  $facture->date = (empty($facturerec->date_when) ? $now : $facturerec->date_when); // We could also use dol_now here but we prefer date_when so invoice has real date when we would like even if we generate later.
1335  $facture->socid = $facturerec->socid;
1336  if (!empty($facturerec->fk_multicurrency)) {
1337  $facture->fk_multicurrency = $facturerec->fk_multicurrency;
1338  $facture->multicurrency_code = $facturerec->multicurrency_code;
1339  $facture->multicurrency_tx = $facturerec->multicurrency_tx;
1340  }
1341 
1342  $invoiceidgenerated = $facture->create($user);
1343  if ($invoiceidgenerated <= 0) {
1344  $this->errors = $facture->errors;
1345  $this->error = $facture->error;
1346  $error++;
1347  }
1348 
1349 
1350  if (!$error && ($facturerec->auto_validate || $forcevalidation)) {
1351  $result = $facture->validate($user);
1352  if ($result <= 0) {
1353  $this->errors = $facture->errors;
1354  $this->error = $facture->error;
1355  $error++;
1356  }
1357  }
1358  if (!$error && $facturerec->generate_pdf) {
1359  // We refresh the object in order to have all necessary data (like date_lim_reglement)
1360  $facture->fetch($facture->id);
1361  $result = $facture->generateDocument($facturerec->model_pdf, $langs);
1362  if ($result <= 0) {
1363  $this->errors = $facture->errors;
1364  $this->error = $facture->error;
1365  $error++;
1366  }
1367  }
1368  if (!$error && !$notrigger) {
1369  // Call trigger
1370  $result = $facturerec->call_trigger('BILLREC_CREATEBILL', $user);
1371  if ($result < 0) {
1372  $this->errors = $facturerec->errors;
1373  $this->error = $facturerec->error;
1374  $error++;
1375  }
1376  // End call triggers
1377  }
1378  } else {
1379  $error++;
1380  $this->error = "Failed to load invoice template with id=".$line->rowid.", entity=".$conf->entity."\n";
1381  $this->errors[] = "Failed to load invoice template with id=".$line->rowid.", entity=".$conf->entity;
1382  dol_syslog("createRecurringInvoices Failed to load invoice template with id=".$line->rowid.", entity=".$conf->entity);
1383  }
1384 
1385  if (!$error && $invoiceidgenerated >= 0) {
1386  $this->db->commit("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref);
1387  dol_syslog("createRecurringInvoices Process invoice template ".$facturerec->ref." is finished with a success generation");
1388  $nb_create++;
1389  $this->output .= $langs->trans("InvoiceGeneratedFromTemplate", $facture->ref, $facturerec->ref)."\n";
1390  } else {
1391  $this->db->rollback("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref);
1392  }
1393 
1394  $parameters = array(
1395  'cpt' => $i,
1396  'total' => $num,
1397  'errorCount' => $error,
1398  'invoiceidgenerated' => $invoiceidgenerated,
1399  'facturerec' => $facturerec, // it's an object which PHP passes by "reference", so modifiable by hooks.
1400  'this' => $this, // it's an object which PHP passes by "reference", so modifiable by hooks.
1401  );
1402  $reshook = $hookmanager->executeHooks('afterCreationOfRecurringInvoice', $parameters, $facture); // note: $facture can be modified by hooks (warning: $facture can be null)
1403 
1404  $i++;
1405  }
1406 
1407  $conf->entity = $saventity; // Restore entity context
1408  } else {
1409  dol_print_error($this->db);
1410  }
1411 
1412  $this->output = trim($this->output);
1413 
1414  return $error ? $error : 0;
1415  }
1416 
1429  public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = '', $save_lastsearch_value = -1)
1430  {
1431  global $langs, $hookmanager;
1432 
1433  $result = '';
1434 
1435  $label = '<u>'.$langs->trans("RepeatableInvoice").'</u>';
1436  if (!empty($this->ref)) {
1437  $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1438  }
1439  if ($this->frequency > 0) {
1440  $label .= '<br><b>'.$langs->trans('Frequency').':</b> '.$langs->trans('FrequencyPer_'.$this->unit_frequency, $this->frequency);
1441  }
1442  if (!empty($this->date_last_gen)) {
1443  $label .= '<br><b>'.$langs->trans('DateLastGeneration').':</b> '.dol_print_date($this->date_last_gen, 'dayhour');
1444  }
1445  if ($this->frequency > 0) {
1446  if (!empty($this->date_when)) {
1447  $label .= '<br><b>'.$langs->trans('NextDateToExecution').':</b> ';
1448  $label .= (empty($this->suspended) ? '' : '<strike>').dol_print_date($this->date_when, 'day').(empty($this->suspended) ? '' : '</strike>'); // No hour for this property
1449  if (!empty($this->suspended)) {
1450  $label .= ' ('.$langs->trans("Disabled").')';
1451  }
1452  }
1453  }
1454 
1455  $url = DOL_URL_ROOT.'/compta/facture/card-rec.php?facid='.$this->id;
1456 
1457  if ($short) {
1458  return $url;
1459  }
1460 
1461  if ($option != 'nolink') {
1462  // Add param to save lastsearch_values or not
1463  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1464  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1465  $add_save_lastsearch_values = 1;
1466  }
1467  if ($add_save_lastsearch_values) {
1468  $url .= '&save_lastsearch_values=1';
1469  }
1470  }
1471 
1472  $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
1473  $linkend = '</a>';
1474 
1475  $result .= $linkstart;
1476  if ($withpicto) {
1477  $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);
1478  }
1479  if ($withpicto != 2) {
1480  $result .= $this->ref;
1481  }
1482  $result .= $linkend;
1483  global $action;
1484  $hookmanager->initHooks(array($this->element . 'dao'));
1485  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1486  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1487  if ($reshook > 0) {
1488  $result = $hookmanager->resPrint;
1489  } else {
1490  $result .= $hookmanager->resPrint;
1491  }
1492  return $result;
1493  }
1494 
1502  public function getLibStatut($mode = 0, $alreadypaid = -1)
1503  {
1504  return $this->LibStatut($this->frequency ? 1 : 0, $this->suspended, $mode, $alreadypaid, empty($this->type) ? 0 : $this->type);
1505  }
1506 
1507  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1518  public function LibStatut($recur, $status, $mode = 0, $alreadypaid = -1, $type = 0)
1519  {
1520  // phpcs:enable
1521  global $langs;
1522  $langs->load('bills');
1523 
1524  $labelStatus = $langs->transnoentitiesnoconv('Active');
1525  $statusType = 'status0';
1526 
1527  //print "$recur,$status,$mode,$alreadypaid,$type";
1528  if ($mode == 0) {
1529  if ($recur) {
1530  if ($status == self::STATUS_SUSPENDED) {
1531  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1532  } else {
1533  $labelStatus = $langs->transnoentitiesnoconv('Active');
1534  }
1535  } else {
1536  if ($status == self::STATUS_SUSPENDED) {
1537  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1538  } else {
1539  $labelStatus = $langs->transnoentitiesnoconv("Draft");
1540  }
1541  }
1542  } elseif ($mode == 1) {
1543  $prefix = 'Short';
1544  if ($recur) {
1545  if ($status == self::STATUS_SUSPENDED) {
1546  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1547  } else {
1548  $labelStatus = $langs->transnoentitiesnoconv('Active');
1549  }
1550  } else {
1551  if ($status == self::STATUS_SUSPENDED) {
1552  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1553  } else {
1554  $labelStatus = $langs->transnoentitiesnoconv("Draft");
1555  }
1556  }
1557  } elseif ($mode == 2) {
1558  if ($recur) {
1559  if ($status == self::STATUS_SUSPENDED) {
1560  $statusType = 'status6';
1561  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1562  } else {
1563  $statusType = 'status4';
1564  $labelStatus = $langs->transnoentitiesnoconv('Active');
1565  }
1566  } else {
1567  if ($status == self::STATUS_SUSPENDED) {
1568  $statusType = 'status6';
1569  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1570  } else {
1571  $statusType = 'status0';
1572  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1573  }
1574  }
1575  } elseif ($mode == 3) {
1576  if ($recur) {
1577  $prefix = 'Short';
1578  if ($status == self::STATUS_SUSPENDED) {
1579  $statusType = 'status6';
1580  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1581  } else {
1582  $statusType = 'status4';
1583  $labelStatus = $langs->transnoentitiesnoconv('Active');
1584  }
1585  } else {
1586  if ($status == self::STATUS_SUSPENDED) {
1587  $statusType = 'status6';
1588  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1589  } else {
1590  $statusType = 'status0';
1591  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1592  }
1593  }
1594  } elseif ($mode == 4) {
1595  $prefix = '';
1596  if ($recur) {
1597  if ($status == self::STATUS_SUSPENDED) {
1598  $statusType = 'status6';
1599  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1600  } else {
1601  $statusType = 'status4';
1602  $labelStatus = $langs->transnoentitiesnoconv('Active');
1603  }
1604  } else {
1605  if ($status == self::STATUS_SUSPENDED) {
1606  $statusType = 'status6';
1607  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1608  } else {
1609  $statusType = 'status0';
1610  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1611  }
1612  }
1613  } elseif ($mode == 5 || $mode == 6) {
1614  $prefix = '';
1615  if ($mode == 5) {
1616  $prefix = 'Short';
1617  }
1618  if ($recur) {
1619  if ($status == self::STATUS_SUSPENDED) {
1620  $statusType = 'status6';
1621  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1622  } else {
1623  $statusType = 'status4';
1624  $labelStatus = $langs->transnoentitiesnoconv('Active');
1625  }
1626  } else {
1627  if ($status == self::STATUS_SUSPENDED) {
1628  $statusType = 'status6';
1629  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1630  } else {
1631  $statusType = 'status0';
1632  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1633  }
1634  }
1635  }
1636 
1637  $labelStatusShort = $labelStatus;
1638 
1639  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1640  }
1641 
1650  public function initAsSpecimen($option = '')
1651  {
1652  global $user, $langs, $conf;
1653 
1654  $now = dol_now();
1655  $arraynow = dol_getdate($now);
1656  $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1657 
1658  // Load array of products prodids
1659  $num_prods = 0;
1660  $prodids = array();
1661 
1662  $sql = "SELECT rowid";
1663  $sql .= " FROM ".MAIN_DB_PREFIX."product";
1664  $sql .= " WHERE entity IN (".getEntity('product').")";
1665  $sql .= $this->db->plimit(100);
1666 
1667  $resql = $this->db->query($sql);
1668  if ($resql) {
1669  $num_prods = $this->db->num_rows($resql);
1670  $i = 0;
1671  while ($i < $num_prods) {
1672  $i++;
1673  $row = $this->db->fetch_row($resql);
1674  $prodids[$i] = $row[0];
1675  }
1676  }
1677 
1678  // Initialize parameters
1679  $this->id = 0;
1680  $this->ref = 'SPECIMEN';
1681  $this->title = 'SPECIMEN';
1682  $this->specimen = 1;
1683  $this->socid = 1;
1684  $this->date = $nownotime;
1685  $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
1686  $this->cond_reglement_id = 1;
1687  $this->cond_reglement_code = 'RECEP';
1688  $this->date_lim_reglement = $this->calculate_date_lim_reglement();
1689  $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR
1690  $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
1691  $this->note_public = 'This is a comment (public)';
1692  $this->note_private = 'This is a comment (private)';
1693  $this->note = 'This is a comment (private)';
1694  $this->fk_incoterms = 0;
1695  $this->location_incoterms = '';
1696 
1697  if (empty($option) || $option != 'nolines') {
1698  // Lines
1699  $nbp = 5;
1700  $xnbp = 0;
1701  while ($xnbp < $nbp) {
1702  $line = new FactureLigne($this->db);
1703  $line->desc = $langs->trans("Description")." ".$xnbp;
1704  $line->qty = 1;
1705  $line->subprice = 100;
1706  $line->tva_tx = 19.6;
1707  $line->localtax1_tx = 0;
1708  $line->localtax2_tx = 0;
1709  $line->remise_percent = 0;
1710  if ($xnbp == 1) { // Qty is negative (product line)
1711  $prodid = mt_rand(1, $num_prods);
1712  $line->fk_product = $prodids[$prodid];
1713  $line->qty = -1;
1714  $line->total_ht = -100;
1715  $line->total_ttc = -119.6;
1716  $line->total_tva = -19.6;
1717  } elseif ($xnbp == 2) { // UP is negative (free line)
1718  $line->subprice = -100;
1719  $line->total_ht = -100;
1720  $line->total_ttc = -119.6;
1721  $line->total_tva = -19.6;
1722  $line->remise_percent = 0;
1723  } elseif ($xnbp == 3) { // Discount is 50% (product line)
1724  $prodid = mt_rand(1, $num_prods);
1725  $line->fk_product = $prodids[$prodid];
1726  $line->total_ht = 50;
1727  $line->total_ttc = 59.8;
1728  $line->total_tva = 9.8;
1729  $line->remise_percent = 50;
1730  } else // (product line)
1731  {
1732  $prodid = mt_rand(1, $num_prods);
1733  $line->fk_product = $prodids[$prodid];
1734  $line->total_ht = 100;
1735  $line->total_ttc = 119.6;
1736  $line->total_tva = 19.6;
1737  $line->remise_percent = 00;
1738  }
1739 
1740  $this->lines[$xnbp] = $line;
1741  $xnbp++;
1742 
1743  $this->total_ht += $line->total_ht;
1744  $this->total_tva += $line->total_tva;
1745  $this->total_ttc += $line->total_ttc;
1746  }
1747  $this->revenuestamp = 0;
1748 
1749  // Add a line "offered"
1750  $line = new FactureLigne($this->db);
1751  $line->desc = $langs->trans("Description")." (offered line)";
1752  $line->qty = 1;
1753  $line->subprice = 100;
1754  $line->tva_tx = 19.6;
1755  $line->localtax1_tx = 0;
1756  $line->localtax2_tx = 0;
1757  $line->remise_percent = 100;
1758  $line->total_ht = 0;
1759  $line->total_ttc = 0; // 90 * 1.196
1760  $line->total_tva = 0;
1761  $prodid = mt_rand(1, $num_prods);
1762  $line->fk_product = $prodids[$prodid];
1763 
1764  $this->lines[$xnbp] = $line;
1765  $xnbp++;
1766  }
1767 
1768  $this->usenewprice = 0;
1769  }
1770 
1779  public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
1780  {
1781  $tables = array(
1782  'facture_rec'
1783  );
1784 
1785  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
1786  }
1787 
1796  public static function replaceProduct(DoliDB $db, $origin_id, $dest_id)
1797  {
1798  $tables = array(
1799  'facturedet_rec'
1800  );
1801 
1802  return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables);
1803  }
1804 
1813  public function setFrequencyAndUnit($frequency, $unit, $notrigger = 0)
1814  {
1815  global $user;
1816 
1817  if (!$this->table_element) {
1818  dol_syslog(get_class($this)."::setFrequencyAndUnit was called on objet with property table_element not defined", LOG_ERR);
1819  return -1;
1820  }
1821 
1822  if (!empty($frequency) && empty($unit)) {
1823  dol_syslog(get_class($this)."::setFrequencyAndUnit was called on objet with params frequency defined but unit not defined", LOG_ERR);
1824  return -2;
1825  }
1826 
1827  $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1828  $sql .= ' SET frequency = '.($frequency ? $this->db->escape($frequency) : 'null');
1829  if (!empty($unit)) {
1830  $sql .= ', unit_frequency = \''.$this->db->escape($unit).'\'';
1831  }
1832  $sql .= " WHERE rowid = ".((int) $this->id);
1833 
1834  dol_syslog(get_class($this)."::setFrequencyAndUnit", LOG_DEBUG);
1835  if ($this->db->query($sql)) {
1836  $this->frequency = $frequency;
1837  if (!empty($unit)) {
1838  $this->unit_frequency = $unit;
1839  }
1840 
1841  if (!$notrigger) {
1842  // Call trigger
1843  $result = $this->call_trigger('BILLREC_MODIFY', $user);
1844  if ($result < 0) {
1845  return $result;
1846  }
1847  // End call triggers
1848  }
1849 
1850  return 1;
1851  } else {
1852  dol_print_error($this->db);
1853  return -1;
1854  }
1855  }
1856 
1865  public function setNextDate($date, $increment_nb_gen_done = 0, $notrigger = 0)
1866  {
1867 
1868  global $user;
1869 
1870  if (!$this->table_element) {
1871  dol_syslog(get_class($this)."::setNextDate was called on objet with property table_element not defined", LOG_ERR);
1872  return -1;
1873  }
1874  $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1875  $sql .= " SET date_when = ".($date ? "'".$this->db->idate($date)."'" : "null");
1876  if ($increment_nb_gen_done > 0) {
1877  $sql .= ', nb_gen_done = nb_gen_done + 1';
1878  }
1879  $sql .= " WHERE rowid = ".((int) $this->id);
1880 
1881  dol_syslog(get_class($this)."::setNextDate", LOG_DEBUG);
1882  if ($this->db->query($sql)) {
1883  $this->date_when = $date;
1884  if ($increment_nb_gen_done > 0) {
1885  $this->nb_gen_done++;
1886  }
1887 
1888  if (!$notrigger) {
1889  // Call trigger
1890  $result = $this->call_trigger('BILLREC_MODIFY', $user);
1891  if ($result < 0) {
1892  return $result;
1893  }
1894  // End call triggers
1895  }
1896  return 1;
1897  } else {
1898  dol_print_error($this->db);
1899  return -1;
1900  }
1901  }
1902 
1910  public function setMaxPeriod($nb, $notrigger = 0)
1911  {
1912 
1913  global $user;
1914 
1915  if (!$this->table_element) {
1916  dol_syslog(get_class($this)."::setMaxPeriod was called on objet with property table_element not defined", LOG_ERR);
1917  return -1;
1918  }
1919 
1920  if (empty($nb)) {
1921  $nb = 0;
1922  }
1923 
1924  $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1925  $sql .= ' SET nb_gen_max = '.((int) $nb);
1926  $sql .= " WHERE rowid = ".((int) $this->id);
1927 
1928  dol_syslog(get_class($this)."::setMaxPeriod", LOG_DEBUG);
1929  if ($this->db->query($sql)) {
1930  $this->nb_gen_max = $nb;
1931 
1932  if (!$notrigger) {
1933  // Call trigger
1934  $result = $this->call_trigger('BILLREC_MODIFY', $user);
1935  if ($result < 0) {
1936  return $result;
1937  }
1938  // End call triggers
1939  }
1940 
1941  return 1;
1942  } else {
1943  dol_print_error($this->db);
1944  return -1;
1945  }
1946  }
1947 
1955  public function setAutoValidate($validate, $notrigger = 0)
1956  {
1957  global $user;
1958 
1959  if (!$this->table_element) {
1960  dol_syslog(get_class($this)."::setAutoValidate was called on objet with property table_element not defined", LOG_ERR);
1961  return -1;
1962  }
1963 
1964  $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1965  $sql .= ' SET auto_validate = '.((int) $validate);
1966  $sql .= " WHERE rowid = ".((int) $this->id);
1967 
1968  dol_syslog(get_class($this)."::setAutoValidate", LOG_DEBUG);
1969  if ($this->db->query($sql)) {
1970  $this->auto_validate = $validate;
1971 
1972  if (!$notrigger) {
1973  // Call trigger
1974  $result = $this->call_trigger('BILLREC_MODIFY', $user);
1975  if ($result < 0) {
1976  return $result;
1977  }
1978  // End call triggers
1979  }
1980 
1981  return 1;
1982  } else {
1983  dol_print_error($this->db);
1984  return -1;
1985  }
1986  }
1987 
1995  public function setGeneratePdf($validate, $notrigger = 0)
1996  {
1997  global $user;
1998 
1999  if (!$this->table_element) {
2000  dol_syslog(get_class($this)."::setGeneratePdf was called on objet with property table_element not defined", LOG_ERR);
2001  return -1;
2002  }
2003 
2004  $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2005  $sql .= ' SET generate_pdf = '.((int) $validate);
2006  $sql .= " WHERE rowid = ".((int) $this->id);
2007 
2008  dol_syslog(get_class($this)."::setGeneratePdf", LOG_DEBUG);
2009  if ($this->db->query($sql)) {
2010  $this->generate_pdf = $validate;
2011 
2012  if (!$notrigger) {
2013  // Call trigger
2014  $result = $this->call_trigger('BILLREC_MODIFY', $user);
2015  if ($result < 0) {
2016  return $result;
2017  }
2018  // End call triggers
2019  }
2020 
2021  return 1;
2022  } else {
2023  dol_print_error($this->db);
2024  return -1;
2025  }
2026  }
2027 
2035  public function setModelPdf($model, $notrigger = 0)
2036  {
2037  global $user;
2038  if (!$this->table_element) {
2039  dol_syslog(get_class($this)."::setModelPdf was called on objet with property table_element not defined", LOG_ERR);
2040  return -1;
2041  }
2042 
2043  $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2044  $sql .= " SET modelpdf = '".$this->db->escape($model)."'";
2045  $sql .= " WHERE rowid = ".((int) $this->id);
2046 
2047  dol_syslog(get_class($this)."::setModelPdf", LOG_DEBUG);
2048  if ($this->db->query($sql)) {
2049  $this->model_pdf = $model;
2050 
2051  if (!$notrigger) {
2052  // Call trigger
2053  $result = $this->call_trigger('BILLREC_MODIFY', $user);
2054  if ($result < 0) {
2055  return $result;
2056  }
2057  // End call triggers
2058  }
2059 
2060  return 1;
2061  } else {
2062  dol_print_error($this->db);
2063  return -1;
2064  }
2065  }
2066 }
2067 
2068 
2069 
2075 {
2079  public $element = 'facturedetrec';
2080 
2084  public $table_element = 'facturedet_rec';
2085 
2086 
2087  public $fk_product_fournisseur_price;
2088  public $fk_fournprice; // For backward compatibility
2089 
2090  public $rang;
2091 
2092  public $desc;
2093  public $description;
2094 
2095  public $fk_product_type; // Use instead product_type
2096 
2097  public $fk_contract_line;
2098 
2099 
2107  public function delete(User $user, $notrigger = false)
2108  {
2109  $error = 0;
2110 
2111  $this->db->begin();
2112 
2113  if (!$error) {
2114  if (!$notrigger) {
2115  // Call triggers
2116  $result = $this->call_trigger('LINEBILLREC_DELETE', $user);
2117  if ($result < 0) {
2118  $error++;
2119  } // Do also here what you must do to rollback action if trigger fail
2120  // End call triggers
2121  }
2122  }
2123 
2124  if (!$error) {
2125  $result = $this->deleteExtraFields();
2126  if ($result < 0) {
2127  $error++;
2128  }
2129  }
2130 
2131  if (!$error) {
2132  $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid='.((int) $this->id);
2133 
2134  $res = $this->db->query($sql);
2135  if (!$res) {
2136  $error++;
2137  $this->errors[] = $this->db->lasterror();
2138  }
2139  }
2140 
2141  // Commit or rollback
2142  if ($error) {
2143  $this->db->rollback();
2144  return -1;
2145  } else {
2146  $this->db->commit();
2147  return 1;
2148  }
2149  }
2150 
2151 
2158  public function fetch($rowid)
2159  {
2160  $sql = 'SELECT l.rowid, l.fk_facture ,l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,';
2161  $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise, l.remise_percent, l.subprice,';
2162  $sql .= ' l.date_start_fill, l.date_end_fill, l.info_bits, l.total_ht, l.total_tva, l.total_ttc,';
2163  $sql .= ' l.rang, l.special_code,';
2164  $sql .= ' l.fk_unit, l.fk_contract_line,';
2165  $sql .= ' l.import_key, l.fk_multicurrency,';
2166  $sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2167  $sql .= ' l.buy_price_ht, l.fk_product_fournisseur_price,';
2168  $sql .= ' l.fk_user_author, l.fk_user_modif,';
2169  $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2170  $sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet_rec as l';
2171  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
2172  $sql .= ' WHERE l.rowid = '.((int) $rowid);
2173  $sql .= ' ORDER BY l.rang';
2174 
2175  dol_syslog('FactureRec::fetch', LOG_DEBUG);
2176  $result = $this->db->query($sql);
2177  if ($result) {
2178  $objp = $this->db->fetch_object($result);
2179 
2180  $this->id = $objp->rowid;
2181  $this->label = $objp->custom_label; // Label line
2182  $this->desc = $objp->description; // Description line
2183  $this->description = $objp->description; // Description line
2184  $this->product_type = $objp->product_type; // Type of line
2185  $this->ref = $objp->product_ref; // Ref product
2186  $this->product_ref = $objp->product_ref; // Ref product
2187  $this->libelle = $objp->product_label; // deprecated
2188  $this->product_label = $objp->product_label; // Label product
2189  $this->product_desc = $objp->product_desc; // Description product
2190  $this->fk_product_type = $objp->fk_product_type; // Type of product
2191  $this->qty = $objp->qty;
2192  $this->price = $objp->price;
2193  $this->subprice = $objp->subprice;
2194  $this->fk_facture = $objp->fk_facture;
2195  $this->vat_src_code = $objp->vat_src_code;
2196  $this->tva_tx = $objp->tva_tx;
2197  $this->localtax1_tx = $objp->localtax1_tx;
2198  $this->localtax2_tx = $objp->localtax2_tx;
2199  $this->localtax1_type = $objp->localtax1_type;
2200  $this->localtax2_type = $objp->localtax2_type;
2201  $this->remise_percent = $objp->remise_percent;
2202  //$this->fk_remise_except = $objp->fk_remise_except;
2203  $this->fk_product = $objp->fk_product;
2204  $this->date_start_fill = $objp->date_start_fill;
2205  $this->date_end_fill = $objp->date_end_fill;
2206  $this->info_bits = $objp->info_bits;
2207  $this->total_ht = $objp->total_ht;
2208  $this->total_tva = $objp->total_tva;
2209  $this->total_ttc = $objp->total_ttc;
2210  //$this->code_ventilation = $objp->fk_code_ventilation;
2211  $this->rang = $objp->rang;
2212  $this->special_code = $objp->special_code;
2213  $this->fk_unit = $objp->fk_unit;
2214  $this->fk_contract_line = $objp->fk_contract_line;
2215  $this->import_key = $objp->import_key;
2216  $this->fk_multicurrency = $objp->fk_multicurrency;
2217  $this->multicurrency_code = $objp->multicurrency_code;
2218  $this->multicurrency_subprice = $objp->multicurrency_subprice;
2219  $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
2220  $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
2221  $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2222 
2223  $this->buy_price_ht = $objp->buy_price_ht;
2224 
2225  $this->fk_product_fournisseur_price = $objp->fk_product_fournisseur_price;
2226  $this->fk_user_author = $objp->fk_user_author;
2227  $this->fk_user_modif = $objp->fk_user_modif;
2228 
2229  $this->db->free($result);
2230  return 1;
2231  } else {
2232  $this->error = $this->db->lasterror();
2233  return -3;
2234  }
2235  }
2236 
2237 
2245  public function update(User $user, $notrigger = 0)
2246  {
2247  global $conf;
2248 
2249  $error = 0;
2250 
2251  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
2252 
2253  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET";
2254  $sql .= " fk_facture = ".((int) $this->fk_facture);
2255  $sql .= ", label=".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null");
2256  $sql .= ", description='".$this->db->escape($this->desc)."'";
2257  $sql .= ", price=".price2num($this->price);
2258  $sql .= ", qty=".price2num($this->qty);
2259  $sql .= ", tva_tx=".price2num($this->tva_tx);
2260  $sql .= ", vat_src_code='".$this->db->escape($this->vat_src_code)."'";
2261  $sql .= ", localtax1_tx=".price2num($this->localtax1_tx);
2262  $sql .= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'";
2263  $sql .= ", localtax2_tx=".price2num($this->localtax2_tx);
2264  $sql .= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'";
2265  $sql .= ", fk_product=".($this->fk_product > 0 ? $this->fk_product : "null");
2266  $sql .= ", product_type=".((int) $this->product_type);
2267  $sql .= ", remise_percent=".price2num($this->remise_percent);
2268  $sql .= ", subprice=".price2num($this->subprice);
2269  $sql .= ", info_bits=".price2num($this->info_bits);
2270  $sql .= ", date_start_fill=".(int) $this->date_start_fill;
2271  $sql .= ", date_end_fill=".(int) $this->date_end_fill;
2272  if (empty($this->skip_update_total)) {
2273  $sql .= ", total_ht=".price2num($this->total_ht);
2274  $sql .= ", total_tva=".price2num($this->total_tva);
2275  $sql .= ", total_localtax1=".price2num($this->total_localtax1);
2276  $sql .= ", total_localtax2=".price2num($this->total_localtax2);
2277  $sql .= ", total_ttc=".price2num($this->total_ttc);
2278  }
2279  $sql .= ", rang=".((int) $this->rang);
2280  $sql .= ", special_code=".((int) $this->special_code);
2281  $sql .= ", fk_unit=".($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : "null");
2282  $sql .= ", fk_contract_line=".($this->fk_contract_line ? $this->fk_contract_line : "null");
2283  $sql .= " WHERE rowid = ".((int) $this->id);
2284 
2285  $this->db->begin();
2286 
2287  dol_syslog(get_class($this)."::updateline", LOG_DEBUG);
2288 
2289  $resql = $this->db->query($sql);
2290  if ($resql) {
2291  if (!$error) {
2292  $result = $this->insertExtraFields();
2293  if ($result < 0) {
2294  $error++;
2295  }
2296  }
2297 
2298  if (!$error && !$notrigger) {
2299  // Call trigger
2300  $result = $this->call_trigger('LINEBILLREC_MODIFY', $user);
2301  if ($result < 0) {
2302  $error++;
2303  }
2304  // End call triggers
2305  }
2306 
2307  if ($error) {
2308  $this->db->rollback();
2309  return -2;
2310  } else {
2311  $this->db->commit();
2312  return 1;
2313  }
2314  } else {
2315  $this->error = $this->db->lasterror();
2316  $this->db->rollback();
2317  return -2;
2318  }
2319  }
2320 }
create($user, $facid, $notrigger=0)
Create a predefined invoice.
calculate_date_lim_reglement($cond_reglement=0)
Returns an invoice payment deadline based on the invoice settlement conditions and billing date...
setAutoValidate($validate, $notrigger=0)
Update the auto validate flag of invoice.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
Class to manage invoice lines of templates.
setMaxPeriod($nb, $notrigger=0)
Update the maximum period.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm= 'auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
setNextDate($date, $increment_nb_gen_done=0, $notrigger=0)
Update the next date of execution.
getNomUrl($withpicto=0, $option= '', $max=0, $short=0, $moretitle= '', $notooltip= '', $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
$conf db
API class for accounts.
Definition: inc.php:41
initAsSpecimen($option= '')
Initialise an instance with random values.
Class to manage products or services.
dol_now($mode= 'auto')
Return date for now.
deleteObjectLinked($sourceid=null, $sourcetype= '', $targetid=null, $targettype= '', $rowid= '', $f_user=null, $notrigger=0)
Delete all links between an object $this.
Class to manage invoice templates.
static commonReplaceProduct(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller= '', $localtaxes_array= '', $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code= '')
Calculate totals (net, vat, ...) of a line.
Definition: price.lib.php:86
Class to manage Dolibarr users.
Definition: user.class.php:44
Class to manage Dolibarr database access.
getLinesArray()
Create an array of invoice lines.
getNextDate()
Return the next date of.
fetch($rowid, $ref= '', $ref_ext= '')
Load object and lines.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
Parent class of all other business classes for details of elements (invoices, contracts, proposals, orders, ...)
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:121
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...
insertExtraFields($trigger= '', $userused=null)
Add/Update all extra fields values for the current object.
fetch_lines()
Get lines of template invoices into this-&gt;lines.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
static commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
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.
update(User $user, $notrigger=0)
Update a line to invoice_rec.
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
deleteExtraFields()
Delete all extra fields values for the current object.
setModelPdf($model, $notrigger=0)
Update the model for documents.
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this-&gt;array_options This method is in most cases call...
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->supplier_invoice->lire)) if(isModEnabled('don')&&!empty($user->rights->don->lire)) if(isModEnabled('tax')&&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture')&&isModEnabled('commande')&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
Superclass for invoices classes.
strikeIfMaxNbGenReached($ret)
Format string to output with by striking the string if max number of generation was reached...
fetch($rowid)
Get line of template invoice.
updateline($rowid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type= 'HT', $info_bits=0, $fk_remise_except= '', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $label= '', $fk_unit=null, $pu_ht_devise=0, $notrigger=0, $date_start_fill=0, $date_end_fill=0, $fk_fournprice=null, $pa_ht=0)
Update a line to invoice.
div float
Buy price without taxes.
Definition: style.css.php:809
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
call_trigger($triggerName, $user)
Call trigger based on this instance.
addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type= 'HT', $info_bits=0, $fk_remise_except= '', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $label= '', $fk_unit=null, $pu_ht_devise=0, $date_start_fill=0, $date_end_fill=0, $fk_fournprice=null, $pa_ht=0)
Add a line to invoice.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add objects linked in llx_element_element.
$object ref
Definition: info.php:77
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
LibStatut($recur, $status, $mode=0, $alreadypaid=-1, $type=0)
Return label of a status.
__construct(DoliDB $db)
Constructor.
dolGetStatus($statusLabel= '', $statusLabelShort= '', $html= '', $statusType= 'status0', $displayMode=0, $url= '', $params=array())
Output the badge of a status.
isMaxNbGenReached()
Return if maximum number of generation is reached.
Class to manage invoices.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
setFrequencyAndUnit($frequency, $unit, $notrigger=0)
Update frequency and unit.
update(User $user, $notrigger=0)
Update a line to invoice_rec.
update_price($exclspec=0, $roundingadjust= 'none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines)...
setGeneratePdf($validate, $notrigger=0)
Update the auto generate documents.
createRecurringInvoices($restrictioninvoiceid=0, $forcevalidation=0, $notrigger=0)
Create all recurrents invoices (for all entities if multicompany is used).
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
getLibStatut($mode=0, $alreadypaid=-1)
Return label of object status.
Class to manage invoice lines.