dolibarr  18.0.6
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'=>'isModEnabled("societe")', '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'=>'isModEnabled("banque")', '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'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105),
205  'note_public' =>array('type'=>'html', '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  $this->db->begin();
524 
525  dol_syslog(get_class($this)."::update", LOG_DEBUG);
526  $resql = $this->db->query($sql);
527  if ($resql) {
528  if (!$error) {
529  $result = $this->insertExtraFields();
530  if ($result < 0) {
531  $error++;
532  }
533  }
534 
535  if (!$error && !$notrigger) {
536  // Call trigger
537  $result = $this->call_trigger('SUPPLIERBILLREC_MODIFY', $user);
538  if ($result < 0) {
539  $this->db->rollback();
540  return -2;
541  }
542  // End call triggers
543  }
544  $this->db->commit();
545  return 1;
546  } else {
547  $this->error = $this->db->lasterror();
548  $this->db->rollback();
549  return -2;
550  }
551  }
552 
561  public function fetch($rowid, $ref = '', $ref_ext = '')
562  {
563  $sql = 'SELECT f.rowid, f.titre, f.ref_supplier, f.entity, f.fk_soc';
564  $sql .= ', f.datec, f.tms, f.suspended';
565  $sql .= ', f.libelle as label';
566  $sql .= ', f.vat_src_code, f.localtax1, f.localtax2';
567  $sql .= ', f.total_tva, f.total_ht, f.total_ttc';
568  $sql .= ', f.fk_user_author, f.fk_user_modif';
569  $sql .= ', f.fk_projet as fk_project, f.fk_account';
570  $sql .= ', f.fk_mode_reglement, p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
571  $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';
572  $sql .= ', f.date_lim_reglement';
573  $sql .= ', f.note_private, f.note_public, f.modelpdf';
574  $sql .= ', f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc';
575  $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';
576  $sql .= ', f.generate_pdf';
577  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_rec as f';
578  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
579  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
580  $sql .= ' WHERE f.entity IN ('.getEntity('invoice').')';
581  if ($rowid) {
582  $sql .= ' AND f.rowid='. (int) $rowid;
583  } elseif ($ref) {
584  $sql .= " AND f.titre='".$this->db->escape($ref)."'";
585  } else {
586  $sql .= ' AND f.rowid = 0';
587  }
588 
589  $result = $this->db->query($sql);
590  if ($result) {
591  if ($this->db->num_rows($result)) {
592  $obj = $this->db->fetch_object($result);
593 
594  $keyforref = $this->table_ref_field;
595 
596  $this->id = $obj->rowid;
597  $this->titre = $obj->titre;
598  $this->ref = $obj->$keyforref;
599  $this->ref_supplier = $obj->ref_supplier;
600  $this->entity = $obj->entity;
601  $this->socid = $obj->fk_soc;
602  $this->date_creation = $obj->datec;
603  $this->date_modification = $obj->tms;
604  $this->suspended = $obj->suspended;
605  $this->libelle = $obj->label;
606  $this->label = $obj->label;
607  $this->vat_src_code = $obj->vat_src_code;
608  $this->total_localtax1 = $obj->localtax1;
609  $this->total_localtax2 = $obj->localtax2;
610  $this->total_ht = $obj->total_ht;
611  $this->total_tva = $obj->total_tva;
612  $this->total_ttc = $obj->total_ttc;
613  $this->user_author = $obj->fk_user_author;
614  $this->user_modif = $obj->fk_user_modif;
615  $this->fk_project = $obj->fk_project;
616  $this->fk_account = $obj->fk_account;
617  $this->mode_reglement_id = $obj->fk_mode_reglement;
618  $this->mode_reglement_code = $obj->mode_reglement_code;
619  $this->mode_reglement = $obj->mode_reglement_libelle;
620  $this->cond_reglement_id = $obj->fk_cond_reglement;
621  $this->cond_reglement_code = $obj->cond_reglement_code;
622  $this->cond_reglement = $obj->cond_reglement_libelle;
623  $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
624  $this->date_lim_reglement = $this->db->jdate($obj->date_lim_reglement);
625  $this->note_private = $obj->note_private;
626  $this->note_public = $obj->note_public;
627  $this->model_pdf = $obj->modelpdf;
628 
629  // Multicurrency
630  $this->fk_multicurrency = $obj->fk_multicurrency;
631  $this->multicurrency_code = $obj->multicurrency_code;
632  $this->multicurrency_tx = $obj->multicurrency_tx;
633  $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
634  $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
635  $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
636 
637  $this->usenewprice = $obj->usenewprice;
638  $this->frequency = $obj->frequency;
639  $this->unit_frequency = $obj->unit_frequency;
640  $this->date_when = $this->db->jdate($obj->date_when);
641  $this->date_last_gen = $this->db->jdate($obj->date_last_gen);
642  $this->nb_gen_done = $obj->nb_gen_done;
643  $this->nb_gen_max = $obj->nb_gen_max;
644  $this->auto_validate = $obj->auto_validate;
645  $this->generate_pdf = $obj->generate_pdf;
646 
647 
648  if ($this->statut == self::STATUS_DRAFT) {
649  $this->brouillon = 1;
650  }
651 
652  // Retrieve all extrafield
653  // fetch optionals attributes and labels
654  $this->fetch_optionals();
655 
656  /*
657  * Lines
658  */
659  $result = $this->fetch_lines();
660  if ($result < 0) {
661  $this->error = $this->db->lasterror();
662  return -3;
663  }
664  return 1;
665  } else {
666  $this->error = 'Bill with id '.$rowid.' or ref '.$ref.' not found';
667  dol_syslog('Facture::Fetch Error '.$this->error, LOG_ERR);
668  return -2;
669  }
670  } else {
671  $this->error = $this->db->error();
672  return -1;
673  }
674  }
675 
676 
682  public function getLinesArray()
683  {
684  return $this->fetch_lines();
685  }
686 
687  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
693  public function fetch_lines()
694  {
695  // phpcs:enable
696  $this->lines = array();
697 
698  // Retrieve all extrafield for line
699  // fetch optionals attributes and labels
700  /*if (!is_object($extrafields)) {
701  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
702  $extrafields = new ExtraFields($this->db);
703  }
704  $extrafields->fetch_name_optionals_label($this->table_element_line, true);
705  */
706 
707  $sql = 'SELECT l.rowid,';
708  $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product, l.ref, l.label, l.description,';
709  $sql .= ' l.pu_ht, l.pu_ttc, l.qty, l.remise_percent, l.fk_remise_except, l.vat_src_code, l.tva_tx,';
710  $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type,';
711  $sql .= ' l.total_ht, l.total_tva, l.total_ttc, total_localtax1, total_localtax2,';
712  $sql .= ' l.product_type, l.date_start, l.date_end,';
713  $sql .= ' l.info_bits, l.special_code, l.rang,';
714  $sql .= ' l.fk_unit, l.import_key, l.fk_user_author, l.fk_user_modif,';
715  $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
716  $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
717  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det_rec as l';
718  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
719  $sql .= ' WHERE l.fk_facture_fourn = '. (int) $this->id;
720  $sql .= ' ORDER BY l.rang';
721 
722  dol_syslog('FactureFournisseurRec::fetch_lines', LOG_DEBUG);
723 
724  $result = $this->db->query($sql);
725  if ($result) {
726  $num = $this->db->num_rows($result);
727  $i = 0;
728  while ($i < $num) {
729  $objp = $this->db->fetch_object($result);
730 
731  $line = new FactureFournisseurLigneRec($this->db);
732 
733  $line->id = $objp->rowid;
734  $line->fk_facture_fourn = $objp->fk_facture_fourn;
735  $line->fk_parent = $objp->fk_parent_line;
736  $line->fk_product = $objp->fk_product;
737  $line->ref_supplier = $objp->ref;
738  $line->label = $objp->label;
739  $line->description = $objp->description;
740  $line->pu_ht = $objp->pu_ht;
741  $line->pu_ttc = $objp->pu_ttc;
742  $line->qty = $objp->qty;
743  $line->remise_percent = $objp->remise_percent;
744  $line->fk_remise_except = $objp->fk_remise_except;
745  $line->vat_src_code = $objp->vat_src_code;
746  $line->tva_tx = $objp->tva_tx;
747  $line->localtax1_tx = $objp->localtax1_tx;
748  $line->localtax1_type = $objp->localtax1_type;
749  $line->localtax2_tx = $objp->localtax2_tx;
750  $line->localtax2_type = $objp->localtax2_type;
751  $line->total_ht = $objp->total_ht;
752  $line->total_tva = $objp->total_tva;
753  $line->total_localtax1 = $objp->total_localtax1;
754  $line->total_localtax2 = $objp->total_localtax2;
755  $line->total_ttc = $objp->total_ttc;
756  $line->product_type = $objp->product_type;
757  $line->date_start = $objp->date_start;
758  $line->date_end = $objp->date_end;
759  $line->info_bits = $objp->info_bits ;
760  $line->special_code = $objp->special_code;
761  $line->rang = $objp->rang;
762  $line->fk_unit = $objp->fk_unit;
763  $line->import_key = $objp->import_key;
764  $line->fk_user_author = $objp->fk_user_author;
765  $line->fk_user_modif = $objp->fk_user_modif;
766  $line->fk_multicurrency = $objp->fk_multicurrency;
767  $line->multicurrency_code = $objp->multicurrency_code;
768  $line->multicurrency_subprice = $objp->multicurrency_subprice;
769  $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
770  $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
771  $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
772 
773  $line->fetch_optionals();
774 
775  $this->lines[$i] = $line;
776 
777  $i++;
778  }
779 
780  $this->db->free($result);
781  return 1;
782  } else {
783  $this->error = $this->db->lasterror();
784  return -3;
785  }
786  }
787 
788 
797  public function delete(User $user, $notrigger = 0, $idwarehouse = -1)
798  {
799  $rowid = $this->id;
800 
801  dol_syslog(get_class($this)."::delete rowid=".((int) $rowid), LOG_DEBUG);
802 
803  $error = 0;
804  $this->db->begin();
805 
806  $main = MAIN_DB_PREFIX.'facture_fourn_det_rec';
807  $ef = $main."_extrafields";
808 
809  $sqlef = "DELETE FROM ".$ef." WHERE fk_object IN (SELECT rowid FROM ".$main." WHERE fk_facture_fourn = ". (int) $rowid .")";
810  $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_fourn_det_rec WHERE fk_facture_fourn = ". (int) $rowid;
811 
812  if ($this->db->query($sqlef) && $this->db->query($sql)) {
813  $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_fourn_rec WHERE rowid = ". (int) $rowid;
814  dol_syslog($sql);
815  if ($this->db->query($sql)) {
816  // Delete linked object
817  $res = $this->deleteObjectLinked();
818  if ($res < 0) {
819  $error = -3;
820  }
821  // Delete extrafields
822  $res = $this->deleteExtraFields();
823  if ($res < 0) {
824  $error = -4;
825  }
826  } else {
827  $this->error = $this->db->lasterror();
828  $error = -1;
829  }
830  } else {
831  $this->error = $this->db->lasterror();
832  $error = -2;
833  }
834  if (!$error && !$notrigger) {
835  // Call trigger
836  $result = $this->call_trigger('SUPPLIERBILLREC_DELETE', $user);
837  if ($result < 0) {
838  $error++;
839  }
840  // End call triggers
841  }
842  if (! $error) {
843  $this->db->commit();
844  return 1;
845  } else {
846  $this->db->rollback();
847  return $error;
848  }
849  }
850 
877  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)
878  {
879  global $mysoc, $user;
880 
881  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
882 
883  $facid = $this->id; //Supplier invoice template ID linked to
884 
885  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);
886 
887  // Check if object of the line is product or service
888  if ($type < 0) {
889  return -1;
890  }
891 
892  if ($this->suspended == self::STATUS_NOTSUSPENDED) {
893  $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
894 
895  // Clean vat code
896  $reg = array();
897  $vat_src_code = '';
898  if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
899  $vat_src_code = $reg[1];
900  $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
901  }
902 
903  // Clean parameters
904  $fk_product = empty($fk_product) ? 0 : $fk_product;
905  $label = empty($label) ? '' : $label;
906  $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
907  $qty = price2num($qty);
908  $pu_ht = price2num($pu_ht);
909  $pu_ttc = price2num($pu_ttc);
910  if (!preg_match('/\‍((.*)\‍)/', $txtva)) {
911  $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
912  }
913  $txlocaltax1 = price2num($txlocaltax1);
914  $txlocaltax2 = price2num($txlocaltax2);
915  $txtva = !empty($txtva) ? $txtva : 0;
916  $txlocaltax1 = !empty($txlocaltax1) ? $txlocaltax1 : 0;
917  $txlocaltax2 = !empty($txlocaltax2) ? $txlocaltax2 : 0;
918  $info_bits = !empty($info_bits) ? $info_bits : 0;
919  $info_bits = !empty($info_bits) ? $info_bits : 0;
920  $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
921 
922  // Calcul du total TTC et de la TVA pour la ligne a partir de qty, pu, remise_percent et txtva
923  // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
924  // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
925 
926  $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);
927  $total_ht = $tabprice[0];
928  $total_tva = $tabprice[1];
929  $total_ttc = $tabprice[2];
930  $total_localtax1 = $tabprice[9];
931  $total_localtax2 = $tabprice[10];
932  $pu_ht = $tabprice[3];
933 
934  // MultiCurrency
935  $multicurrency_total_ht = $tabprice[16];
936  $multicurrency_total_tva = $tabprice[17];
937  $multicurrency_total_ttc = $tabprice[18];
938  $pu_ht_devise = $tabprice[19];
939 
940  $this->db->begin();
941  $product_type = $type;
942  if ($fk_product) {
943  $product = new Product($this->db);
944  $result = $product->fetch($fk_product);
945  if ($result < 0) {
946  return -1;
947  }
948  $product_type = $product->type;
949  if (empty($label)) {
950  $label = $product->label;
951  }
952  }
953 
954  $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec (';
955  $sql .= 'fk_facture_fourn';
956  $sql .= ', fk_product';
957  $sql .= ', ref';
958  $sql .= ', label';
959  $sql .= ', description';
960  $sql .= ', pu_ht';
961  $sql .= ', pu_ttc';
962  $sql .= ', qty';
963  $sql .= ', remise_percent';
964  $sql .= ', fk_remise_except';
965  $sql .= ', vat_src_code';
966  $sql .= ', tva_tx';
967  $sql .= ', localtax1_tx';
968  $sql .= ', localtax1_type';
969  $sql .= ', localtax2_tx';
970  $sql .= ', localtax2_type';
971  $sql .= ', total_ht';
972  $sql .= ', total_tva';
973  $sql .= ', total_localtax1';
974  $sql .= ', total_localtax2';
975  $sql .= ', total_ttc';
976  $sql .= ', product_type';
977  $sql .= ', date_start';
978  $sql .= ', date_end';
979  $sql .= ', info_bits';
980  $sql .= ', special_code';
981  $sql .= ', rang';
982  $sql .= ', fk_unit';
983  $sql .= ', fk_user_author';
984  $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
985  $sql .= ') VALUES (';
986  $sql .= ' ' . (int) $facid; // source supplier invoice id
987  $sql .= ', ' . (!empty($fk_product) ? "'" . $this->db->escape($fk_product) . "'" : 'null');
988  $sql .= ', ' . (!empty($ref) ? "'" . $this->db->escape($ref) . "'" : 'null');
989  $sql .= ', ' . (!empty($label) ? "'" . $this->db->escape($label) . "'" : 'null');
990  $sql .= ", '" . $this->db->escape($desc) . "'";
991  $sql .= ', ' . price2num($pu_ht);
992  $sql .= ', ' . price2num($pu_ttc);
993  $sql .= ', ' . price2num($qty);
994  $sql .= ', ' . price2num($remise_percent);
995  $sql .= ', null';
996  $sql .= ", '" . $this->db->escape($vat_src_code) . "'";
997  $sql .= ', ' . price2num($txtva);
998  $sql .= ', ' . price2num($txlocaltax1);
999  $sql .= ", '" . $this->db->escape(isset($localtaxes_type[0]) ? $localtaxes_type[0] : '') . "'";
1000  $sql .= ', ' . price2num($txlocaltax2);
1001  $sql .= ", '" . $this->db->escape(isset($localtaxes_type[2]) ? $localtaxes_type[2] : '') . "'";
1002  $sql .= ', ' . price2num($total_ht);
1003  $sql .= ', ' . price2num($total_tva);
1004  $sql .= ', ' . price2num($total_localtax1);
1005  $sql .= ', ' . price2num($total_localtax2);
1006  $sql .= ', ' . price2num($total_ttc);
1007  $sql .= ', ' . (int) $product_type;
1008  $sql .= ', ' . ($date_start > 0 ? (int) $date_start : 'NULL');
1009  $sql .= ', ' . ($date_end > 0 ? (int) $date_end : 'NULL');
1010  $sql .= ', ' . (int) $info_bits;
1011  $sql .= ', ' . (int) $special_code;
1012  $sql .= ', ' . (int) $rang;
1013  $sql .= ', ' . ($fk_unit ? (int) $fk_unit : 'NULL');
1014  $sql .= ', ' . (int) $user->id;
1015  $sql .= ', ' . (int) $this->fk_multicurrency;
1016  $sql .= ", '" . $this->db->escape($this->multicurrency_code) . "'";
1017  $sql .= ', ' . price2num($pu_ht_devise, 'CU');
1018  $sql .= ', ' . price2num($multicurrency_total_ht, 'CT');
1019  $sql .= ', ' . price2num($multicurrency_total_tva, 'CT');
1020  $sql .= ', ' . price2num($multicurrency_total_ttc, 'CT');
1021  $sql .= ')';
1022 
1023  dol_syslog(get_class($this). '::addline', LOG_DEBUG);
1024  if ($this->db->query($sql)) {
1025  $lineId = $this->db->last_insert_id(MAIN_DB_PREFIX. 'facture_fourn_det_rec');
1026  $this->update_price();
1027  $this->id = $facid;
1028  $this->db->commit();
1029  return $lineId;
1030  } else {
1031  $this->db->rollback();
1032  $this->error = $this->db->lasterror();
1033 
1034  return -1;
1035  }
1036  } else {
1037  $this->error = 'Recurring Invoice is suspended. adding lines not allowed.';
1038 
1039  return -1;
1040  }
1041  }
1042 
1069  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)
1070  {
1071  global $mysoc, $user;
1072 
1073  $facid = $this->id;
1074 
1075  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);
1076  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
1077 
1078  // Check parameters
1079  if ($type < 0) {
1080  return -1;
1081  }
1082 
1083  if ($this->brouillon) {
1084  // Clean parameters
1085  $fk_product = empty($fk_product) ? 0 : $fk_product;
1086  $label = empty($label) ? '' : $label;
1087  $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
1088  $qty = price2num($qty);
1089  $info_bits = empty($info_bits) ? 0 : $info_bits;
1090  $pu_ht = price2num($pu_ht);
1091  $pu_ttc = price2num($pu_ttc);
1092  $pu_ht_devise = price2num($pu_ht_devise);
1093 
1094  if (!preg_match('/\‍((.*)\‍)/', $txtva)) {
1095  $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
1096  }
1097 
1098  $txlocaltax1 = empty($txlocaltax1) ? 0 : price2num($txlocaltax1);
1099  $txlocaltax2 = empty($txlocaltax2) ? 0 : price2num($txlocaltax2);
1100  $this->multicurrency_subprice = empty($this->multicurrency_subprice) ? 0 : $this->multicurrency_subprice;
1101  $this->multicurrency_total_ht = empty($this->multicurrency_total_ht) ? 0 : $this->multicurrency_total_ht;
1102  $this->multicurrency_total_tva = empty($this->multicurrency_total_tva) ? 0 : $this->multicurrency_total_tva;
1103  $this->multicurrency_total_ttc = empty($this->multicurrency_total_ttc) ? 0 : $this->multicurrency_total_ttc;
1104 
1105  $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
1106 
1107 
1108  // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
1109  // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1110  // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1111 
1112  $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
1113 
1114  // Clean vat code
1115  $vat_src_code = '';
1116  $reg = array();
1117  if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
1118  $vat_src_code = $reg[1];
1119  $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
1120  }
1121 
1122  $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);
1123 
1124  $total_ht = $tabprice[0];
1125  $total_tva = $tabprice[1];
1126  $total_ttc = $tabprice[2];
1127  $total_localtax1 = $tabprice[9];
1128  $total_localtax2 = $tabprice[10];
1129  $pu_ht = $tabprice[3];
1130  $pu_tva = $tabprice[4];
1131  $pu_ttc = $tabprice[5];
1132 
1133  // MultiCurrency
1134  $multicurrency_total_ht = $tabprice[16];
1135  $multicurrency_total_tva = $tabprice[17];
1136  $multicurrency_total_ttc = $tabprice[18];
1137  $pu_ht_devise = $tabprice[19];
1138 
1139  $product_type = $type;
1140  if ($fk_product) {
1141  $product = new Product($this->db);
1142  $result = $product->fetch($fk_product);
1143  $product_type = $product->type;
1144  }
1145 
1146  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
1147  $sql .= ' fk_facture_fourn = ' . ((int) $facid);
1148  $sql .= ', fk_product = ' . ($fk_product > 0 ? ((int) $fk_product) : 'null');
1149  $sql .= ", ref = '" . $this->db->escape($ref) . "'";
1150  $sql .= ", label = '" . $this->db->escape($label) . "'";
1151  $sql .= ", description = '" . $this->db->escape($desc) . "'";
1152  $sql .= ', pu_ht = ' . price2num($pu_ht);
1153  $sql .= ', qty = ' . price2num($qty);
1154  $sql .= ", remise_percent = '" . price2num($remise_percent) . "'";
1155  $sql .= ", vat_src_code = '" . $this->db->escape($vat_src_code) . "'";
1156  $sql .= ', tva_tx = ' . price2num($txtva);
1157  $sql .= ', localtax1_tx = ' . (float) $txlocaltax1;
1158  $sql .= ", localtax1_type = '" . $this->db->escape($localtaxes_type[0]) . "'";
1159  $sql .= ', localtax2_tx = ' . (float) $txlocaltax2;
1160  $sql .= ", localtax2_type = '" . $this->db->escape($localtaxes_type[2]) . "'";
1161  $sql .= ", total_ht = '" . price2num($total_ht) . "'";
1162  $sql .= ", total_tva = '" . price2num($total_tva) . "'";
1163  $sql .= ", total_localtax1 = '" . price2num($total_localtax1) . "'";
1164  $sql .= ", total_localtax2 = '" . price2num($total_localtax2) . "'";
1165  $sql .= ", total_ttc = '" . price2num($total_ttc) . "'";
1166  $sql .= ', product_type = ' . (int) $product_type;
1167  $sql .= ', date_start = ' . (empty($date_start) ? 'NULL' : (int) $date_start);
1168  $sql .= ', date_end = ' . (empty($date_end) ? 'NULL' : (int) $date_end);
1169  $sql .= ', info_bits = ' . (int) $info_bits;
1170  $sql .= ', special_code = ' . (int) $special_code;
1171  $sql .= ', rang = ' . (int) $rang;
1172  $sql .= ', fk_unit = ' . ($fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : 'null');
1173  $sql .= ', fk_user_modif = ' . (int) $user;
1174  $sql .= ', multicurrency_subprice = '.price2num($pu_ht_devise);
1175  $sql .= ', multicurrency_total_ht = '.price2num($multicurrency_total_ht);
1176  $sql .= ', multicurrency_total_tva = '.price2num($multicurrency_total_tva);
1177  $sql .= ', multicurrency_total_ttc = '.price2num($multicurrency_total_ttc);
1178  $sql .= ' WHERE rowid = ' . (int) $rowid;
1179 
1180  dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
1181  if ($this->db->query($sql)) {
1182  $this->id = $facid;
1183  $this->update_price();
1184  return 1;
1185  } else {
1186  $this->error = $this->db->lasterror();
1187  return -1;
1188  }
1189  }
1190  }
1191 
1192 
1198  public function getNextDate()
1199  {
1200  if (empty($this->date_when)) {
1201  return false;
1202  }
1203  return dol_time_plus_duree($this->date_when, $this->frequency, $this->unit_frequency);
1204  }
1205 
1211  public function isMaxNbGenReached()
1212  {
1213  $ret = false;
1214  if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) {
1215  $ret = true;
1216  }
1217  return $ret;
1218  }
1219 
1226  public function strikeIfMaxNbGenReached($ret)
1227  {
1228  // Special case to strike the date
1229  return ($this->isMaxNbGenReached() ? '<strike>' : '').$ret.($this->isMaxNbGenReached() ? '</strike>' : '');
1230  }
1231 
1242  public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0)
1243  {
1244  global $conf, $langs, $db, $user, $hookmanager;
1245 
1246  $error = 0;
1247  $nb_create = 0;
1248 
1249  // Load translation files required by the page
1250  $langs->loadLangs(array('main', 'bills'));
1251 
1252  $now = dol_now();
1253  $tmparray = dol_getdate($now);
1254  $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
1255 
1256  dol_syslog('createRecurringInvoices restrictioninvoiceid=' .$restrictioninvoiceid. ' forcevalidation=' .$forcevalidation);
1257 
1258  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_fourn_rec';
1259  $sql .= ' WHERE frequency > 0'; // A recurring supplier invoice is an invoice with a frequency
1260  $sql .= " AND (date_when IS NULL OR date_when <= '".$this->db->idate($today)."')";
1261  $sql .= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)';
1262  $sql .= ' AND suspended = 0';
1263  $sql .= ' AND entity = '. (int) $conf->entity; // MUST STAY = $conf->entity here
1264  if ($restrictioninvoiceid > 0) {
1265  $sql .= ' AND rowid = '. (int) $restrictioninvoiceid;
1266  }
1267  $sql .= $this->db->order('entity', 'ASC');
1268  //print $sql;exit;
1269  $parameters = array(
1270  'restrictioninvoiceid' => $restrictioninvoiceid,
1271  'forcevalidation' => $forcevalidation,
1272  );
1273  $reshook = $hookmanager->executeHooks('beforeCreationOfRecurringInvoices', $parameters, $sql); // note that $sql might be modified by hooks
1274 
1275  $resql = $this->db->query($sql);
1276  if ($resql) {
1277  $i = 0;
1278  $num = $this->db->num_rows($resql);
1279 
1280  if ($num) {
1281  $this->output .= $langs->trans('FoundXQualifiedRecurringInvoiceTemplate', $num)."\n";
1282  } else {
1283  $this->output .= $langs->trans('NoQualifiedRecurringInvoiceTemplateFound');
1284  }
1285 
1286  $saventity = $conf->entity;
1287  $laststep="None";
1288 
1289  while ($i < $num) { // Loop on each template invoice. If $num = 0, test is false at first pass.
1290  $line = $this->db->fetch_object($resql);
1291 
1292  $this->db->begin();
1293 
1294  $invoiceidgenerated = 0;
1295 
1296  $new_fac_fourn = null;
1297  $facturerec = new FactureFournisseurRec($this->db);
1298  $laststep="Fetch {$line->rowid}";
1299  $facturerec->fetch($line->rowid);
1300 
1301  if ($facturerec->id > 0) {
1302  // Set entity context
1303  $conf->entity = $facturerec->entity;
1304 
1305  dol_syslog('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', ref=' .$facturerec->ref. ', entity=' .$facturerec->entity);
1306 
1307  $new_fac_fourn = new FactureFournisseur($this->db);
1308  $new_fac_fourn->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice
1309  $new_fac_fourn->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice
1310 
1311  $new_fac_fourn->type = self::TYPE_STANDARD;
1312  $new_fac_fourn->brouillon = 1;
1313  $new_fac_fourn->statut = self::STATUS_DRAFT;
1314  $new_fac_fourn->status = self::STATUS_DRAFT;
1315  $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.
1316  $new_fac_fourn->socid = $facturerec->socid;
1317  $new_fac_fourn->lines = $facturerec->lines;
1318  $new_fac_fourn->ref_supplier = $facturerec->ref_supplier;
1319  $new_fac_fourn->model_pdf = $facturerec->model_pdf;
1320  $new_fac_fourn->fk_project = $facturerec->fk_project;
1321  $new_fac_fourn->libelle = $facturerec->libelle;
1322 
1323  $invoiceidgenerated = $new_fac_fourn->create($user);
1324  $laststep="Create invoiceidgenerated $invoiceidgenerated";
1325  if ($invoiceidgenerated <= 0) {
1326  $this->errors = $new_fac_fourn->errors;
1327  $this->error = $new_fac_fourn->error;
1328  $error++;
1329  }
1330  if (!$error && ($facturerec->auto_validate || $forcevalidation)) {
1331  $result = $new_fac_fourn->validate($user);
1332  $laststep = "Validate by user {$user->login}";
1333  if ($result <= 0) {
1334  $this->errors = $new_fac_fourn->errors;
1335  $this->error = $new_fac_fourn->error;
1336  $error++;
1337  }
1338  }
1339 
1340  if (!$error && $facturerec->generate_pdf) {
1341  // We refresh the object in order to have all necessary data (like date_lim_reglement)
1342  $laststep = "Refresh {$new_fac_fourn->id}";
1343  $new_fac_fourn->fetch($new_fac_fourn->id);
1344  $laststep = "GenerateDocument {$new_fac_fourn->id}";
1345  $result = $new_fac_fourn->generateDocument($facturerec->model_pdf, $langs);
1346  if ($result < 0) {
1347  $this->errors = $new_fac_fourn->errors;
1348  $this->error = $new_fac_fourn->error;
1349  $error++;
1350  }
1351  }
1352  } else {
1353  $error++;
1354  $this->error = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity."\n";
1355  $this->errors[] = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity;
1356  dol_syslog('createRecurringInvoices Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity);
1357  }
1358 
1359  if (!$error && $invoiceidgenerated >= 0) {
1360  $facturerec->nb_gen_done++;
1361  $facturerec->date_last_gen = dol_now();
1362  $facturerec->date_when= $facturerec->getNextDate();
1363  $facturerec->update($user);
1364  $this->db->commit('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', title=' .$facturerec->titre);
1365  dol_syslog('createRecurringInvoices Process invoice template ' .$facturerec->titre. ' is finished with a success generation');
1366  $nb_create++;
1367  $this->output .= $langs->trans('InvoiceGeneratedFromTemplate', $new_fac_fourn->ref, $facturerec->titre)."\n";
1368  } else {
1369  $this->db->rollback('createRecurringInvoices Process invoice template error={$error} invoiceidgenerated={$invoiceidgenerated} LastStep={$laststep} id=' .$facturerec->id. ', title=' .$facturerec->titre);
1370  }
1371 
1372  $parameters = array(
1373  'cpt' => $i,
1374  'total' => $num,
1375  'errorCount' => $error,
1376  'invoiceidgenerated' => $invoiceidgenerated,
1377  'facturerec' => $facturerec, // it's an object which PHP passes by "reference", so modifiable by hooks.
1378  'this' => $this, // it's an object which PHP passes by "reference", so modifiable by hooks.
1379  );
1380  $reshook = $hookmanager->executeHooks('afterCreationOfRecurringInvoice', $parameters, $new_fac_fourn); // note: $facture can be modified by hooks (warning: $facture can be null)
1381 
1382  $i++;
1383  }
1384 
1385  $conf->entity = $saventity; // Restore entity context
1386  } else {
1387  dol_print_error($this->db);
1388  }
1389 
1390  $this->output = trim($this->output);
1391 
1392  return $error ? $error : 0;
1393  }
1394 
1407  public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = '', $save_lastsearch_value = -1)
1408  {
1409  global $langs, $hookmanager;
1410 
1411  $result = '';
1412 
1413  $label = '<u>'.$langs->trans('RepeatableInvoice').'</u>';
1414  if (!empty($this->ref)) {
1415  $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1416  }
1417  if ($this->frequency > 0) {
1418  $label .= '<br><b>'.$langs->trans('Frequency').':</b> '.$langs->trans('FrequencyPer_'.$this->unit_frequency, $this->frequency);
1419  }
1420  if (!empty($this->date_last_gen)) {
1421  $label .= '<br><b>'.$langs->trans('DateLastGeneration').':</b> '.dol_print_date($this->date_last_gen, 'dayhour');
1422  }
1423  if ($this->frequency > 0) {
1424  if (!empty($this->date_when)) {
1425  $label .= '<br><b>'.$langs->trans('NextDateToExecution').':</b> ';
1426  $label .= (empty($this->suspended) ? '' : '<strike>').dol_print_date($this->date_when, 'day').(empty($this->suspended) ? '' : '</strike>'); // No hour for this property
1427  if (!empty($this->suspended)) {
1428  $label .= ' ('.$langs->trans('Disabled').')';
1429  }
1430  }
1431  }
1432 
1433  $url = DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$this->id;
1434 
1435  if ($short) {
1436  return $url;
1437  }
1438 
1439  if ($option != 'nolink') {
1440  // Add param to save lastsearch_values or not
1441  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1442  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER['PHP_SELF'])) {
1443  $add_save_lastsearch_values = 1;
1444  }
1445  if ($add_save_lastsearch_values) {
1446  $url .= '&save_lastsearch_values=1';
1447  }
1448  }
1449 
1450  $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
1451  $linkend = '</a>';
1452 
1453  $result .= $linkstart;
1454  if ($withpicto) {
1455  $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);
1456  }
1457  if ($withpicto != 2) {
1458  $result .= $this->ref;
1459  }
1460  $result .= $linkend;
1461  global $action;
1462  $hookmanager->initHooks(array($this->element . 'dao'));
1463  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1464  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1465  if ($reshook > 0) {
1466  $result = $hookmanager->resPrint;
1467  } else {
1468  $result .= $hookmanager->resPrint;
1469  }
1470  return $result;
1471  }
1472 
1480  public function getLibStatut($mode = 0, $alreadypaid = -1)
1481  {
1482  return $this->LibStatut($this->frequency ? 1 : 0, $this->suspended, $mode, $alreadypaid, empty($this->type) ? 0 : $this->type);
1483  }
1484 
1485  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1496  public function LibStatut($recur, $status, $mode = 0, $alreadypaid = -1, $type = 0)
1497  {
1498  // phpcs:enable
1499  global $langs;
1500  $langs->load('bills');
1501 
1502  $labelStatus = $langs->transnoentitiesnoconv('Active');
1503  $statusType = 'status0';
1504 
1505  //print "$recur,$status,$mode,$alreadypaid,$type";
1506  if ($mode == 0) {
1507  if ($recur) {
1508  if ($status == self::STATUS_SUSPENDED) {
1509  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1510  } else {
1511  $labelStatus = $langs->transnoentitiesnoconv('Active');
1512  }
1513  } else {
1514  if ($status == self::STATUS_SUSPENDED) {
1515  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1516  } else {
1517  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1518  }
1519  }
1520  } elseif ($mode == 1) {
1521  $prefix = 'Short';
1522  if ($recur) {
1523  if ($status == self::STATUS_SUSPENDED) {
1524  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1525  } else {
1526  $labelStatus = $langs->transnoentitiesnoconv('Active');
1527  }
1528  } else {
1529  if ($status == self::STATUS_SUSPENDED) {
1530  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1531  } else {
1532  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1533  }
1534  }
1535  } elseif ($mode == 2) {
1536  if ($recur) {
1537  if ($status == self::STATUS_SUSPENDED) {
1538  $statusType = 'status6';
1539  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1540  } else {
1541  $statusType = 'status4';
1542  $labelStatus = $langs->transnoentitiesnoconv('Active');
1543  }
1544  } else {
1545  if ($status == self::STATUS_SUSPENDED) {
1546  $statusType = 'status6';
1547  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1548  } else {
1549  $statusType = 'status0';
1550  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1551  }
1552  }
1553  } elseif ($mode == 3) {
1554  if ($recur) {
1555  $prefix = 'Short';
1556  if ($status == self::STATUS_SUSPENDED) {
1557  $statusType = 'status6';
1558  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1559  } else {
1560  $statusType = 'status4';
1561  $labelStatus = $langs->transnoentitiesnoconv('Active');
1562  }
1563  } else {
1564  if ($status == self::STATUS_SUSPENDED) {
1565  $statusType = 'status6';
1566  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1567  } else {
1568  $statusType = 'status0';
1569  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1570  }
1571  }
1572  } elseif ($mode == 4) {
1573  $prefix = '';
1574  if ($recur) {
1575  if ($status == self::STATUS_SUSPENDED) {
1576  $statusType = 'status6';
1577  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1578  } else {
1579  $statusType = 'status4';
1580  $labelStatus = $langs->transnoentitiesnoconv('Active');
1581  }
1582  } else {
1583  if ($status == self::STATUS_SUSPENDED) {
1584  $statusType = 'status6';
1585  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1586  } else {
1587  $statusType = 'status0';
1588  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1589  }
1590  }
1591  } elseif ($mode == 5 || $mode == 6) {
1592  $prefix = '';
1593  if ($mode == 5) {
1594  $prefix = 'Short';
1595  }
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  }
1614 
1615  $labelStatusShort = $labelStatus;
1616 
1617  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1618  }
1619 
1628  public function initAsSpecimen($option = '')
1629  {
1630  global $user, $langs, $conf;
1631 
1632  $now = dol_now();
1633  $arraynow = dol_getdate($now);
1634  $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1635 
1636  // Load array of products prodids
1637  $num_prods = 0;
1638  $prodids = array();
1639 
1640  $sql = 'SELECT rowid';
1641  $sql .= ' FROM ' .MAIN_DB_PREFIX. 'product';
1642  $sql .= ' WHERE entity IN (' .getEntity('product'). ')';
1643  $sql .= $this->db->plimit(100);
1644 
1645  $resql = $this->db->query($sql);
1646  if ($resql) {
1647  $num_prods = $this->db->num_rows($resql);
1648  $i = 0;
1649  while ($i < $num_prods) {
1650  $i++;
1651  $row = $this->db->fetch_row($resql);
1652  $prodids[$i] = $row[0];
1653  }
1654  }
1655 
1656  // Initialize parameters
1657  $this->id = 0;
1658  $this->ref = 'SPECIMEN';
1659  $this->title = 'SPECIMEN';
1660  $this->specimen = 1;
1661  $this->socid = 1;
1662  $this->date = $nownotime;
1663  $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
1664  $this->cond_reglement_id = 1;
1665  $this->cond_reglement_code = 'RECEP';
1666  $this->date_lim_reglement = $this->calculate_date_lim_reglement();
1667  $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR
1668  $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
1669  $this->note_public = 'This is a comment (public)';
1670  $this->note_private = 'This is a comment (private)';
1671  $this->note = 'This is a comment (private)';
1672  $this->fk_incoterms = 0;
1673  $this->location_incoterms = '';
1674 
1675  if (empty($option) || $option != 'nolines') {
1676  // Lines
1677  $nbp = 5;
1678  $xnbp = 0;
1679  while ($xnbp < $nbp) {
1680  $line = new FactureLigne($this->db);
1681  $line->desc = $langs->trans('Description'). ' ' .$xnbp;
1682  $line->qty = 1;
1683  $line->subprice = 100;
1684  $line->tva_tx = 19.6;
1685  $line->localtax1_tx = 0;
1686  $line->localtax2_tx = 0;
1687  $line->remise_percent = 0;
1688  if ($xnbp == 1) { // Qty is negative (product line)
1689  $prodid = mt_rand(1, $num_prods);
1690  $line->fk_product = $prodids[$prodid];
1691  $line->qty = -1;
1692  $line->total_ht = -100;
1693  $line->total_ttc = -119.6;
1694  $line->total_tva = -19.6;
1695  } elseif ($xnbp == 2) { // UP is negative (free line)
1696  $line->subprice = -100;
1697  $line->total_ht = -100;
1698  $line->total_ttc = -119.6;
1699  $line->total_tva = -19.6;
1700  $line->remise_percent = 0;
1701  } elseif ($xnbp == 3) { // Discount is 50% (product line)
1702  $prodid = mt_rand(1, $num_prods);
1703  $line->fk_product = $prodids[$prodid];
1704  $line->total_ht = 50;
1705  $line->total_ttc = 59.8;
1706  $line->total_tva = 9.8;
1707  $line->remise_percent = 50;
1708  } else // (product line)
1709  {
1710  $prodid = mt_rand(1, $num_prods);
1711  $line->fk_product = $prodids[$prodid];
1712  $line->total_ht = 100;
1713  $line->total_ttc = 119.6;
1714  $line->total_tva = 19.6;
1715  $line->remise_percent = 00;
1716  }
1717 
1718  $this->lines[$xnbp] = $line;
1719  $xnbp++;
1720 
1721  $this->total_ht += $line->total_ht;
1722  $this->total_tva += $line->total_tva;
1723  $this->total_ttc += $line->total_ttc;
1724  }
1725  $this->revenuestamp = 0;
1726 
1727  // Add a line "offered"
1728  $line = new FactureLigne($this->db);
1729  $line->desc = $langs->trans('Description'). ' (offered line)';
1730  $line->qty = 1;
1731  $line->subprice = 100;
1732  $line->tva_tx = 19.6;
1733  $line->localtax1_tx = 0;
1734  $line->localtax2_tx = 0;
1735  $line->remise_percent = 100;
1736  $line->total_ht = 0;
1737  $line->total_ttc = 0; // 90 * 1.196
1738  $line->total_tva = 0;
1739  $prodid = mt_rand(1, $num_prods);
1740  $line->fk_product = $prodids[$prodid];
1741 
1742  $this->lines[$xnbp] = $line;
1743  $xnbp++;
1744  }
1745 
1746  $this->usenewprice = 0;
1747  }
1748 
1757  public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1758  {
1759  $tables = array(
1760  'facture_rec'
1761  );
1762 
1763  return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1764  }
1765 
1773  public function setFrequencyAndUnit($frequency, $unit)
1774  {
1775  if (!$this->table_element) {
1776  dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with property table_element not defined', LOG_ERR);
1777  return -1;
1778  }
1779 
1780  if (!empty($frequency) && empty($unit)) {
1781  dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with params frequency defined but unit not defined', LOG_ERR);
1782  return -2;
1783  }
1784 
1785  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1786  $sql .= " SET frequency = ".($frequency ? ((int) $frequency) : "NULL");
1787  if (!empty($unit)) {
1788  $sql .= ", unit_frequency = '".$this->db->escape($unit)."'";
1789  }
1790  $sql .= " WHERE rowid = ".((int) $this->id);
1791 
1792  dol_syslog(get_class($this).'::setFrequencyAndUnit', LOG_DEBUG);
1793 
1794  if ($this->db->query($sql)) {
1795  $this->frequency = $frequency;
1796  if (!empty($unit)) {
1797  $this->unit_frequency = $unit;
1798  }
1799  return 1;
1800  } else {
1801  $this->error = $this->db->lasterror();
1802  return -1;
1803  }
1804  }
1805 
1813  public function setNextDate($date, $increment_nb_gen_done = 0)
1814  {
1815  if (!$this->table_element) {
1816  dol_syslog(get_class($this).'::setNextDate was called on objet with property table_element not defined', LOG_ERR);
1817  return -1;
1818  }
1819  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1820  $sql .= " SET date_when = " .($date ? "'".$this->db->idate($date)."'" : "NULL");
1821  if ($increment_nb_gen_done > 0) {
1822  $sql .= ", nb_gen_done = nb_gen_done + 1";
1823  }
1824  $sql .= " WHERE rowid = " . (int) $this->id;
1825 
1826  dol_syslog(get_class($this).'::setNextDate', LOG_DEBUG);
1827 
1828  if ($this->db->query($sql)) {
1829  $this->date_when = $date;
1830  if ($increment_nb_gen_done > 0) {
1831  $this->nb_gen_done++;
1832  }
1833  return 1;
1834  } else {
1835  $this->error = $this->db->lasterror();
1836  return -1;
1837  }
1838  }
1839 
1846  public function setMaxPeriod($nb)
1847  {
1848  if (!$this->table_element) {
1849  dol_syslog(get_class($this).'::setMaxPeriod was called on objet with property table_element not defined', LOG_ERR);
1850  return -1;
1851  }
1852 
1853  if (empty($nb)) {
1854  $nb = 0;
1855  }
1856 
1857  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1858  $sql .= " SET nb_gen_max = ". (int) $nb;
1859  $sql .= " WHERE rowid = " . (int) $this->id;
1860 
1861  dol_syslog(get_class($this).'::setMaxPeriod', LOG_DEBUG);
1862 
1863  if ($this->db->query($sql)) {
1864  $this->nb_gen_max = $nb;
1865  return 1;
1866  } else {
1867  dol_print_error($this->db);
1868  return -1;
1869  }
1870  }
1871 
1878  public function setAutoValidate($validate)
1879  {
1880  if (!$this->table_element) {
1881  dol_syslog(get_class($this).'::setAutoValidate was called on objet with property table_element not defined', LOG_ERR);
1882  return -1;
1883  }
1884 
1885  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1886  $sql .= " SET auto_validate = ".((int) $validate);
1887  $sql .= " WHERE rowid = " . (int) $this->id;
1888 
1889  dol_syslog(get_class($this).'::setAutoValidate', LOG_DEBUG);
1890 
1891  if ($this->db->query($sql)) {
1892  $this->auto_validate = $validate;
1893  return 1;
1894  } else {
1895  dol_print_error($this->db);
1896  return -1;
1897  }
1898  }
1899 
1906  public function setGeneratePdf($validate)
1907  {
1908  if (!$this->table_element) {
1909  dol_syslog(get_class($this).'::setGeneratePdf was called on objet with property table_element not defined', LOG_ERR);
1910  return -1;
1911  }
1912 
1913  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1914  $sql .= " SET generate_pdf = ". (int) $validate;
1915  $sql .= " WHERE rowid = " . (int) $this->id;
1916 
1917  dol_syslog(get_class($this).'::setGeneratePdf', LOG_DEBUG);
1918 
1919  if ($this->db->query($sql)) {
1920  $this->generate_pdf = $validate;
1921  return 1;
1922  } else {
1923  dol_print_error($this->db);
1924  return -1;
1925  }
1926  }
1927 
1934  public function setModelPdf($model)
1935  {
1936  if (!$this->table_element) {
1937  dol_syslog(get_class($this).'::setModelPdf was called on objet with property table_element not defined', LOG_ERR);
1938  return -1;
1939  }
1940 
1941  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1942  $sql .= " SET modelpdf = '".$this->db->escape($model)."'";
1943  $sql .= " WHERE rowid = " . (int) $this->id;
1944 
1945  dol_syslog(get_class($this).'::setModelPdf', LOG_DEBUG);
1946 
1947  if ($this->db->query($sql)) {
1948  $this->model_pdf = $model;
1949  return 1;
1950  } else {
1951  dol_print_error($this->db);
1952  return -1;
1953  }
1954  }
1955 }
1956 
1957 
1958 
1964 {
1968  public $element = 'invoice_supplier_det_rec';
1969 
1973  public $table_element = 'facture_fourn_det_rec';
1974 
1975  public $fk_facture_fourn;
1976  public $fk_parent;
1977  public $fk_product;
1978  public $ref_supplier;
1979  public $label;
1980  public $description;
1981  public $pu_ht;
1982  public $pu_ttc;
1983  public $qty;
1984  public $remise_percent;
1985  public $fk_remise_except;
1986  public $vat_src_code;
1987  public $tva_tx;
1988  public $localtax1_tx;
1989  public $localtax1_type;
1990  public $localtax2_tx;
1991  public $localtax2_type;
1992 
1993  public $product_type;
1994  public $date_start;
1995  public $date_end;
1996  public $info_bits;
1997  public $special_code;
1998  public $rang;
1999 
2000  public $fk_user_author;
2001  public $fk_user_modif;
2002  public $fk_multicurrency;
2003  public $multicurrency_subprice;
2004 
2005 
2006  /* Overrides fields in CommonObject
2007  public $total_ht;
2008  public $total_tva;
2009  public $total_localtax1;
2010  public $total_localtax2;
2011  public $total_ttc;
2012 
2013  public $fk_unit;
2014  public $import_key;
2015  public $multicurrency_code;
2016  public $multicurrency_total_ht;
2017  public $multicurrency_total_tva;
2018  public $multicurrency_total_ttc;
2019  */
2020 
2021 
2029  public function delete(User $user, $notrigger = false)
2030  {
2031  $error = 0;
2032  $this->db->begin();
2033 
2034  if (! $error) {
2035  if (! $notrigger) {
2036  // Call triggers
2037  $result = $this->call_trigger('LINESUPPLIERBILLREC_DELETE', $user);
2038  if ($result < 0) {
2039  $error++;
2040  } // Do also here what you must do to rollback action if trigger fail
2041  // End call triggers
2042  }
2043  }
2044 
2045  if (! $error) {
2046  $result = $this->deleteExtraFields();
2047  if ($result < 0) {
2048  $error++;
2049  }
2050  }
2051 
2052  if (! $error) {
2053  $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element . ' WHERE rowid=' . (int) $this->id;
2054 
2055  $res = $this->db->query($sql);
2056  if ($res === false) {
2057  $error++;
2058  $this->errors[] = $this->db->lasterror();
2059  }
2060  }
2061 
2062  // Commit or rollback
2063  if ($error) {
2064  $this->db->rollback();
2065  return -1;
2066  } else {
2067  $this->db->commit();
2068  return 1;
2069  }
2070  }
2071 
2072 
2079  public function fetch($rowid)
2080  {
2081  $sql = 'SELECT l.rowid,';
2082  $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product,';
2083  $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,';
2084  $sql .= ' l.vat_src_code, l.tva_tx, l.localtax1_tx, l.localtax1_type, l.localtax2_tx, l.localtax2_type,';
2085  $sql .= ' l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc,';
2086  $sql .= ' l.product_type, l.date_start, l.date_end,';
2087  $sql .= ' l.info_bits, l.special_code, l.rang, l.fk_unit, l.import_key,';
2088  $sql .= ' l.fk_user_author, l.fk_user_modif, l.fk_multicurrency,';
2089  $sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2090  $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2091  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det_rec as l';
2092  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
2093  $sql .= ' WHERE l.rowid = '. (int) $rowid;
2094  $sql .= ' ORDER BY l.rang';
2095 
2096  dol_syslog('FactureRec::fetch', LOG_DEBUG);
2097  $result = $this->db->query($sql);
2098  if ($result) {
2099  $objp = $this->db->fetch_object($result);
2100 
2101  $this->id = $objp->rowid;
2102  $this->fk_facture_fourn = $objp->fk_facture_fourn;
2103  $this->fk_parent = $objp->fk_parent_line;
2104  $this->fk_product = $objp->fk_product;
2105  $this->ref_supplier = $objp->ref_supplier;
2106  $this->label = $objp->label;
2107  $this->description = $objp->description;
2108  $this->pu_ht = $objp->pu_ht;
2109  $this->pu_ttc = $objp->pu_ttc;
2110  $this->qty = $objp->qty;
2111  $this->remise_percent = $objp->remise_percent;
2112  $this->fk_remise_except = $objp->fk_remise_except;
2113  $this->vat_src_code = $objp->vat_src_code;
2114  $this->tva_tx = $objp->tva_tx;
2115  $this->localtax1_tx = $objp->localtax1_tx;
2116  $this->localtax1_type = $objp->localtax1_type;
2117  $this->localtax2_tx = $objp->localtax2_tx;
2118  $this->localtax2_type = $objp->localtax2_type;
2119  $this->total_ht = $objp->total_ht;
2120  $this->total_tva = $objp->total_tva;
2121  $this->total_localtax1 = $objp->total_localtax1;
2122  $this->total_localtax2 = $objp->total_localtax2;
2123  $this->total_ttc = $objp->total_ttc;
2124  $this->product_type = $objp->product_type;
2125  $this->date_start = $objp->date_start;
2126  $this->date_end = $objp->date_end;
2127  $this->info_bits = $objp->info_bits;
2128  $this->special_code = $objp->special_code;
2129  $this->rang = $objp->rang;
2130  $this->fk_unit = $objp->fk_unit;
2131  $this->import_key = $objp->import_key;
2132  $this->fk_user_author = $objp->fk_user_author;
2133  $this->fk_user_modif = $objp->fk_user_modif;
2134  $this->fk_multicurrency = $objp->fk_multicurrency;
2135  $this->multicurrency_code = $objp->multicurrency_code;
2136  $this->multicurrency_subprice = $objp->multicurrency_subprice;
2137  $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
2138  $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
2139  $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2140 
2141  $this->db->free($result);
2142  return 1;
2143  } else {
2144  $this->error = $this->db->lasterror();
2145  return -3;
2146  }
2147  }
2148 
2149 
2157  public function update(User $user, $notrigger = 0)
2158  {
2159  global $conf;
2160 
2161  $error = 0;
2162 
2163  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
2164 
2165  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
2166  $sql .= ' fk_facture_fourn = ' . (int) $this->fk_facture_fourn;
2167  $sql .= ', fk_parent_line = ' . (int) $this->fk_parent;
2168  $sql .= ', fk_product = ' . (int) $this->fk_product;
2169  $sql .= ', ref = ' . (!empty($this->ref) ? "'" . $this->db->escape($this->ref) . "'" : 'NULL');
2170  $sql .= ", label = " . (!empty($this->label) ? "'" . $this->db->escape($this->label) . "'" : 'NULL');
2171  $sql .= ", description = '" . $this->db->escape($this->description) . "'";
2172  $sql .= ', pu_ht = ' . price2num($this->pu_ht);
2173  $sql .= ', pu_ttc = ' . price2num($this->pu_ttc);
2174  $sql .= ', qty = ' . price2num($this->qty);
2175  $sql .= ", remise_percent = '" . price2num($this->remise_percent) . "'";
2176  $sql .= ', fk_remise_except = ' . (int) $this->fk_remise_except;
2177  $sql .= ", vat_src_code = '" . $this->db->escape($this->vat_src_code) . "'";
2178  $sql .= ', tva_tx = ' . price2num($this->tva_tx);
2179  $sql .= ', localtax1_tx = ' . price2num($this->localtax1_tx);
2180  $sql .= ", localtax1_type = '" . $this->db->escape($this->localtax1_type) . "'";
2181  $sql .= ', localtax2_tx = ' . price2num($this->localtax2_tx);
2182  $sql .= ", localtax2_type = '" . $this->db->escape($this->localtax2_type) . "'";
2183  if (empty($this->skip_update_total)) {
2184  $sql .= ', total_ht = ' . price2num($this->total_ht);
2185  $sql .= ', total_tva = ' . price2num($this->total_tva);
2186  $sql .= ', total_localtax1 = ' . price2num($this->total_localtax1);
2187  $sql .= ', total_localtax2 = ' . price2num($this->total_localtax2);
2188  $sql .= ', total_ttc = ' . price2num($this->total_ttc);
2189  }
2190  $sql .= ', product_type = ' . (int) $this->product_type;
2191  $sql .= ', date_start = ' . (int) $this->date_start;
2192  $sql .= ', date_end = ' . (int) $this->date_end;
2193  $sql .= ", info_bits = " . ((int) $this->info_bits);
2194  $sql .= ', special_code =' . (int) $this->special_code;
2195  $sql .= ', rang = ' . (int) $this->rang;
2196  $sql .= ', fk_unit = ' .($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : 'null');
2197  $sql .= ', fk_user_modif = ' . (int) $user->id;
2198  $sql .= ' WHERE rowid = ' . (int) $this->id;
2199 
2200  $this->db->begin();
2201 
2202  dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
2203  $resql = $this->db->query($sql);
2204  if ($resql) {
2205  if (!$error) {
2206  $result = $this->insertExtraFields();
2207  if ($result < 0) {
2208  $error++;
2209  }
2210  }
2211 
2212  if (!$error && !$notrigger) {
2213  // Call trigger
2214  $result = $this->call_trigger('LINESUPPLIERBILLREC_MODIFY', $user);
2215  if ($result < 0) {
2216  $error++;
2217  }
2218  // End call triggers
2219  }
2220 
2221  if ($error) {
2222  $this->db->rollback();
2223  return -2;
2224  } else {
2225  $this->db->commit();
2226  return 1;
2227  }
2228  } else {
2229  $this->error = $this->db->lasterror();
2230  $this->db->rollback();
2231  return -2;
2232  }
2233  }
2234 }
$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:48
if(isModEnabled('facture') && $user->hasRight('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') && $user->hasRight('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)) $sql
Social contributions to pay.
Definition: index.php:746
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:122
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...
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.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
div float
Buy price without taxes.
Definition: style.css.php:926
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:120