dolibarr  x.y.z
fournisseur.facture-rec.class.php
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.'/fourn/class/fournisseur.facture.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
35 
36 
41 {
42  const TRIGGER_PREFIX = 'SUPPLIERBILLREC';
46  public $element = 'invoice_supplier_rec';
47 
51  public $table_element = 'facture_fourn_rec';
52 
56  public $table_element_line = 'facture_fourn_det_rec';
57 
61  public $fk_element = 'fk_facture_fourn';
62 
66  public $picto = 'bill';
67 
71  protected $table_ref_field = 'titre';
72 
76  public $titre;
77  public $ref_supplier;
78  public $socid;
79 
80  public $suspended;
81  public $libelle;
82  public $label;
83 
88  public $amount;
93  public $remise;
94 
95  public $vat_src_code;
96  public $localtax1;
97  public $localtax2;
98 
99  public $user_author;
100  public $user_modif;
101  public $fk_project;
102 
103  public $mode_reglement_id;
104  public $mode_reglement_code;
105  public $cond_reglement_code;
106  public $cond_reglement_doc;
107  public $cond_reglement_id;
108 
109  public $date_lim_reglement;
110 
111  public $fk_multicurrency;
112  public $multicurrency_code;
113  public $multicurrency_tx;
114  public $multicurrency_total_ht;
115  public $multicurrency_total_tva;
116  public $multicurrency_total_ttc;
117 
118  public $usenewprice = 0;
119  public $frequency;
120  public $unit_frequency;
121  public $date_when;
122  public $date_last_gen;
123  public $nb_gen_done;
124  public $nb_gen_max;
125  public $auto_validate; // 0 to create in draft, 1 to create and validate the new invoice
126  public $generate_pdf; // 1 to generate PDF on invoice generation (default)
127 
128  public $model_pdf;
129 
134  public $lines = array();
135 
136 
137  /* Override fields in CommonObject
138  public $entity;
139  public $date_creation;
140  public $date_modification;
141  public $total_ht;
142  public $total_tva;
143  public $total_ttc;
144  public $fk_account;
145  public $mode_reglement;
146  public $cond_reglement;
147  public $note_public;
148  public $note_private;
149  */
150 
175  // BEGIN MODULEBUILDER PROPERTIES
179  public $fields = array(
180  'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
181  'titre' =>array('type'=>'varchar(100)', 'label'=>'Titre', 'enabled'=>1, 'showoncombobox' => 1, 'visible'=>-1, 'position'=>15),
182  'ref_supplier' =>array('type'=>'varchar(180)', 'label'=>'RefSupplier', 'enabled'=>1, 'showoncombobox' => 1, 'visible'=>-1, 'position'=>20),
183  'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>25, 'index'=>1),
184  'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>30),
185  'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>35),
186  'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>40),
187  'suspended' =>array('type'=>'integer', 'label'=>'Suspended', 'enabled'=>1, 'visible'=>-1, 'position'=>225),
188  'libelle' =>array('type'=>'varchar(100)', 'label'=>'Libelle', 'enabled'=>1, 'showoncombobox' => 0, 'visible'=>-1, 'position'=>15),
189 
190  'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'isameasure'=>1),
191  'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>65, 'isameasure'=>1),
192  'total_ht' =>array('type'=>'double(24,8)', 'label'=>'Total', 'enabled'=>1, 'visible'=>-1, 'position'=>70, 'isameasure'=>1),
193  'total_tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>55, 'isameasure'=>1),
194  'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>75, 'isameasure'=>1),
195 
196  'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
197  'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>210),
198  'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>85),
199  'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>'$conf->banque->enabled', 'visible'=>-1, 'position'=>175),
200  'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Fk cond reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
201  'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'Fk mode reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
202  'date_lim_reglement' =>array('type'=>'date', 'label'=>'Date lim reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
203 
204  'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105),
205  'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110),
206  'modelpdf' =>array('type'=>'varchar(255)', 'label'=>'Modelpdf', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
207 
208  'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
209  'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
210  'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>190, 'isameasure'=>1),
211  'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>195, 'isameasure'=>1),
212  'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>200, 'isameasure'=>1),
213  'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>205, 'isameasure'=>1),
214 
215  'usenewprice' =>array('type'=>'integer', 'label'=>'UseNewPrice', 'enabled'=>1, 'visible'=>0, 'position'=>155),
216  'frequency' =>array('type'=>'integer', 'label'=>'Frequency', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
217  'unit_frequency' =>array('type'=>'varchar(2)', 'label'=>'Unit frequency', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
218 
219  'date_when' =>array('type'=>'datetime', 'label'=>'Date when', 'enabled'=>1, 'visible'=>-1, 'position'=>130),
220  'date_last_gen' =>array('type'=>'datetime', 'label'=>'Date last gen', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
221  'nb_gen_done' =>array('type'=>'integer', 'label'=>'Nb gen done', 'enabled'=>1, 'visible'=>-1, 'position'=>140),
222  'nb_gen_max' =>array('type'=>'integer', 'label'=>'Nb gen max', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
223  'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>160, 'isameasure'=>1),
224  'auto_validate' =>array('type'=>'integer', 'label'=>'Auto validate', 'enabled'=>1, 'visible'=>-1, 'position'=>165),
225  'generate_pdf' =>array('type'=>'integer', 'label'=>'Generate pdf', 'enabled'=>1, 'visible'=>-1, 'position'=>170),
226 
227  );
228  // END MODULEBUILDER PROPERTIES
229 
230  const STATUS_NOTSUSPENDED = 0;
231  const STATUS_SUSPENDED = 1;
232 
233 
234 
240  public function __construct($db)
241  {
242  $this->db = $db;
243  }
244 
253  public function create($user, $facFournId, $notrigger = 0)
254  {
255  global $conf;
256 
257  $error = 0;
258  $now = dol_now();
259 
260  // Clean parameters
261  $this->titre = empty($this->titre) ? '' : $this->titre;
262  $keyforref = $this->table_ref_field;
263  $this->ref = $this->$keyforref;
264  $this->ref_supplier = empty($this->ref_supplier) ? '' : $this->ref_supplier;
265  $this->usenewprice = empty($this->usenewprice) ? 0 : $this->usenewprice;
266  $this->suspended = empty($this->suspended) ? 0 : $this->suspended;
267  // No frequency defined then no next date to execution
268  if (empty($this->frequency)) {
269  $this->frequency = 0;
270  $this->date_when = null;
271  }
272  $this->frequency = abs($this->frequency);
273  $this->nb_gen_done = 0;
274  $this->nb_gen_max = empty($this->nb_gen_max) ? 0 : $this->nb_gen_max;
275  $this->auto_validate = empty($this->auto_validate) ? 0 : $this->auto_validate;
276  $this->generate_pdf = empty($this->generate_pdf) ? 0 : $this->generate_pdf;
277 
278  $this->db->begin();
279 
280  // On charge la facture fournisseur depuis laquelle on crée la facture fournisseur modèle
281  $facfourn_src = new FactureFournisseur($this->db);
282  $result = $facfourn_src->fetch($facFournId);
283  if ($result > 0) {
284  $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture_fourn_rec (';
285  $sql .= 'titre';
286  $sql .= ', ref_supplier';
287  $sql .= ', entity';
288  $sql .= ', fk_soc';
289  $sql .= ', datec';
290  $sql .= ', suspended';
291  $sql .= ', libelle';
292  $sql .= ', total_ttc';
293  $sql .= ', fk_user_author';
294  $sql .= ', fk_projet';
295  $sql .= ', fk_account';
296  $sql .= ', fk_cond_reglement';
297  $sql .= ', fk_mode_reglement';
298  $sql .= ', date_lim_reglement';
299  $sql .= ', note_private';
300  $sql .= ', note_public';
301  $sql .= ', modelpdf';
302  $sql .= ', fk_multicurrency';
303  $sql .= ', multicurrency_code';
304  $sql .= ', multicurrency_tx';
305  $sql .= ', usenewprice';
306  $sql .= ', frequency';
307  $sql .= ', unit_frequency';
308  $sql .= ', date_when';
309  $sql .= ', date_last_gen';
310  $sql .= ', nb_gen_done';
311  $sql .= ', nb_gen_max';
312  $sql .= ', auto_validate';
313  $sql .= ', generate_pdf';
314  $sql .= ') VALUES (';
315  $sql .= "'".$this->db->escape($this->titre)."'";
316  $sql .= ", '".$this->db->escape($this->ref_supplier)."'";
317  $sql .= ", ".((int) $conf->entity);
318  $sql .= ", ".((int) $facfourn_src->socid);
319  $sql .= ", '".$this->db->idate($now)."'";
320  $sql .= ", ".((int) $this->suspended);
321  $sql .= ", '".$this->db->escape($this->libelle)."'";
322  $sql .= ", " .(!empty($facfourn_src->total_ttc) ? (float) $facfourn_src->total_ttc : '0'); // amount
323  $sql .= ", " .((int) $user->id);
324  $sql .= ", " .(!empty($this->fk_project) ? ((int) $this->fk_project) : 'NULL');
325  $sql .= ", " .(!empty($facfourn_src->fk_account) ? ((int) $facfourn_src->fk_account) : 'NULL');
326  $sql .= ", " .($this->cond_reglement_id > 0 ? (int) $this->cond_reglement_id : 'NULL');
327  $sql .= ", " .($this->mode_reglement_id > 0 ? (int) $this->mode_reglement_id : 'NULL');
328  $sql .= ", ".($facfourn_src->date_echeance > 0 ? "'".$this->db->idate($facfourn_src->date_echeance)."'" : 'NULL'); // date_lim_reglement
329  $sql .= ", " .(!empty($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : 'NULL');
330  $sql .= ", " .(!empty($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : 'NULL');
331  $sql .= ", " .(!empty($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : 'NULL');
332  $sql .= ", " . (int) $facfourn_src->fk_multicurrency;
333  $sql .= ", '".$this->db->escape($facfourn_src->multicurrency_code)."'";
334  $sql .= ", " . (float) $facfourn_src->multicurrency_tx;
335  $sql .= ", " . (int) $this->usenewprice;
336  $sql .= ", " . (int) $this->frequency;
337  $sql .= ", '".$this->db->escape($this->unit_frequency)."'";
338  $sql .= ", " .(!empty($this->date_when) ? "'".$this->db->idate($this->date_when)."'" : 'NULL');
339  $sql .= ", " .(!empty($this->date_last_gen) ? "'".$this->db->idate($this->date_last_gen)."'" : 'NULL');
340  $sql .= ", " . (int) $this->nb_gen_done;
341  $sql .= ", " . (int) $this->nb_gen_max;
342  $sql .= ", " . (int) $this->auto_validate;
343  $sql .= ", " . (int) $this->generate_pdf;
344  $sql .= ')';
345 
346  if ($this->db->query($sql)) {
347  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX. 'facture_fourn_rec');
348 
349  // Fields used into addline later
350  $this->fk_multicurrency = $facfourn_src->fk_multicurrency;
351 
352  $this->multicurrency_code = $facfourn_src->multicurrency_code;
353  $this->multicurrency_tx = $facfourn_src->multicurrency_tx;
354 
355  // Add lines
356  $num = count($facfourn_src->lines);
357  for ($i = 0; $i < $num; $i++) {
358  $tva_tx = $facfourn_src->lines[$i]->tva_tx;
359  if (!empty($facfourn_src->lines[$i]->vat_src_code) && !preg_match('/\‍(/', $tva_tx)) {
360  $tva_tx .= ' ('.$facfourn_src->lines[$i]->vat_src_code.')';
361  }
362 
363  $result_insert = $this->addline(
364  $facfourn_src->lines[$i]->fk_product,
365  $facfourn_src->lines[$i]->ref_supplier,
366  $facfourn_src->lines[$i]->label,
367  $facfourn_src->lines[$i]->description,
368  $facfourn_src->lines[$i]->pu_ht,
369  $facfourn_src->lines[$i]->pu_ttc,
370  $facfourn_src->lines[$i]->qty,
371  $facfourn_src->lines[$i]->remise_percent,
372  $tva_tx,
373  $facfourn_src->lines[$i]->localtax1_tx,
374  $facfourn_src->lines[$i]->localtax2_tx,
375  'HT',
376  $facfourn_src->lines[$i]->product_type,
377  $facfourn_src->lines[$i]->date_start,
378  $facfourn_src->lines[$i]->date_end,
379  $facfourn_src->lines[$i]->info_bits,
380  $facfourn_src->lines[$i]->special_code,
381  $facfourn_src->lines[$i]->rang,
382  $facfourn_src->lines[$i]->fk_unit
383  );
384 
385  if ($result_insert < 0) {
386  $error++;
387  } else {
388  $objectline = new FactureFournisseurLigneRec($this->db);
389 
390  $result2 = $objectline->fetch($result_insert);
391  if ($result2 > 0) {
392  // Extrafields
393  if (method_exists($facfourn_src->lines[$i], 'fetch_optionals')) {
394  $facfourn_src->lines[$i]->fetch_optionals($facfourn_src->lines[$i]->id);
395  $objectline->array_options = $facfourn_src->lines[$i]->array_options;
396  }
397 
398  $result = $objectline->insertExtraFields();
399  if ($result < 0) {
400  $error++;
401  }
402  } elseif ($result2 < 0) {
403  $this->errors[] = $objectline->error;
404  $error++;
405  }
406  }
407  }
408 
409  if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) { // To use new linkedObjectsIds instead of old linked_objects
410  $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds
411  }
412 
413  // Add object linked
414  if (!$error && $this->id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
415  foreach ($this->linked_objects as $origin => $tmp_origin_id) {
416  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, ...))
417  foreach ($tmp_origin_id as $origin_id) {
418  $ret = $this->add_object_linked($origin, $origin_id);
419  if (!$ret) {
420  $this->error = $this->db->lasterror();
421  $error++;
422  }
423  }
424  } else // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
425  {
426  $origin_id = $tmp_origin_id;
427  $ret = $this->add_object_linked($origin, $origin_id);
428  if (!$ret) {
429  $this->error = $this->db->lasterror();
430  $error++;
431  }
432  }
433  }
434  }
435 
436  if (!$error) {
437  $result = $this->insertExtraFields();
438  if ($result < 0) {
439  $error++;
440  }
441  }
442 
443  if (!$error && !$notrigger) {
444  // Call trigger
445  $result = $this->call_trigger('SUPPLIERBILLREC_CREATE', $user);
446  if ($result < 0) {
447  $this->db->rollback();
448  return -2;
449  }
450  // End call triggers
451  }
452 
453  if ($error) {
454  $this->db->rollback();
455  return -3;
456  } else {
457  $this->db->commit();
458  return $this->id;
459  }
460  } else {
461  $this->error = $this->db->lasterror();
462  $this->db->rollback();
463  return -2;
464  }
465  } else {
466  $this->db->rollback();
467  return -1;
468  }
469  }
470 
471 
479  public function update(User $user, $notrigger = 0)
480  {
481  global $conf;
482 
483  $error = 0;
484 
485  $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_rec SET";
486  $sql .= " titre = '" . (!empty($this->titre) ? $this->db->escape($this->titre) : "")."'," ;
487  $sql .= " ref_supplier = '". (!empty($this->ref_supplier) ? $this->db->escape($this->ref_supplier) : "")."',";
488  $sql .= " entity = ". (!empty($this->entity) ? ((int) $this->entity) : 1) . ',';
489  if ($this->fk_soc > 0) $sql .= " fk_soc = ". (int) $this->fk_soc. ',';
490  $sql .= " suspended = ". (!empty($this->suspended) ? ((int) $this->suspended) : 0) . ',';
491  $sql .= " libelle = ". (!empty($this->libelle) ? "'".$this->db->escape($this->libelle)."'" : 'NULL') . ",";
492  $sql .= " vat_src_code = ". (!empty($this->vat_src_code) ? "'".$this->db->escape($this->vat_src_code)."'" : 'NULL') . ',';
493  $sql .= " localtax1 = ". (!empty($this->localtax1) ? ((float) $this->localtax1) : 0.00) . ',';
494  $sql .= " localtax2 = ". (!empty($this->localtax2) ? ((float) $this->localtax2) : 0.00) . ',';
495  $sql .= " total_ht = ". (!empty($this->total_ht) ? ((float) $this->total_ht) : 0.00) . ',';
496  $sql .= " total_tva = ". (!empty($this->total_tva) ? ((float) $this->total_tva) : 0.00) . ',';
497  $sql .= " total_ttc = ". (!empty($this->total_ttc) ? ((float) $this->total_ttc) : 0.00) . ',';
498  $sql .= " fk_user_modif = ". ((int) $user->id) . ',';
499  $sql .= " fk_projet = ". (!empty($this->fk_project) ? ((int) $this->fk_project) : 'NULL') . ',';
500  $sql .= " fk_account = ". (!empty($this->fk_account) ? ((int) $this->fk_account) : 'NULL') . ',';
501  $sql .= " fk_mode_reglement = ". (!empty($this->mode_reglement_id) ? ((int) $this->mode_reglement_id) : 'NULL') . ',';
502  $sql .= " fk_cond_reglement = ". (!empty($this->cond_reglement_id) ? ((int) $this->cond_reglement_id) : 'NULL') . ',';
503  $sql .= " date_lim_reglement = ". (!empty($this->date_lim_reglement) ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'NULL') . ',';
504  $sql .= " note_private = '". (!empty($this->note_private) ? $this->db->escape($this->note_private) : '') . "',";
505  $sql .= " note_public = '". (!empty($this->note_public) ? $this->db->escape($this->note_public) : '') . "',";
506  $sql .= " modelpdf = ". (!empty($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : 'NULL') . ",";
507  $sql .= " fk_multicurrency = ". (!empty($this->fk_multicurrency) ? ((int) $this->fk_multicurrency) : 'NULL') . ',';
508  $sql .= " multicurrency_code = ". (!empty($this->multicurrency_code) ? "'".$this->db->escape($this->multicurrency_code)."'" : 'NULL') . ",";
509  $sql .= " multicurrency_tx = ". (!empty($this->multicurrency_tx) ? ((float) $this->multicurrency_tx) : 1) . ',';
510  $sql .= " multicurrency_total_ht = ". (!empty($this->multicurrency_total_ht) ? ((float) $this->multicurrency_total_ht) : 0.00) . ',';
511  $sql .= " multicurrency_total_tva = ". (!empty($this->multicurrency_total_tva) ? ((float) $this->multicurrency_total_tva) : 0.00) . ',';
512  $sql .= " multicurrency_total_ttc = ". (!empty($this->multicurrency_total_ttc) ? ((float) $this->multicurrency_total_ttc) : 0.00) . ',';
513  $sql .= " usenewprice = ". (!empty($this->usenewprice) ? ((int) $this->usenewprice) : 0) . ',';
514  $sql .= " frequency = ". (!empty($this->frequency) ? ((int) $this->frequency) : 0). ',';
515  $sql .= " unit_frequency = '". (!empty($this->unit_frequency) ? $this->db->escape($this->unit_frequency) : ''). "',";
516  $sql .= " date_when = ". (!empty($this->date_when) ? "'".$this->db->idate($this->date_when)."'" : 'NULL') . ',';
517  $sql .= " date_last_gen = ". (!empty($this->date_last_gen) ? "'".$this->db->idate($this->date_last_gen)."'" : 'NULL') . ',';
518  $sql .= " nb_gen_done = ". (!empty($this->nb_gen_done) ? ((int) $this->nb_gen_done) : 0) . ',';
519  $sql .= " nb_gen_max = ". (!empty($this->nb_gen_max) ? ((int) $this->nb_gen_max) : 0) . ',';
520  $sql .= " auto_validate = ". (!empty($this->auto_validate) ? ((int) $this->auto_validate) : 0);
521  $sql .= " WHERE rowid = ". (int) $this->id;
522 
523  dol_syslog(get_class($this)."::update", LOG_DEBUG);
524  $resql = $this->db->query($sql);
525  if ($resql) {
526  if (!$error) {
527  $result = $this->insertExtraFields();
528  if ($result < 0) {
529  $error++;
530  }
531  }
532 
533  if (!$error && !$notrigger) {
534  // Call trigger
535  $result = $this->call_trigger('SUPPLIERBILLREC_MODIFY', $user);
536  if ($result < 0) {
537  $this->db->rollback();
538  return -2;
539  }
540  // End call triggers
541  }
542  $this->db->commit();
543  return 1;
544  } else {
545  $this->error = $this->db->lasterror();
546  $this->db->rollback();
547  return -2;
548  }
549  }
550 
559  public function fetch($rowid, $ref = '', $ref_ext = '')
560  {
561  $sql = 'SELECT f.rowid, f.titre, f.ref_supplier, f.entity, f.fk_soc';
562  $sql .= ', f.datec, f.tms, f.suspended';
563  $sql .= ', f.libelle as label';
564  $sql .= ', f.vat_src_code, f.localtax1, f.localtax2';
565  $sql .= ', f.total_tva, f.total_ht, f.total_ttc';
566  $sql .= ', f.fk_user_author, f.fk_user_modif';
567  $sql .= ', f.fk_projet as fk_project, f.fk_account';
568  $sql .= ', f.fk_mode_reglement, p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
569  $sql .= ', f.fk_cond_reglement, c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
570  $sql .= ', f.date_lim_reglement';
571  $sql .= ', f.note_private, f.note_public, f.modelpdf';
572  $sql .= ', f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc';
573  $sql .= ', f.usenewprice, f.frequency, f.unit_frequency, f.date_when, f.date_last_gen, f.nb_gen_done, f.nb_gen_max, f.auto_validate';
574  $sql .= ', f.generate_pdf';
575  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_rec as f';
576  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
577  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
578  $sql .= ' WHERE f.entity IN ('.getEntity('invoice').')';
579  if ($rowid) {
580  $sql .= ' AND f.rowid='. (int) $rowid;
581  } elseif ($ref) {
582  $sql .= " AND f.titre='".$this->db->escape($ref)."'";
583  } else {
584  $sql .= ' AND f.rowid = 0';
585  }
586 
587  $result = $this->db->query($sql);
588  if ($result) {
589  if ($this->db->num_rows($result)) {
590  $obj = $this->db->fetch_object($result);
591 
592  $keyforref = $this->table_ref_field;
593 
594  $this->id = $obj->rowid;
595  $this->titre = $obj->titre;
596  $this->ref = $obj->$keyforref;
597  $this->ref_supplier = $obj->ref_supplier;
598  $this->entity = $obj->entity;
599  $this->socid = $obj->fk_soc;
600  $this->date_creation = $obj->datec;
601  $this->date_modification = $obj->tms;
602  $this->suspended = $obj->suspended;
603  $this->libelle = $obj->label;
604  $this->label = $obj->label;
605  $this->vat_src_code = $obj->vat_src_code;
606  $this->total_localtax1 = $obj->localtax1;
607  $this->total_localtax2 = $obj->localtax2;
608  $this->total_ht = $obj->total_ht;
609  $this->total_tva = $obj->total_tva;
610  $this->total_ttc = $obj->total_ttc;
611  $this->user_author = $obj->fk_user_author;
612  $this->user_modif = $obj->fk_user_modif;
613  $this->fk_project = $obj->fk_project;
614  $this->fk_account = $obj->fk_account;
615  $this->mode_reglement_id = $obj->fk_mode_reglement;
616  $this->mode_reglement_code = $obj->mode_reglement_code;
617  $this->mode_reglement = $obj->mode_reglement_libelle;
618  $this->cond_reglement_id = $obj->fk_cond_reglement;
619  $this->cond_reglement_code = $obj->cond_reglement_code;
620  $this->cond_reglement = $obj->cond_reglement_libelle;
621  $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
622  $this->date_lim_reglement = $this->db->jdate($obj->date_lim_reglement);
623  $this->note_private = $obj->note_private;
624  $this->note_public = $obj->note_public;
625  $this->model_pdf = $obj->modelpdf;
626 
627  // Multicurrency
628  $this->fk_multicurrency = $obj->fk_multicurrency;
629  $this->multicurrency_code = $obj->multicurrency_code;
630  $this->multicurrency_tx = $obj->multicurrency_tx;
631  $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
632  $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
633  $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
634 
635  $this->usenewprice = $obj->usenewprice;
636  $this->frequency = $obj->frequency;
637  $this->unit_frequency = $obj->unit_frequency;
638  $this->date_when = $this->db->jdate($obj->date_when);
639  $this->date_last_gen = $this->db->jdate($obj->date_last_gen);
640  $this->nb_gen_done = $obj->nb_gen_done;
641  $this->nb_gen_max = $obj->nb_gen_max;
642  $this->auto_validate = $obj->auto_validate;
643  $this->generate_pdf = $obj->generate_pdf;
644 
645 
646  if ($this->statut == self::STATUS_DRAFT) {
647  $this->brouillon = 1;
648  }
649 
650  // Retrieve all extrafield
651  // fetch optionals attributes and labels
652  $this->fetch_optionals();
653 
654  /*
655  * Lines
656  */
657  $result = $this->fetch_lines();
658  if ($result < 0) {
659  $this->error = $this->db->lasterror();
660  return -3;
661  }
662  return 1;
663  } else {
664  $this->error = 'Bill with id '.$rowid.' or ref '.$ref.' not found';
665  dol_syslog('Facture::Fetch Error '.$this->error, LOG_ERR);
666  return -2;
667  }
668  } else {
669  $this->error = $this->db->error();
670  return -1;
671  }
672  }
673 
674 
680  public function getLinesArray()
681  {
682  return $this->fetch_lines();
683  }
684 
685  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
691  public function fetch_lines()
692  {
693  // phpcs:enable
694  $this->lines = array();
695 
696  // Retrieve all extrafield for line
697  // fetch optionals attributes and labels
698  /*if (!is_object($extrafields)) {
699  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
700  $extrafields = new ExtraFields($this->db);
701  }
702  $extrafields->fetch_name_optionals_label($this->table_element_line, true);
703  */
704 
705  $sql = 'SELECT l.rowid,';
706  $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product, l.ref, l.label, l.description,';
707  $sql .= ' l.pu_ht, l.pu_ttc, l.qty, l.remise_percent, l.fk_remise_except, l.vat_src_code, l.tva_tx,';
708  $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type,';
709  $sql .= ' l.total_ht, l.total_tva, l.total_ttc, total_localtax1, total_localtax2,';
710  $sql .= ' l.product_type, l.date_start, l.date_end,';
711  $sql .= ' l.info_bits, l.special_code, l.rang,';
712  $sql .= ' l.fk_unit, l.import_key, l.fk_user_author, l.fk_user_modif,';
713  $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
714  $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
715  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det_rec as l';
716  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
717  $sql .= ' WHERE l.fk_facture_fourn = '. (int) $this->id;
718  $sql .= ' ORDER BY l.rang';
719 
720  dol_syslog('FactureFournisseurRec::fetch_lines', LOG_DEBUG);
721 
722  $result = $this->db->query($sql);
723  if ($result) {
724  $num = $this->db->num_rows($result);
725  $i = 0;
726  while ($i < $num) {
727  $objp = $this->db->fetch_object($result);
728 
729  $line = new FactureFournisseurLigneRec($this->db);
730 
731  $line->id = $objp->rowid;
732  $line->fk_facture_fourn = $objp->fk_facture_fourn;
733  $line->fk_parent = $objp->fk_parent_line;
734  $line->fk_product = $objp->fk_product;
735  $line->ref_supplier = $objp->ref;
736  $line->label = $objp->label;
737  $line->description = $objp->description;
738  $line->pu_ht = $objp->pu_ht;
739  $line->pu_ttc = $objp->pu_ttc;
740  $line->qty = $objp->qty;
741  $line->remise_percent = $objp->remise_percent;
742  $line->fk_remise_except = $objp->fk_remise_except;
743  $line->vat_src_code = $objp->vat_src_code;
744  $line->tva_tx = $objp->tva_tx;
745  $line->localtax1_tx = $objp->localtax1_tx;
746  $line->localtax1_type = $objp->localtax1_type;
747  $line->localtax2_tx = $objp->localtax2_tx;
748  $line->localtax2_type = $objp->localtax2_type;
749  $line->total_ht = $objp->total_ht;
750  $line->total_tva = $objp->total_tva;
751  $line->total_localtax1 = $objp->total_localtax1;
752  $line->total_localtax2 = $objp->total_localtax2;
753  $line->total_ttc = $objp->total_ttc;
754  $line->product_type = $objp->product_type;
755  $line->date_start = $objp->date_start;
756  $line->date_end = $objp->date_end;
757  $line->info_bits = $objp->info_bits ;
758  $line->special_code = $objp->special_code;
759  $line->rang = $objp->rang;
760  $line->fk_unit = $objp->fk_unit;
761  $line->import_key = $objp->import_key;
762  $line->fk_user_author = $objp->fk_user_author;
763  $line->fk_user_modif = $objp->fk_user_modif;
764  $line->fk_multicurrency = $objp->fk_multicurrency;
765  $line->multicurrency_code = $objp->multicurrency_code;
766  $line->multicurrency_subprice = $objp->multicurrency_subprice;
767  $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
768  $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
769  $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
770 
771  $line->fetch_optionals();
772 
773  $this->lines[$i] = $line;
774 
775  $i++;
776  }
777 
778  $this->db->free($result);
779  return 1;
780  } else {
781  $this->error = $this->db->lasterror();
782  return -3;
783  }
784  }
785 
786 
795  public function delete(User $user, $notrigger = 0, $idwarehouse = -1)
796  {
797  $rowid = $this->id;
798 
799  dol_syslog(get_class($this)."::delete rowid=".((int) $rowid), LOG_DEBUG);
800 
801  $error = 0;
802  $this->db->begin();
803 
804  $main = MAIN_DB_PREFIX.'facture_fourn_det_rec';
805  $ef = $main."_extrafields";
806 
807  $sqlef = "DELETE FROM ".$ef." WHERE fk_object IN (SELECT rowid FROM ".$main." WHERE fk_facture_fourn = ". (int) $rowid .")";
808  $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_fourn_det_rec WHERE fk_facture_fourn = ". (int) $rowid;
809 
810  if ($this->db->query($sqlef) && $this->db->query($sql)) {
811  $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_fourn_rec WHERE rowid = ". (int) $rowid;
812  dol_syslog($sql);
813  if ($this->db->query($sql)) {
814  // Delete linked object
815  $res = $this->deleteObjectLinked();
816  if ($res < 0) {
817  $error = -3;
818  }
819  // Delete extrafields
820  $res = $this->deleteExtraFields();
821  if ($res < 0) {
822  $error = -4;
823  }
824  } else {
825  $this->error = $this->db->lasterror();
826  $error = -1;
827  }
828  } else {
829  $this->error = $this->db->lasterror();
830  $error = -2;
831  }
832  if (!$error && !$notrigger) {
833  // Call trigger
834  $result = $this->call_trigger('SUPPLIERBILLREC_DELETE', $user);
835  if ($result < 0) {
836  $error++;
837  }
838  // End call triggers
839  }
840  if (! $error) {
841  $this->db->commit();
842  return 1;
843  } else {
844  $this->db->rollback();
845  return $error;
846  }
847  }
848 
875  public function addline($fk_product, $ref, $label, $desc, $pu_ht, $pu_ttc, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $type = 0, $date_start = 0, $date_end = 0, $info_bits = 0, $special_code = 0, $rang = -1, $fk_unit = null, $pu_ht_devise = 0)
876  {
877  global $mysoc, $user;
878 
879  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
880 
881  $facid = $this->id; //Supplier invoice template ID linked to
882 
883  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,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,date_end_fill=$date_end", LOG_DEBUG);
884 
885  // Check if object of the line is product or service
886  if ($type < 0) {
887  return -1;
888  }
889 
890  if ($this->suspended == self::STATUS_NOTSUSPENDED) {
891  $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
892 
893  // Clean vat code
894  $reg = array();
895  $vat_src_code = '';
896  if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
897  $vat_src_code = $reg[1];
898  $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
899  }
900 
901  // Clean parameters
902  $fk_product = empty($fk_product) ? 0 : $fk_product;
903  $label = empty($label) ? '' : $label;
904  $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
905  $qty = price2num($qty);
906  $pu_ht = price2num($pu_ht);
907  $pu_ttc = price2num($pu_ttc);
908  if (!preg_match('/\‍((.*)\‍)/', $txtva)) {
909  $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
910  }
911  $txlocaltax1 = price2num($txlocaltax1);
912  $txlocaltax2 = price2num($txlocaltax2);
913  $txtva = !empty($txtva) ? $txtva : 0;
914  $txlocaltax1 = !empty($txlocaltax1) ? $txlocaltax1 : 0;
915  $txlocaltax2 = !empty($txlocaltax2) ? $txlocaltax2 : 0;
916  $info_bits = !empty($info_bits) ? $info_bits : 0;
917  $info_bits = !empty($info_bits) ? $info_bits : 0;
918  $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
919 
920  // Calcul du total TTC et de la TVA pour la ligne a partir de qty, pu, remise_percent et txtva
921  // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
922  // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
923 
924  $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);
925  $total_ht = $tabprice[0];
926  $total_tva = $tabprice[1];
927  $total_ttc = $tabprice[2];
928  $total_localtax1 = $tabprice[9];
929  $total_localtax2 = $tabprice[10];
930  $pu_ht = $tabprice[3];
931 
932  // MultiCurrency
933  $multicurrency_total_ht = $tabprice[16];
934  $multicurrency_total_tva = $tabprice[17];
935  $multicurrency_total_ttc = $tabprice[18];
936  $pu_ht_devise = $tabprice[19];
937 
938  $this->db->begin();
939  $product_type = $type;
940  if ($fk_product) {
941  $product = new Product($this->db);
942  $result = $product->fetch($fk_product);
943  if ($result < 0) {
944  return -1;
945  }
946  $product_type = $product->type;
947  if (empty($label)) {
948  $label = $product->label;
949  }
950  }
951 
952  $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec (';
953  $sql .= 'fk_facture_fourn';
954  $sql .= ', fk_product';
955  $sql .= ', ref';
956  $sql .= ', label';
957  $sql .= ', description';
958  $sql .= ', pu_ht';
959  $sql .= ', pu_ttc';
960  $sql .= ', qty';
961  $sql .= ', remise_percent';
962  $sql .= ', fk_remise_except';
963  $sql .= ', vat_src_code';
964  $sql .= ', tva_tx';
965  $sql .= ', localtax1_tx';
966  $sql .= ', localtax1_type';
967  $sql .= ', localtax2_tx';
968  $sql .= ', localtax2_type';
969  $sql .= ', total_ht';
970  $sql .= ', total_tva';
971  $sql .= ', total_localtax1';
972  $sql .= ', total_localtax2';
973  $sql .= ', total_ttc';
974  $sql .= ', product_type';
975  $sql .= ', date_start';
976  $sql .= ', date_end';
977  $sql .= ', info_bits';
978  $sql .= ', special_code';
979  $sql .= ', rang';
980  $sql .= ', fk_unit';
981  $sql .= ', fk_user_author';
982  $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
983  $sql .= ') VALUES (';
984  $sql .= ' ' . (int) $facid; // source supplier invoie id
985  $sql .= ', ' . (!empty($fk_product) ? "'" . $this->db->escape($fk_product) . "'" : 'null');
986  $sql .= ', ' . (!empty($ref) ? "'" . $this->db->escape($ref) . "'" : 'null');
987  $sql .= ', ' . (!empty($label) ? "'" . $this->db->escape($label) . "'" : 'null');
988  $sql .= ", '" . $this->db->escape($desc) . "'";
989  $sql .= ', ' . price2num($pu_ht);
990  $sql .= ', ' . price2num($pu_ttc);
991  $sql .= ', ' . price2num($qty);
992  $sql .= ', ' . price2num($remise_percent);
993  $sql .= ', null';
994  $sql .= ", '" . $this->db->escape($vat_src_code) . "'";
995  $sql .= ', ' . price2num($txtva);
996  $sql .= ', ' . price2num($txlocaltax1);
997  $sql .= ", '" . $this->db->escape(isset($localtaxes_type[0]) ? $localtaxes_type[0] : '') . "'";
998  $sql .= ', ' . price2num($txlocaltax2);
999  $sql .= ", '" . $this->db->escape(isset($localtaxes_type[2]) ? $localtaxes_type[2] : '') . "'";
1000  $sql .= ', ' . price2num($total_ht);
1001  $sql .= ', ' . price2num($total_tva);
1002  $sql .= ', ' . price2num($total_localtax1);
1003  $sql .= ', ' . price2num($total_localtax2);
1004  $sql .= ', ' . price2num($total_ttc);
1005  $sql .= ', ' . (int) $product_type;
1006  $sql .= ', ' . ($date_start > 0 ? (int) $date_start : 'NULL');
1007  $sql .= ', ' . ($date_end > 0 ? (int) $date_end : 'NULL');
1008  $sql .= ', ' . (int) $info_bits;
1009  $sql .= ', ' . (int) $special_code;
1010  $sql .= ', ' . (int) $rang;
1011  $sql .= ', ' . ($fk_unit ? (int) $fk_unit : 'NULL');
1012  $sql .= ', ' . (int) $user;
1013  $sql .= ', ' . (int) $this->fk_multicurrency;
1014  $sql .= ", '" . $this->db->escape($this->multicurrency_code) . "'";
1015  $sql .= ', ' . price2num($pu_ht_devise, 'CU');
1016  $sql .= ', ' . price2num($multicurrency_total_ht, 'CT');
1017  $sql .= ', ' . price2num($multicurrency_total_tva, 'CT');
1018  $sql .= ', ' . price2num($multicurrency_total_ttc, 'CT');
1019  $sql .= ')';
1020 
1021  dol_syslog(get_class($this). '::addline', LOG_DEBUG);
1022  if ($this->db->query($sql)) {
1023  $lineId = $this->db->last_insert_id(MAIN_DB_PREFIX. 'facture_fourn_det_rec');
1024  $this->update_price();
1025  $this->id = $facid;
1026  $this->db->commit();
1027  return $lineId;
1028  } else {
1029  $this->db->rollback();
1030  $this->error = $this->db->lasterror();
1031 
1032  return -1;
1033  }
1034  }
1035  }
1036 
1063  public function updateline($rowid, $fk_product, $ref, $label, $desc, $pu_ht, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $type = 0, $date_start = 0, $date_end = 0, $info_bits = 0, $special_code = 0, $rang = -1, $fk_unit = null, $pu_ht_devise = 0)
1064  {
1065  global $mysoc, $user;
1066 
1067  $facid = $this->id;
1068 
1069  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);
1070  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
1071 
1072  // Check parameters
1073  if ($type < 0) {
1074  return -1;
1075  }
1076 
1077  if ($this->brouillon) {
1078  // Clean parameters
1079  $fk_product = empty($fk_product) ? 0 : $fk_product;
1080  $label = empty($label) ? '' : $label;
1081  $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
1082  $qty = price2num($qty);
1083  $info_bits = empty($info_bits) ? 0 : $info_bits;
1084  $pu_ht = price2num($pu_ht);
1085  $pu_ttc = price2num($pu_ttc);
1086  $pu_ht_devise = price2num($pu_ht_devise);
1087 
1088  if (!preg_match('/\‍((.*)\‍)/', $txtva)) {
1089  $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
1090  }
1091 
1092  $txlocaltax1 = empty($txlocaltax1) ? 0 : price2num($txlocaltax1);
1093  $txlocaltax2 = empty($txlocaltax2) ? 0 : price2num($txlocaltax2);
1094  $this->multicurrency_subprice = empty($this->multicurrency_subprice) ? 0 : $this->multicurrency_subprice;
1095  $this->multicurrency_total_ht = empty($this->multicurrency_total_ht) ? 0 : $this->multicurrency_total_ht;
1096  $this->multicurrency_total_tva = empty($this->multicurrency_total_tva) ? 0 : $this->multicurrency_total_tva;
1097  $this->multicurrency_total_ttc = empty($this->multicurrency_total_ttc) ? 0 : $this->multicurrency_total_ttc;
1098 
1099  $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
1100 
1101 
1102  // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
1103  // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1104  // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1105 
1106  $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
1107 
1108  // Clean vat code
1109  $vat_src_code = '';
1110  $reg = array();
1111  if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
1112  $vat_src_code = $reg[1];
1113  $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
1114  }
1115 
1116  $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);
1117 
1118  $total_ht = $tabprice[0];
1119  $total_tva = $tabprice[1];
1120  $total_ttc = $tabprice[2];
1121  $total_localtax1 = $tabprice[9];
1122  $total_localtax2 = $tabprice[10];
1123  $pu_ht = $tabprice[3];
1124  $pu_tva = $tabprice[4];
1125  $pu_ttc = $tabprice[5];
1126 
1127  // MultiCurrency
1128  $multicurrency_total_ht = $tabprice[16];
1129  $multicurrency_total_tva = $tabprice[17];
1130  $multicurrency_total_ttc = $tabprice[18];
1131  $pu_ht_devise = $tabprice[19];
1132 
1133  $product_type = $type;
1134  if ($fk_product) {
1135  $product = new Product($this->db);
1136  $result = $product->fetch($fk_product);
1137  $product_type = $product->type;
1138  }
1139 
1140  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
1141  $sql .= ' fk_facture_fourn = ' . ((int) $facid);
1142  $sql .= ', fk_product = ' . ($fk_product > 0 ? ((int) $fk_product) : 'null');
1143  $sql .= ", ref = '" . $this->db->escape($ref) . "'";
1144  $sql .= ", label = '" . $this->db->escape($label) . "'";
1145  $sql .= ", description = '" . $this->db->escape($desc) . "'";
1146  $sql .= ', pu_ht = ' . price2num($pu_ht);
1147  $sql .= ', qty = ' . price2num($qty);
1148  $sql .= ", remise_percent = '" . price2num($remise_percent) . "'";
1149  $sql .= ", vat_src_code = '" . $this->db->escape($vat_src_code) . "'";
1150  $sql .= ', tva_tx = ' . price2num($txtva);
1151  $sql .= ', localtax1_tx = ' . (float) $txlocaltax1;
1152  $sql .= ", localtax1_type = '" . $this->db->escape($localtaxes_type[0]) . "'";
1153  $sql .= ', localtax2_tx = ' . (float) $txlocaltax2;
1154  $sql .= ", localtax2_type = '" . $this->db->escape($localtaxes_type[2]) . "'";
1155  $sql .= ", total_ht = '" . price2num($total_ht) . "'";
1156  $sql .= ", total_tva = '" . price2num($total_tva) . "'";
1157  $sql .= ", total_localtax1 = '" . price2num($total_localtax1) . "'";
1158  $sql .= ", total_localtax2 = '" . price2num($total_localtax2) . "'";
1159  $sql .= ", total_ttc = '" . price2num($total_ttc) . "'";
1160  $sql .= ', product_type = ' . (int) $product_type;
1161  $sql .= ', date_start = ' . (empty($date_start) ? 'NULL' : (int) $date_start);
1162  $sql .= ', date_end = ' . (empty($date_end) ? 'NULL' : (int) $date_end);
1163  $sql .= ', info_bits = ' . (int) $info_bits;
1164  $sql .= ', special_code = ' . (int) $special_code;
1165  $sql .= ', rang = ' . (int) $rang;
1166  $sql .= ', fk_unit = ' . ($fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : 'null');
1167  $sql .= ', fk_user_modif = ' . (int) $user;
1168  $sql .= ', multicurrency_subprice = '.price2num($pu_ht_devise);
1169  $sql .= ', multicurrency_total_ht = '.price2num($multicurrency_total_ht);
1170  $sql .= ', multicurrency_total_tva = '.price2num($multicurrency_total_tva);
1171  $sql .= ', multicurrency_total_ttc = '.price2num($multicurrency_total_ttc);
1172  $sql .= ' WHERE rowid = ' . (int) $rowid;
1173 
1174  dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
1175  if ($this->db->query($sql)) {
1176  $this->id = $facid;
1177  $this->update_price();
1178  return 1;
1179  } else {
1180  $this->error = $this->db->lasterror();
1181  return -1;
1182  }
1183  }
1184  }
1185 
1186 
1192  public function getNextDate()
1193  {
1194  if (empty($this->date_when)) {
1195  return false;
1196  }
1197  return dol_time_plus_duree($this->date_when, $this->frequency, $this->unit_frequency);
1198  }
1199 
1205  public function isMaxNbGenReached()
1206  {
1207  $ret = false;
1208  if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) {
1209  $ret = true;
1210  }
1211  return $ret;
1212  }
1213 
1220  public function strikeIfMaxNbGenReached($ret)
1221  {
1222  // Special case to strike the date
1223  return ($this->isMaxNbGenReached() ? '<strike>' : '').$ret.($this->isMaxNbGenReached() ? '</strike>' : '');
1224  }
1225 
1236  public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0)
1237  {
1238  global $conf, $langs, $db, $user, $hookmanager;
1239 
1240  $error = 0;
1241  $nb_create = 0;
1242 
1243  // Load translation files required by the page
1244  $langs->loadLangs(array('main', 'bills'));
1245 
1246  $now = dol_now();
1247  $tmparray = dol_getdate($now);
1248  $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
1249 
1250  dol_syslog('createRecurringInvoices restrictioninvoiceid=' .$restrictioninvoiceid. ' forcevalidation=' .$forcevalidation);
1251 
1252  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_fourn_rec';
1253  $sql .= ' WHERE frequency > 0'; // A recurring supplier invoice is an invoice with a frequency
1254  $sql .= " AND (date_when IS NULL OR date_when <= '".$this->db->idate($today)."')";
1255  $sql .= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)';
1256  $sql .= ' AND suspended = 0';
1257  $sql .= ' AND entity = '. (int) $conf->entity; // MUST STAY = $conf->entity here
1258  if ($restrictioninvoiceid > 0) {
1259  $sql .= ' AND rowid = '. (int) $restrictioninvoiceid;
1260  }
1261  $sql .= $this->db->order('entity', 'ASC');
1262  //print $sql;exit;
1263  $parameters = array(
1264  'restrictioninvoiceid' => $restrictioninvoiceid,
1265  'forcevalidation' => $forcevalidation,
1266  );
1267  $reshook = $hookmanager->executeHooks('beforeCreationOfRecurringInvoices', $parameters, $sql); // note that $sql might be modified by hooks
1268 
1269  $resql = $this->db->query($sql);
1270  if ($resql) {
1271  $i = 0;
1272  $num = $this->db->num_rows($resql);
1273 
1274  if ($num) {
1275  $this->output .= $langs->trans('FoundXQualifiedRecurringInvoiceTemplate', $num)."\n";
1276  } else {
1277  $this->output .= $langs->trans('NoQualifiedRecurringInvoiceTemplateFound');
1278  }
1279 
1280  $saventity = $conf->entity;
1281 
1282  while ($i < $num) { // Loop on each template invoice. If $num = 0, test is false at first pass.
1283  $line = $this->db->fetch_object($resql);
1284 
1285  $this->db->begin();
1286 
1287  $invoiceidgenerated = 0;
1288 
1289  $new_fac_fourn = null;
1290  $facturerec = new FactureFournisseurRec($this->db);
1291  $facturerec->fetch($line->rowid);
1292 
1293  if ($facturerec->id > 0) {
1294  // Set entity context
1295  $conf->entity = $facturerec->entity;
1296 
1297  dol_syslog('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', ref=' .$facturerec->ref. ', entity=' .$facturerec->entity);
1298 
1299  $new_fac_fourn = new FactureFournisseur($this->db);
1300  $new_fac_fourn->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice
1301  $new_fac_fourn->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice
1302 
1303  $new_fac_fourn->type = self::TYPE_STANDARD;
1304  $new_fac_fourn->brouillon = 1;
1305  $new_fac_fourn->statut = self::STATUS_DRAFT;
1306  $new_fac_fourn->status = self::STATUS_DRAFT;
1307  $new_fac_fourn->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.
1308  $new_fac_fourn->socid = $facturerec->socid;
1309  $new_fac_fourn->lines = $facturerec->lines;
1310  $new_fac_fourn->ref_supplier = $facturerec->ref_supplier;
1311  $new_fac_fourn->model_pdf = $facturerec->model_pdf;
1312  $new_fac_fourn->fk_project = $facturerec->fk_project;
1313  $new_fac_fourn->libelle = $facturerec->libelle;
1314 
1315  $invoiceidgenerated = $new_fac_fourn->create($user);
1316  if ($invoiceidgenerated <= 0) {
1317  $this->errors = $new_fac_fourn->errors;
1318  $this->error = $new_fac_fourn->error;
1319  $error++;
1320  }
1321  if (!$error && ($facturerec->auto_validate || $forcevalidation)) {
1322  $result = $new_fac_fourn->validate($user);
1323  if ($result <= 0) {
1324  $this->errors = $new_fac_fourn->errors;
1325  $this->error = $new_fac_fourn->error;
1326  $error++;
1327  }
1328  }
1329 
1330  if (!$error && $facturerec->generate_pdf) {
1331  // We refresh the object in order to have all necessary data (like date_lim_reglement)
1332  $new_fac_fourn->fetch($new_fac_fourn->id);
1333  $result = $new_fac_fourn->generateDocument($facturerec->model_pdf, $langs);
1334  if ($result <= 0) {
1335  $this->errors = $new_fac_fourn->errors;
1336  $this->error = $new_fac_fourn->error;
1337  $error++;
1338  }
1339  }
1340  } else {
1341  $error++;
1342  $this->error = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity."\n";
1343  $this->errors[] = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity;
1344  dol_syslog('createRecurringInvoices Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity);
1345  }
1346 
1347  if (!$error && $invoiceidgenerated >= 0) {
1348  $facturerec->nb_gen_done++;
1349  $facturerec->date_last_gen = dol_now();
1350  $facturerec->date_when= $facturerec->getNextDate();
1351  $facturerec->update($user);
1352  $this->db->commit('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', title=' .$facturerec->titre);
1353  dol_syslog('createRecurringInvoices Process invoice template ' .$facturerec->titre. ' is finished with a success generation');
1354  $nb_create++;
1355  $this->output .= $langs->trans('InvoiceGeneratedFromTemplate', $new_fac_fourn->ref, $facturerec->titre)."\n";
1356  } else {
1357  $this->db->rollback('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', title=' .$facturerec->titre);
1358  }
1359 
1360  $parameters = array(
1361  'cpt' => $i,
1362  'total' => $num,
1363  'errorCount' => $error,
1364  'invoiceidgenerated' => $invoiceidgenerated,
1365  'facturerec' => $facturerec, // it's an object which PHP passes by "reference", so modifiable by hooks.
1366  'this' => $this, // it's an object which PHP passes by "reference", so modifiable by hooks.
1367  );
1368  $reshook = $hookmanager->executeHooks('afterCreationOfRecurringInvoice', $parameters, $new_fac_fourn); // note: $facture can be modified by hooks (warning: $facture can be null)
1369 
1370  $i++;
1371  }
1372 
1373  $conf->entity = $saventity; // Restore entity context
1374  } else {
1375  dol_print_error($this->db);
1376  }
1377 
1378  $this->output = trim($this->output);
1379 
1380  return $error ? $error : 0;
1381  }
1382 
1395  public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = '', $save_lastsearch_value = -1)
1396  {
1397  global $langs, $hookmanager;
1398 
1399  $result = '';
1400 
1401  $label = '<u>'.$langs->trans('RepeatableInvoice').'</u>';
1402  if (!empty($this->ref)) {
1403  $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1404  }
1405  if ($this->frequency > 0) {
1406  $label .= '<br><b>'.$langs->trans('Frequency').':</b> '.$langs->trans('FrequencyPer_'.$this->unit_frequency, $this->frequency);
1407  }
1408  if (!empty($this->date_last_gen)) {
1409  $label .= '<br><b>'.$langs->trans('DateLastGeneration').':</b> '.dol_print_date($this->date_last_gen, 'dayhour');
1410  }
1411  if ($this->frequency > 0) {
1412  if (!empty($this->date_when)) {
1413  $label .= '<br><b>'.$langs->trans('NextDateToExecution').':</b> ';
1414  $label .= (empty($this->suspended) ? '' : '<strike>').dol_print_date($this->date_when, 'day').(empty($this->suspended) ? '' : '</strike>'); // No hour for this property
1415  if (!empty($this->suspended)) {
1416  $label .= ' ('.$langs->trans('Disabled').')';
1417  }
1418  }
1419  }
1420 
1421  $url = DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$this->id;
1422 
1423  if ($short) {
1424  return $url;
1425  }
1426 
1427  if ($option != 'nolink') {
1428  // Add param to save lastsearch_values or not
1429  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1430  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER['PHP_SELF'])) {
1431  $add_save_lastsearch_values = 1;
1432  }
1433  if ($add_save_lastsearch_values) {
1434  $url .= '&save_lastsearch_values=1';
1435  }
1436  }
1437 
1438  $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
1439  $linkend = '</a>';
1440 
1441  $result .= $linkstart;
1442  if ($withpicto) {
1443  $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);
1444  }
1445  if ($withpicto != 2) {
1446  $result .= $this->ref;
1447  }
1448  $result .= $linkend;
1449  global $action;
1450  $hookmanager->initHooks(array($this->element . 'dao'));
1451  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1452  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1453  if ($reshook > 0) {
1454  $result = $hookmanager->resPrint;
1455  } else {
1456  $result .= $hookmanager->resPrint;
1457  }
1458  return $result;
1459  }
1460 
1468  public function getLibStatut($mode = 0, $alreadypaid = -1)
1469  {
1470  return $this->LibStatut($this->frequency ? 1 : 0, $this->suspended, $mode, $alreadypaid, empty($this->type) ? 0 : $this->type);
1471  }
1472 
1473  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1484  public function LibStatut($recur, $status, $mode = 0, $alreadypaid = -1, $type = 0)
1485  {
1486  // phpcs:enable
1487  global $langs;
1488  $langs->load('bills');
1489 
1490  $labelStatus = $langs->transnoentitiesnoconv('Active');
1491  $statusType = 'status0';
1492 
1493  //print "$recur,$status,$mode,$alreadypaid,$type";
1494  if ($mode == 0) {
1495  if ($recur) {
1496  if ($status == self::STATUS_SUSPENDED) {
1497  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1498  } else {
1499  $labelStatus = $langs->transnoentitiesnoconv('Active');
1500  }
1501  } else {
1502  if ($status == self::STATUS_SUSPENDED) {
1503  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1504  } else {
1505  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1506  }
1507  }
1508  } elseif ($mode == 1) {
1509  $prefix = 'Short';
1510  if ($recur) {
1511  if ($status == self::STATUS_SUSPENDED) {
1512  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1513  } else {
1514  $labelStatus = $langs->transnoentitiesnoconv('Active');
1515  }
1516  } else {
1517  if ($status == self::STATUS_SUSPENDED) {
1518  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1519  } else {
1520  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1521  }
1522  }
1523  } elseif ($mode == 2) {
1524  if ($recur) {
1525  if ($status == self::STATUS_SUSPENDED) {
1526  $statusType = 'status6';
1527  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1528  } else {
1529  $statusType = 'status4';
1530  $labelStatus = $langs->transnoentitiesnoconv('Active');
1531  }
1532  } else {
1533  if ($status == self::STATUS_SUSPENDED) {
1534  $statusType = 'status6';
1535  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1536  } else {
1537  $statusType = 'status0';
1538  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1539  }
1540  }
1541  } elseif ($mode == 3) {
1542  if ($recur) {
1543  $prefix = 'Short';
1544  if ($status == self::STATUS_SUSPENDED) {
1545  $statusType = 'status6';
1546  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1547  } else {
1548  $statusType = 'status4';
1549  $labelStatus = $langs->transnoentitiesnoconv('Active');
1550  }
1551  } else {
1552  if ($status == self::STATUS_SUSPENDED) {
1553  $statusType = 'status6';
1554  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1555  } else {
1556  $statusType = 'status0';
1557  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1558  }
1559  }
1560  } elseif ($mode == 4) {
1561  $prefix = '';
1562  if ($recur) {
1563  if ($status == self::STATUS_SUSPENDED) {
1564  $statusType = 'status6';
1565  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1566  } else {
1567  $statusType = 'status4';
1568  $labelStatus = $langs->transnoentitiesnoconv('Active');
1569  }
1570  } else {
1571  if ($status == self::STATUS_SUSPENDED) {
1572  $statusType = 'status6';
1573  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1574  } else {
1575  $statusType = 'status0';
1576  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1577  }
1578  }
1579  } elseif ($mode == 5 || $mode == 6) {
1580  $prefix = '';
1581  if ($mode == 5) {
1582  $prefix = 'Short';
1583  }
1584  if ($recur) {
1585  if ($status == self::STATUS_SUSPENDED) {
1586  $statusType = 'status6';
1587  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1588  } else {
1589  $statusType = 'status4';
1590  $labelStatus = $langs->transnoentitiesnoconv('Active');
1591  }
1592  } else {
1593  if ($status == self::STATUS_SUSPENDED) {
1594  $statusType = 'status6';
1595  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1596  } else {
1597  $statusType = 'status0';
1598  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1599  }
1600  }
1601  }
1602 
1603  $labelStatusShort = $labelStatus;
1604 
1605  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1606  }
1607 
1616  public function initAsSpecimen($option = '')
1617  {
1618  global $user, $langs, $conf;
1619 
1620  $now = dol_now();
1621  $arraynow = dol_getdate($now);
1622  $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1623 
1624  // Load array of products prodids
1625  $num_prods = 0;
1626  $prodids = array();
1627 
1628  $sql = 'SELECT rowid';
1629  $sql .= ' FROM ' .MAIN_DB_PREFIX. 'product';
1630  $sql .= ' WHERE entity IN (' .getEntity('product'). ')';
1631  $sql .= $this->db->plimit(100);
1632 
1633  $resql = $this->db->query($sql);
1634  if ($resql) {
1635  $num_prods = $this->db->num_rows($resql);
1636  $i = 0;
1637  while ($i < $num_prods) {
1638  $i++;
1639  $row = $this->db->fetch_row($resql);
1640  $prodids[$i] = $row[0];
1641  }
1642  }
1643 
1644  // Initialize parameters
1645  $this->id = 0;
1646  $this->ref = 'SPECIMEN';
1647  $this->title = 'SPECIMEN';
1648  $this->specimen = 1;
1649  $this->socid = 1;
1650  $this->date = $nownotime;
1651  $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
1652  $this->cond_reglement_id = 1;
1653  $this->cond_reglement_code = 'RECEP';
1654  $this->date_lim_reglement = $this->calculate_date_lim_reglement();
1655  $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR
1656  $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
1657  $this->note_public = 'This is a comment (public)';
1658  $this->note_private = 'This is a comment (private)';
1659  $this->note = 'This is a comment (private)';
1660  $this->fk_incoterms = 0;
1661  $this->location_incoterms = '';
1662 
1663  if (empty($option) || $option != 'nolines') {
1664  // Lines
1665  $nbp = 5;
1666  $xnbp = 0;
1667  while ($xnbp < $nbp) {
1668  $line = new FactureLigne($this->db);
1669  $line->desc = $langs->trans('Description'). ' ' .$xnbp;
1670  $line->qty = 1;
1671  $line->subprice = 100;
1672  $line->tva_tx = 19.6;
1673  $line->localtax1_tx = 0;
1674  $line->localtax2_tx = 0;
1675  $line->remise_percent = 0;
1676  if ($xnbp == 1) { // Qty is negative (product line)
1677  $prodid = mt_rand(1, $num_prods);
1678  $line->fk_product = $prodids[$prodid];
1679  $line->qty = -1;
1680  $line->total_ht = -100;
1681  $line->total_ttc = -119.6;
1682  $line->total_tva = -19.6;
1683  } elseif ($xnbp == 2) { // UP is negative (free line)
1684  $line->subprice = -100;
1685  $line->total_ht = -100;
1686  $line->total_ttc = -119.6;
1687  $line->total_tva = -19.6;
1688  $line->remise_percent = 0;
1689  } elseif ($xnbp == 3) { // Discount is 50% (product line)
1690  $prodid = mt_rand(1, $num_prods);
1691  $line->fk_product = $prodids[$prodid];
1692  $line->total_ht = 50;
1693  $line->total_ttc = 59.8;
1694  $line->total_tva = 9.8;
1695  $line->remise_percent = 50;
1696  } else // (product line)
1697  {
1698  $prodid = mt_rand(1, $num_prods);
1699  $line->fk_product = $prodids[$prodid];
1700  $line->total_ht = 100;
1701  $line->total_ttc = 119.6;
1702  $line->total_tva = 19.6;
1703  $line->remise_percent = 00;
1704  }
1705 
1706  $this->lines[$xnbp] = $line;
1707  $xnbp++;
1708 
1709  $this->total_ht += $line->total_ht;
1710  $this->total_tva += $line->total_tva;
1711  $this->total_ttc += $line->total_ttc;
1712  }
1713  $this->revenuestamp = 0;
1714 
1715  // Add a line "offered"
1716  $line = new FactureLigne($this->db);
1717  $line->desc = $langs->trans('Description'). ' (offered line)';
1718  $line->qty = 1;
1719  $line->subprice = 100;
1720  $line->tva_tx = 19.6;
1721  $line->localtax1_tx = 0;
1722  $line->localtax2_tx = 0;
1723  $line->remise_percent = 100;
1724  $line->total_ht = 0;
1725  $line->total_ttc = 0; // 90 * 1.196
1726  $line->total_tva = 0;
1727  $prodid = mt_rand(1, $num_prods);
1728  $line->fk_product = $prodids[$prodid];
1729 
1730  $this->lines[$xnbp] = $line;
1731  $xnbp++;
1732  }
1733 
1734  $this->usenewprice = 0;
1735  }
1736 
1745  public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1746  {
1747  $tables = array(
1748  'facture_rec'
1749  );
1750 
1751  return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1752  }
1753 
1761  public function setFrequencyAndUnit($frequency, $unit)
1762  {
1763  if (!$this->table_element) {
1764  dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with property table_element not defined', LOG_ERR);
1765  return -1;
1766  }
1767 
1768  if (!empty($frequency) && empty($unit)) {
1769  dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with params frequency defined but unit not defined', LOG_ERR);
1770  return -2;
1771  }
1772 
1773  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1774  $sql .= " SET frequency = ".($frequency ? ((int) $frequency) : "NULL");
1775  if (!empty($unit)) {
1776  $sql .= ", unit_frequency = '".$this->db->escape($unit)."'";
1777  }
1778  $sql .= " WHERE rowid = ".((int) $this->id);
1779 
1780  dol_syslog(get_class($this).'::setFrequencyAndUnit', LOG_DEBUG);
1781 
1782  if ($this->db->query($sql)) {
1783  $this->frequency = $frequency;
1784  if (!empty($unit)) {
1785  $this->unit_frequency = $unit;
1786  }
1787  return 1;
1788  } else {
1789  $this->error = $this->db->lasterror();
1790  return -1;
1791  }
1792  }
1793 
1801  public function setNextDate($date, $increment_nb_gen_done = 0)
1802  {
1803  if (!$this->table_element) {
1804  dol_syslog(get_class($this).'::setNextDate was called on objet with property table_element not defined', LOG_ERR);
1805  return -1;
1806  }
1807  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1808  $sql .= " SET date_when = " .($date ? "'".$this->db->idate($date)."'" : "NULL");
1809  if ($increment_nb_gen_done > 0) {
1810  $sql .= ", nb_gen_done = nb_gen_done + 1";
1811  }
1812  $sql .= " WHERE rowid = " . (int) $this->id;
1813 
1814  dol_syslog(get_class($this).'::setNextDate', LOG_DEBUG);
1815 
1816  if ($this->db->query($sql)) {
1817  $this->date_when = $date;
1818  if ($increment_nb_gen_done > 0) {
1819  $this->nb_gen_done++;
1820  }
1821  return 1;
1822  } else {
1823  $this->error = $this->db->lasterror();
1824  return -1;
1825  }
1826  }
1827 
1834  public function setMaxPeriod($nb)
1835  {
1836  if (!$this->table_element) {
1837  dol_syslog(get_class($this).'::setMaxPeriod was called on objet with property table_element not defined', LOG_ERR);
1838  return -1;
1839  }
1840 
1841  if (empty($nb)) {
1842  $nb = 0;
1843  }
1844 
1845  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1846  $sql .= " SET nb_gen_max = ". (int) $nb;
1847  $sql .= " WHERE rowid = " . (int) $this->id;
1848 
1849  dol_syslog(get_class($this).'::setMaxPeriod', LOG_DEBUG);
1850 
1851  if ($this->db->query($sql)) {
1852  $this->nb_gen_max = $nb;
1853  return 1;
1854  } else {
1855  dol_print_error($this->db);
1856  return -1;
1857  }
1858  }
1859 
1866  public function setAutoValidate($validate)
1867  {
1868  if (!$this->table_element) {
1869  dol_syslog(get_class($this).'::setAutoValidate was called on objet with property table_element not defined', LOG_ERR);
1870  return -1;
1871  }
1872 
1873  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1874  $sql .= " SET auto_validate = ".((int) $validate);
1875  $sql .= " WHERE rowid = " . (int) $this->id;
1876 
1877  dol_syslog(get_class($this).'::setAutoValidate', LOG_DEBUG);
1878 
1879  if ($this->db->query($sql)) {
1880  $this->auto_validate = $validate;
1881  return 1;
1882  } else {
1883  dol_print_error($this->db);
1884  return -1;
1885  }
1886  }
1887 
1894  public function setGeneratePdf($validate)
1895  {
1896  if (!$this->table_element) {
1897  dol_syslog(get_class($this).'::setGeneratePdf was called on objet with property table_element not defined', LOG_ERR);
1898  return -1;
1899  }
1900 
1901  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1902  $sql .= " SET generate_pdf = ". (int) $validate;
1903  $sql .= " WHERE rowid = " . (int) $this->id;
1904 
1905  dol_syslog(get_class($this).'::setGeneratePdf', LOG_DEBUG);
1906 
1907  if ($this->db->query($sql)) {
1908  $this->generate_pdf = $validate;
1909  return 1;
1910  } else {
1911  dol_print_error($this->db);
1912  return -1;
1913  }
1914  }
1915 
1922  public function setModelPdf($model)
1923  {
1924  if (!$this->table_element) {
1925  dol_syslog(get_class($this).'::setModelPdf was called on objet with property table_element not defined', LOG_ERR);
1926  return -1;
1927  }
1928 
1929  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1930  $sql .= " SET modelpdf = '".$this->db->escape($model)."'";
1931  $sql .= " WHERE rowid = " . (int) $this->id;
1932 
1933  dol_syslog(get_class($this).'::setModelPdf', LOG_DEBUG);
1934 
1935  if ($this->db->query($sql)) {
1936  $this->model_pdf = $model;
1937  return 1;
1938  } else {
1939  dol_print_error($this->db);
1940  return -1;
1941  }
1942  }
1943 }
1944 
1945 
1946 
1952 {
1956  public $element = 'invoice_supplier_det_rec';
1957 
1961  public $table_element = 'facture_fourn_det_rec';
1962 
1963  public $fk_facture_fourn;
1964  public $fk_parent;
1965  public $fk_product;
1966  public $ref_supplier;
1967  public $label;
1968  public $description;
1969  public $pu_ht;
1970  public $pu_ttc;
1971  public $qty;
1972  public $remise_percent;
1973  public $fk_remise_except;
1974  public $vat_src_code;
1975  public $tva_tx;
1976  public $localtax1_tx;
1977  public $localtax1_type;
1978  public $localtax2_tx;
1979  public $localtax2_type;
1980 
1981  public $product_type;
1982  public $date_start;
1983  public $date_end;
1984  public $info_bits;
1985  public $special_code;
1986  public $rang;
1987 
1988  public $fk_user_author;
1989  public $fk_user_modif;
1990  public $fk_multicurrency;
1991  public $multicurrency_subprice;
1992 
1993 
1994  /* Overrides fields in CommonObject
1995  public $total_ht;
1996  public $total_tva;
1997  public $total_localtax1;
1998  public $total_localtax2;
1999  public $total_ttc;
2000 
2001  public $fk_unit;
2002  public $import_key;
2003  public $multicurrency_code;
2004  public $multicurrency_total_ht;
2005  public $multicurrency_total_tva;
2006  public $multicurrency_total_ttc;
2007  */
2008 
2009 
2017  public function delete(User $user, $notrigger = false)
2018  {
2019  $error = 0;
2020  $this->db->begin();
2021 
2022  if (! $error) {
2023  if (! $notrigger) {
2024  // Call triggers
2025  $result = $this->call_trigger('LINESUPPLIERBILLREC_DELETE', $user);
2026  if ($result < 0) {
2027  $error++;
2028  } // Do also here what you must do to rollback action if trigger fail
2029  // End call triggers
2030  }
2031  }
2032 
2033  if (! $error) {
2034  $result = $this->deleteExtraFields();
2035  if ($result < 0) {
2036  $error++;
2037  }
2038  }
2039 
2040  if (! $error) {
2041  $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element . ' WHERE rowid=' . (int) $this->id;
2042 
2043  $res = $this->db->query($sql);
2044  if ($res === false) {
2045  $error++;
2046  $this->errors[] = $this->db->lasterror();
2047  }
2048  }
2049 
2050  // Commit or rollback
2051  if ($error) {
2052  $this->db->rollback();
2053  return -1;
2054  } else {
2055  $this->db->commit();
2056  return 1;
2057  }
2058  }
2059 
2060 
2067  public function fetch($rowid)
2068  {
2069  $sql = 'SELECT l.rowid,';
2070  $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product,';
2071  $sql .= ' l.ref as ref_supplier, l.label, l.description, l.pu_ht, l.pu_ttc, l.qty, l.remise_percent, l.fk_remise_except,';
2072  $sql .= ' l.vat_src_code, l.tva_tx, l.localtax1_tx, l.localtax1_type, l.localtax2_tx, l.localtax2_type,';
2073  $sql .= ' l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc,';
2074  $sql .= ' l.product_type, l.date_start, l.date_end,';
2075  $sql .= ' l.info_bits, l.special_code, l.rang, l.fk_unit, l.import_key,';
2076  $sql .= ' l.fk_user_author, l.fk_user_modif, l.fk_multicurrency,';
2077  $sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2078  $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2079  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det_rec as l';
2080  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
2081  $sql .= ' WHERE l.rowid = '. (int) $rowid;
2082  $sql .= ' ORDER BY l.rang';
2083 
2084  dol_syslog('FactureRec::fetch', LOG_DEBUG);
2085  $result = $this->db->query($sql);
2086  if ($result) {
2087  $objp = $this->db->fetch_object($result);
2088 
2089  $this->id = $objp->rowid;
2090  $this->fk_facture_fourn = $objp->fk_facture_fourn;
2091  $this->fk_parent = $objp->fk_parent_line;
2092  $this->fk_product = $objp->fk_product;
2093  $this->ref_supplier = $objp->ref_supplier;
2094  $this->label = $objp->label;
2095  $this->description = $objp->description;
2096  $this->pu_ht = $objp->pu_ht;
2097  $this->pu_ttc = $objp->pu_ttc;
2098  $this->qty = $objp->qty;
2099  $this->remise_percent = $objp->remise_percent;
2100  $this->fk_remise_except = $objp->fk_remise_except;
2101  $this->vat_src_code = $objp->vat_src_code;
2102  $this->tva_tx = $objp->tva_tx;
2103  $this->localtax1_tx = $objp->localtax1_tx;
2104  $this->localtax1_type = $objp->localtax1_type;
2105  $this->localtax2_tx = $objp->localtax2_tx;
2106  $this->localtax2_type = $objp->localtax2_type;
2107  $this->total_ht = $objp->total_ht;
2108  $this->total_tva = $objp->total_tva;
2109  $this->total_localtax1 = $objp->total_localtax1;
2110  $this->total_localtax2 = $objp->total_localtax2;
2111  $this->total_ttc = $objp->total_ttc;
2112  $this->product_type = $objp->product_type;
2113  $this->date_start = $objp->date_start;
2114  $this->date_end = $objp->date_end;
2115  $this->info_bits = $objp->info_bits;
2116  $this->special_code = $objp->special_code;
2117  $this->rang = $objp->rang;
2118  $this->fk_unit = $objp->fk_unit;
2119  $this->import_key = $objp->import_key;
2120  $this->fk_user_author = $objp->fk_user_author;
2121  $this->fk_user_modif = $objp->fk_user_modif;
2122  $this->fk_multicurrency = $objp->fk_multicurrency;
2123  $this->multicurrency_code = $objp->multicurrency_code;
2124  $this->multicurrency_subprice = $objp->multicurrency_subprice;
2125  $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
2126  $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
2127  $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2128 
2129  $this->db->free($result);
2130  return 1;
2131  } else {
2132  $this->error = $this->db->lasterror();
2133  return -3;
2134  }
2135  }
2136 
2137 
2145  public function update(User $user, $notrigger = 0)
2146  {
2147  global $conf;
2148 
2149  $error = 0;
2150 
2151  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
2152 
2153  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
2154  $sql .= ' fk_facture_fourn = ' . (int) $this->fk_facture_fourn;
2155  $sql .= ', fk_parent_line = ' . (int) $this->fk_parent;
2156  $sql .= ', fk_product = ' . (int) $this->fk_product;
2157  $sql .= ', ref = ' . (!empty($this->ref) ? "'" . $this->db->escape($this->ref) . "'" : 'NULL');
2158  $sql .= ", label = " . (!empty($this->label) ? "'" . $this->db->escape($this->label) . "'" : 'NULL');
2159  $sql .= ", description = '" . $this->db->escape($this->description) . "'";
2160  $sql .= ', pu_ht = ' . price2num($this->pu_ht);
2161  $sql .= ', pu_ttc = ' . price2num($this->pu_ttc);
2162  $sql .= ', qty = ' . price2num($this->qty);
2163  $sql .= ", remise_percent = '" . price2num($this->remise_percent) . "'";
2164  $sql .= ', fk_remise_except = ' . (int) $this->fk_remise_except;
2165  $sql .= ", vat_src_code = '" . $this->db->escape($this->vat_src_code) . "'";
2166  $sql .= ', tva_tx = ' . price2num($this->tva_tx);
2167  $sql .= ', localtax1_tx = ' . price2num($this->localtax1_tx);
2168  $sql .= ", localtax1_type = '" . $this->db->escape($this->localtax1_type) . "'";
2169  $sql .= ', localtax2_tx = ' . price2num($this->localtax2_tx);
2170  $sql .= ", localtax2_type = '" . $this->db->escape($this->localtax2_type) . "'";
2171  if (empty($this->skip_update_total)) {
2172  $sql .= ', total_ht = ' . price2num($this->total_ht);
2173  $sql .= ', total_tva = ' . price2num($this->total_tva);
2174  $sql .= ', total_localtax1 = ' . price2num($this->total_localtax1);
2175  $sql .= ', total_localtax2 = ' . price2num($this->total_localtax2);
2176  $sql .= ', total_ttc = ' . price2num($this->total_ttc);
2177  }
2178  $sql .= ', product_type = ' . (int) $this->product_type;
2179  $sql .= ', date_start = ' . (int) $this->date_start;
2180  $sql .= ', date_end = ' . (int) $this->date_end;
2181  $sql .= ", info_bits = " . ((int) $this->info_bits);
2182  $sql .= ', special_code =' . (int) $this->special_code;
2183  $sql .= ', rang = ' . (int) $this->rang;
2184  $sql .= ', fk_unit = ' .($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : 'null');
2185  $sql .= ', fk_user_modif = ' . (int) $user;
2186  $sql .= ' WHERE rowid = ' . (int) $this->id;
2187 
2188  $this->db->begin();
2189 
2190  dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
2191  $resql = $this->db->query($sql);
2192  if ($resql) {
2193  if (!$error) {
2194  $result = $this->insertExtraFields();
2195  if ($result < 0) {
2196  $error++;
2197  }
2198  }
2199 
2200  if (!$error && !$notrigger) {
2201  // Call trigger
2202  $result = $this->call_trigger('LINESUPPLIERBILLREC_MODIFY', $user);
2203  if ($result < 0) {
2204  $error++;
2205  }
2206  // End call triggers
2207  }
2208 
2209  if ($error) {
2210  $this->db->rollback();
2211  return -2;
2212  } else {
2213  $this->db->commit();
2214  return 1;
2215  }
2216  } else {
2217  $this->error = $this->db->lasterror();
2218  $this->db->rollback();
2219  return -2;
2220  }
2221  }
2222 }
$object ref
Definition: info.php:78
Superclass for invoices classes.
const TYPE_STANDARD
Standard invoice.
calculate_date_lim_reglement($cond_reglement=0)
Returns an invoice payment deadline based on the invoice settlement conditions and billing date.
const STATUS_DRAFT
Draft status.
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...
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
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).
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class to manage suppliers invoices.
Class to manage supplier invoice lines of templates.
fetch($rowid)
Get line of template invoice.
update(User $user, $notrigger=0)
Update a line to supplier invoice template .
Class to manage invoice templates.
setModelPdf($model)
Update the model for documents.
fetch($rowid, $ref='', $ref_ext='')
Load object and lines.
strikeIfMaxNbGenReached($ret)
Format string to output with by striking the string if max number of generation was reached.
setFrequencyAndUnit($frequency, $unit)
Update frequency and unit.
create($user, $facFournId, $notrigger=0)
Create a predefined supplier invoice.
setGeneratePdf($validate)
Update the auto generate documents.
getLinesArray()
Create an array of invoice lines.
initAsSpecimen($option='')
Initialise an instance with random values.
LibStatut($recur, $status, $mode=0, $alreadypaid=-1, $type=0)
Return label of a status.
isMaxNbGenReached()
Return if maximum number of generation is reached.
setAutoValidate($validate)
Update the auto validate flag of invoice.
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $moretitle='', $notooltip='', $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
getNextDate()
Return the next date of.
fetch_lines()
Get lines of template invoices into this->lines.
getLibStatut($mode=0, $alreadypaid=-1)
Return label of object status.
setNextDate($date, $increment_nb_gen_done=0)
Update the next date of execution.
setMaxPeriod($nb)
Update the maximum period.
createRecurringInvoices($restrictioninvoiceid=0, $forcevalidation=0)
Create all recurrents supplier invoices (for all entities if multicompany is used).
update(User $user, $notrigger=0)
Update fourn_invoice_rec.
updateline($rowid, $fk_product, $ref, $label, $desc, $pu_ht, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $type=0, $date_start=0, $date_end=0, $info_bits=0, $special_code=0, $rang=-1, $fk_unit=null, $pu_ht_devise=0)
Update a line to supplier invoice template.
addline($fk_product, $ref, $label, $desc, $pu_ht, $pu_ttc, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $type=0, $date_start=0, $date_end=0, $info_bits=0, $special_code=0, $rang=-1, $fk_unit=null, $pu_ht_devise=0)
Add a line to recursive supplier invoice.
Class to manage invoice lines.
Class to manage products or services.
Class to manage Dolibarr users.
Definition: user.class.php:45
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("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->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:121
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
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...
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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(!defined( 'CSRFCHECK_WITH_TOKEN'))
div float
Buy price without taxes.
Definition: style.css.php:913
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
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
$conf db
API class for accounts.
Definition: inc.php:41