dolibarr  19.0.0-dev
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  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  } else {
1035  $this->error = 'Recurring Invoice is suspended. adding lines not allowed.';
1036 
1037  return -1;
1038  }
1039  }
1040 
1067  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)
1068  {
1069  global $mysoc, $user;
1070 
1071  $facid = $this->id;
1072 
1073  dol_syslog(get_class($this). '::updateline facid=' .$facid." rowid=$rowid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, type=$type, fk_unit=$fk_unit, pu_ht_devise=$pu_ht_devise", LOG_DEBUG);
1074  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
1075 
1076  // Check parameters
1077  if ($type < 0) {
1078  return -1;
1079  }
1080 
1081  if ($this->brouillon) {
1082  // Clean parameters
1083  $fk_product = empty($fk_product) ? 0 : $fk_product;
1084  $label = empty($label) ? '' : $label;
1085  $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
1086  $qty = price2num($qty);
1087  $info_bits = empty($info_bits) ? 0 : $info_bits;
1088  $pu_ht = price2num($pu_ht);
1089  $pu_ttc = price2num($pu_ttc);
1090  $pu_ht_devise = price2num($pu_ht_devise);
1091 
1092  if (!preg_match('/\‍((.*)\‍)/', $txtva)) {
1093  $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
1094  }
1095 
1096  $txlocaltax1 = empty($txlocaltax1) ? 0 : price2num($txlocaltax1);
1097  $txlocaltax2 = empty($txlocaltax2) ? 0 : price2num($txlocaltax2);
1098  $this->multicurrency_subprice = empty($this->multicurrency_subprice) ? 0 : $this->multicurrency_subprice;
1099  $this->multicurrency_total_ht = empty($this->multicurrency_total_ht) ? 0 : $this->multicurrency_total_ht;
1100  $this->multicurrency_total_tva = empty($this->multicurrency_total_tva) ? 0 : $this->multicurrency_total_tva;
1101  $this->multicurrency_total_ttc = empty($this->multicurrency_total_ttc) ? 0 : $this->multicurrency_total_ttc;
1102 
1103  $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
1104 
1105 
1106  // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
1107  // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1108  // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1109 
1110  $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
1111 
1112  // Clean vat code
1113  $vat_src_code = '';
1114  $reg = array();
1115  if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
1116  $vat_src_code = $reg[1];
1117  $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
1118  }
1119 
1120  $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);
1121 
1122  $total_ht = $tabprice[0];
1123  $total_tva = $tabprice[1];
1124  $total_ttc = $tabprice[2];
1125  $total_localtax1 = $tabprice[9];
1126  $total_localtax2 = $tabprice[10];
1127  $pu_ht = $tabprice[3];
1128  $pu_tva = $tabprice[4];
1129  $pu_ttc = $tabprice[5];
1130 
1131  // MultiCurrency
1132  $multicurrency_total_ht = $tabprice[16];
1133  $multicurrency_total_tva = $tabprice[17];
1134  $multicurrency_total_ttc = $tabprice[18];
1135  $pu_ht_devise = $tabprice[19];
1136 
1137  $product_type = $type;
1138  if ($fk_product) {
1139  $product = new Product($this->db);
1140  $result = $product->fetch($fk_product);
1141  $product_type = $product->type;
1142  }
1143 
1144  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
1145  $sql .= ' fk_facture_fourn = ' . ((int) $facid);
1146  $sql .= ', fk_product = ' . ($fk_product > 0 ? ((int) $fk_product) : 'null');
1147  $sql .= ", ref = '" . $this->db->escape($ref) . "'";
1148  $sql .= ", label = '" . $this->db->escape($label) . "'";
1149  $sql .= ", description = '" . $this->db->escape($desc) . "'";
1150  $sql .= ', pu_ht = ' . price2num($pu_ht);
1151  $sql .= ', qty = ' . price2num($qty);
1152  $sql .= ", remise_percent = '" . price2num($remise_percent) . "'";
1153  $sql .= ", vat_src_code = '" . $this->db->escape($vat_src_code) . "'";
1154  $sql .= ', tva_tx = ' . price2num($txtva);
1155  $sql .= ', localtax1_tx = ' . (float) $txlocaltax1;
1156  $sql .= ", localtax1_type = '" . $this->db->escape($localtaxes_type[0]) . "'";
1157  $sql .= ', localtax2_tx = ' . (float) $txlocaltax2;
1158  $sql .= ", localtax2_type = '" . $this->db->escape($localtaxes_type[2]) . "'";
1159  $sql .= ", total_ht = '" . price2num($total_ht) . "'";
1160  $sql .= ", total_tva = '" . price2num($total_tva) . "'";
1161  $sql .= ", total_localtax1 = '" . price2num($total_localtax1) . "'";
1162  $sql .= ", total_localtax2 = '" . price2num($total_localtax2) . "'";
1163  $sql .= ", total_ttc = '" . price2num($total_ttc) . "'";
1164  $sql .= ', product_type = ' . (int) $product_type;
1165  $sql .= ', date_start = ' . (empty($date_start) ? 'NULL' : (int) $date_start);
1166  $sql .= ', date_end = ' . (empty($date_end) ? 'NULL' : (int) $date_end);
1167  $sql .= ', info_bits = ' . (int) $info_bits;
1168  $sql .= ', special_code = ' . (int) $special_code;
1169  $sql .= ', rang = ' . (int) $rang;
1170  $sql .= ', fk_unit = ' . ($fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : 'null');
1171  $sql .= ', fk_user_modif = ' . (int) $user;
1172  $sql .= ', multicurrency_subprice = '.price2num($pu_ht_devise);
1173  $sql .= ', multicurrency_total_ht = '.price2num($multicurrency_total_ht);
1174  $sql .= ', multicurrency_total_tva = '.price2num($multicurrency_total_tva);
1175  $sql .= ', multicurrency_total_ttc = '.price2num($multicurrency_total_ttc);
1176  $sql .= ' WHERE rowid = ' . (int) $rowid;
1177 
1178  dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
1179  if ($this->db->query($sql)) {
1180  $this->id = $facid;
1181  $this->update_price();
1182  return 1;
1183  } else {
1184  $this->error = $this->db->lasterror();
1185  return -1;
1186  }
1187  }
1188  }
1189 
1190 
1196  public function getNextDate()
1197  {
1198  if (empty($this->date_when)) {
1199  return false;
1200  }
1201  return dol_time_plus_duree($this->date_when, $this->frequency, $this->unit_frequency);
1202  }
1203 
1209  public function isMaxNbGenReached()
1210  {
1211  $ret = false;
1212  if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) {
1213  $ret = true;
1214  }
1215  return $ret;
1216  }
1217 
1224  public function strikeIfMaxNbGenReached($ret)
1225  {
1226  // Special case to strike the date
1227  return ($this->isMaxNbGenReached() ? '<strike>' : '').$ret.($this->isMaxNbGenReached() ? '</strike>' : '');
1228  }
1229 
1240  public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0)
1241  {
1242  global $conf, $langs, $db, $user, $hookmanager;
1243 
1244  $error = 0;
1245  $nb_create = 0;
1246 
1247  // Load translation files required by the page
1248  $langs->loadLangs(array('main', 'bills'));
1249 
1250  $now = dol_now();
1251  $tmparray = dol_getdate($now);
1252  $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
1253 
1254  dol_syslog('createRecurringInvoices restrictioninvoiceid=' .$restrictioninvoiceid. ' forcevalidation=' .$forcevalidation);
1255 
1256  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_fourn_rec';
1257  $sql .= ' WHERE frequency > 0'; // A recurring supplier invoice is an invoice with a frequency
1258  $sql .= " AND (date_when IS NULL OR date_when <= '".$this->db->idate($today)."')";
1259  $sql .= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)';
1260  $sql .= ' AND suspended = 0';
1261  $sql .= ' AND entity = '. (int) $conf->entity; // MUST STAY = $conf->entity here
1262  if ($restrictioninvoiceid > 0) {
1263  $sql .= ' AND rowid = '. (int) $restrictioninvoiceid;
1264  }
1265  $sql .= $this->db->order('entity', 'ASC');
1266  //print $sql;exit;
1267  $parameters = array(
1268  'restrictioninvoiceid' => $restrictioninvoiceid,
1269  'forcevalidation' => $forcevalidation,
1270  );
1271  $reshook = $hookmanager->executeHooks('beforeCreationOfRecurringInvoices', $parameters, $sql); // note that $sql might be modified by hooks
1272 
1273  $resql = $this->db->query($sql);
1274  if ($resql) {
1275  $i = 0;
1276  $num = $this->db->num_rows($resql);
1277 
1278  if ($num) {
1279  $this->output .= $langs->trans('FoundXQualifiedRecurringInvoiceTemplate', $num)."\n";
1280  } else {
1281  $this->output .= $langs->trans('NoQualifiedRecurringInvoiceTemplateFound');
1282  }
1283 
1284  $saventity = $conf->entity;
1285 
1286  while ($i < $num) { // Loop on each template invoice. If $num = 0, test is false at first pass.
1287  $line = $this->db->fetch_object($resql);
1288 
1289  $this->db->begin();
1290 
1291  $invoiceidgenerated = 0;
1292 
1293  $new_fac_fourn = null;
1294  $facturerec = new FactureFournisseurRec($this->db);
1295  $facturerec->fetch($line->rowid);
1296 
1297  if ($facturerec->id > 0) {
1298  // Set entity context
1299  $conf->entity = $facturerec->entity;
1300 
1301  dol_syslog('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', ref=' .$facturerec->ref. ', entity=' .$facturerec->entity);
1302 
1303  $new_fac_fourn = new FactureFournisseur($this->db);
1304  $new_fac_fourn->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice
1305  $new_fac_fourn->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice
1306 
1307  $new_fac_fourn->type = self::TYPE_STANDARD;
1308  $new_fac_fourn->brouillon = 1;
1309  $new_fac_fourn->statut = self::STATUS_DRAFT;
1310  $new_fac_fourn->status = self::STATUS_DRAFT;
1311  $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.
1312  $new_fac_fourn->socid = $facturerec->socid;
1313  $new_fac_fourn->lines = $facturerec->lines;
1314  $new_fac_fourn->ref_supplier = $facturerec->ref_supplier;
1315  $new_fac_fourn->model_pdf = $facturerec->model_pdf;
1316  $new_fac_fourn->fk_project = $facturerec->fk_project;
1317  $new_fac_fourn->libelle = $facturerec->libelle;
1318 
1319  $invoiceidgenerated = $new_fac_fourn->create($user);
1320  if ($invoiceidgenerated <= 0) {
1321  $this->errors = $new_fac_fourn->errors;
1322  $this->error = $new_fac_fourn->error;
1323  $error++;
1324  }
1325  if (!$error && ($facturerec->auto_validate || $forcevalidation)) {
1326  $result = $new_fac_fourn->validate($user);
1327  if ($result <= 0) {
1328  $this->errors = $new_fac_fourn->errors;
1329  $this->error = $new_fac_fourn->error;
1330  $error++;
1331  }
1332  }
1333 
1334  if (!$error && $facturerec->generate_pdf) {
1335  // We refresh the object in order to have all necessary data (like date_lim_reglement)
1336  $new_fac_fourn->fetch($new_fac_fourn->id);
1337  $result = $new_fac_fourn->generateDocument($facturerec->model_pdf, $langs);
1338  if ($result < 0) {
1339  $this->errors = $new_fac_fourn->errors;
1340  $this->error = $new_fac_fourn->error;
1341  $error++;
1342  }
1343  }
1344  } else {
1345  $error++;
1346  $this->error = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity."\n";
1347  $this->errors[] = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity;
1348  dol_syslog('createRecurringInvoices Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity);
1349  }
1350 
1351  if (!$error && $invoiceidgenerated >= 0) {
1352  $facturerec->nb_gen_done++;
1353  $facturerec->date_last_gen = dol_now();
1354  $facturerec->date_when= $facturerec->getNextDate();
1355  $facturerec->update($user);
1356  $this->db->commit('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', title=' .$facturerec->titre);
1357  dol_syslog('createRecurringInvoices Process invoice template ' .$facturerec->titre. ' is finished with a success generation');
1358  $nb_create++;
1359  $this->output .= $langs->trans('InvoiceGeneratedFromTemplate', $new_fac_fourn->ref, $facturerec->titre)."\n";
1360  } else {
1361  $this->db->rollback('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', title=' .$facturerec->titre);
1362  }
1363 
1364  $parameters = array(
1365  'cpt' => $i,
1366  'total' => $num,
1367  'errorCount' => $error,
1368  'invoiceidgenerated' => $invoiceidgenerated,
1369  'facturerec' => $facturerec, // it's an object which PHP passes by "reference", so modifiable by hooks.
1370  'this' => $this, // it's an object which PHP passes by "reference", so modifiable by hooks.
1371  );
1372  $reshook = $hookmanager->executeHooks('afterCreationOfRecurringInvoice', $parameters, $new_fac_fourn); // note: $facture can be modified by hooks (warning: $facture can be null)
1373 
1374  $i++;
1375  }
1376 
1377  $conf->entity = $saventity; // Restore entity context
1378  } else {
1379  dol_print_error($this->db);
1380  }
1381 
1382  $this->output = trim($this->output);
1383 
1384  return $error ? $error : 0;
1385  }
1386 
1399  public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = '', $save_lastsearch_value = -1)
1400  {
1401  global $langs, $hookmanager;
1402 
1403  $result = '';
1404 
1405  $label = '<u>'.$langs->trans('RepeatableInvoice').'</u>';
1406  if (!empty($this->ref)) {
1407  $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1408  }
1409  if ($this->frequency > 0) {
1410  $label .= '<br><b>'.$langs->trans('Frequency').':</b> '.$langs->trans('FrequencyPer_'.$this->unit_frequency, $this->frequency);
1411  }
1412  if (!empty($this->date_last_gen)) {
1413  $label .= '<br><b>'.$langs->trans('DateLastGeneration').':</b> '.dol_print_date($this->date_last_gen, 'dayhour');
1414  }
1415  if ($this->frequency > 0) {
1416  if (!empty($this->date_when)) {
1417  $label .= '<br><b>'.$langs->trans('NextDateToExecution').':</b> ';
1418  $label .= (empty($this->suspended) ? '' : '<strike>').dol_print_date($this->date_when, 'day').(empty($this->suspended) ? '' : '</strike>'); // No hour for this property
1419  if (!empty($this->suspended)) {
1420  $label .= ' ('.$langs->trans('Disabled').')';
1421  }
1422  }
1423  }
1424 
1425  $url = DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$this->id;
1426 
1427  if ($short) {
1428  return $url;
1429  }
1430 
1431  if ($option != 'nolink') {
1432  // Add param to save lastsearch_values or not
1433  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1434  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER['PHP_SELF'])) {
1435  $add_save_lastsearch_values = 1;
1436  }
1437  if ($add_save_lastsearch_values) {
1438  $url .= '&save_lastsearch_values=1';
1439  }
1440  }
1441 
1442  $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
1443  $linkend = '</a>';
1444 
1445  $result .= $linkstart;
1446  if ($withpicto) {
1447  $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);
1448  }
1449  if ($withpicto != 2) {
1450  $result .= $this->ref;
1451  }
1452  $result .= $linkend;
1453  global $action;
1454  $hookmanager->initHooks(array($this->element . 'dao'));
1455  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1456  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1457  if ($reshook > 0) {
1458  $result = $hookmanager->resPrint;
1459  } else {
1460  $result .= $hookmanager->resPrint;
1461  }
1462  return $result;
1463  }
1464 
1472  public function getLibStatut($mode = 0, $alreadypaid = -1)
1473  {
1474  return $this->LibStatut($this->frequency ? 1 : 0, $this->suspended, $mode, $alreadypaid, empty($this->type) ? 0 : $this->type);
1475  }
1476 
1477  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1488  public function LibStatut($recur, $status, $mode = 0, $alreadypaid = -1, $type = 0)
1489  {
1490  // phpcs:enable
1491  global $langs;
1492  $langs->load('bills');
1493 
1494  $labelStatus = $langs->transnoentitiesnoconv('Active');
1495  $statusType = 'status0';
1496 
1497  //print "$recur,$status,$mode,$alreadypaid,$type";
1498  if ($mode == 0) {
1499  if ($recur) {
1500  if ($status == self::STATUS_SUSPENDED) {
1501  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1502  } else {
1503  $labelStatus = $langs->transnoentitiesnoconv('Active');
1504  }
1505  } else {
1506  if ($status == self::STATUS_SUSPENDED) {
1507  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1508  } else {
1509  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1510  }
1511  }
1512  } elseif ($mode == 1) {
1513  $prefix = 'Short';
1514  if ($recur) {
1515  if ($status == self::STATUS_SUSPENDED) {
1516  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1517  } else {
1518  $labelStatus = $langs->transnoentitiesnoconv('Active');
1519  }
1520  } else {
1521  if ($status == self::STATUS_SUSPENDED) {
1522  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1523  } else {
1524  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1525  }
1526  }
1527  } elseif ($mode == 2) {
1528  if ($recur) {
1529  if ($status == self::STATUS_SUSPENDED) {
1530  $statusType = 'status6';
1531  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1532  } else {
1533  $statusType = 'status4';
1534  $labelStatus = $langs->transnoentitiesnoconv('Active');
1535  }
1536  } else {
1537  if ($status == self::STATUS_SUSPENDED) {
1538  $statusType = 'status6';
1539  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1540  } else {
1541  $statusType = 'status0';
1542  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1543  }
1544  }
1545  } elseif ($mode == 3) {
1546  if ($recur) {
1547  $prefix = 'Short';
1548  if ($status == self::STATUS_SUSPENDED) {
1549  $statusType = 'status6';
1550  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1551  } else {
1552  $statusType = 'status4';
1553  $labelStatus = $langs->transnoentitiesnoconv('Active');
1554  }
1555  } else {
1556  if ($status == self::STATUS_SUSPENDED) {
1557  $statusType = 'status6';
1558  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1559  } else {
1560  $statusType = 'status0';
1561  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1562  }
1563  }
1564  } elseif ($mode == 4) {
1565  $prefix = '';
1566  if ($recur) {
1567  if ($status == self::STATUS_SUSPENDED) {
1568  $statusType = 'status6';
1569  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1570  } else {
1571  $statusType = 'status4';
1572  $labelStatus = $langs->transnoentitiesnoconv('Active');
1573  }
1574  } else {
1575  if ($status == self::STATUS_SUSPENDED) {
1576  $statusType = 'status6';
1577  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1578  } else {
1579  $statusType = 'status0';
1580  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1581  }
1582  }
1583  } elseif ($mode == 5 || $mode == 6) {
1584  $prefix = '';
1585  if ($mode == 5) {
1586  $prefix = 'Short';
1587  }
1588  if ($recur) {
1589  if ($status == self::STATUS_SUSPENDED) {
1590  $statusType = 'status6';
1591  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1592  } else {
1593  $statusType = 'status4';
1594  $labelStatus = $langs->transnoentitiesnoconv('Active');
1595  }
1596  } else {
1597  if ($status == self::STATUS_SUSPENDED) {
1598  $statusType = 'status6';
1599  $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1600  } else {
1601  $statusType = 'status0';
1602  $labelStatus = $langs->transnoentitiesnoconv('Draft');
1603  }
1604  }
1605  }
1606 
1607  $labelStatusShort = $labelStatus;
1608 
1609  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1610  }
1611 
1620  public function initAsSpecimen($option = '')
1621  {
1622  global $user, $langs, $conf;
1623 
1624  $now = dol_now();
1625  $arraynow = dol_getdate($now);
1626  $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1627 
1628  // Load array of products prodids
1629  $num_prods = 0;
1630  $prodids = array();
1631 
1632  $sql = 'SELECT rowid';
1633  $sql .= ' FROM ' .MAIN_DB_PREFIX. 'product';
1634  $sql .= ' WHERE entity IN (' .getEntity('product'). ')';
1635  $sql .= $this->db->plimit(100);
1636 
1637  $resql = $this->db->query($sql);
1638  if ($resql) {
1639  $num_prods = $this->db->num_rows($resql);
1640  $i = 0;
1641  while ($i < $num_prods) {
1642  $i++;
1643  $row = $this->db->fetch_row($resql);
1644  $prodids[$i] = $row[0];
1645  }
1646  }
1647 
1648  // Initialize parameters
1649  $this->id = 0;
1650  $this->ref = 'SPECIMEN';
1651  $this->title = 'SPECIMEN';
1652  $this->specimen = 1;
1653  $this->socid = 1;
1654  $this->date = $nownotime;
1655  $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
1656  $this->cond_reglement_id = 1;
1657  $this->cond_reglement_code = 'RECEP';
1658  $this->date_lim_reglement = $this->calculate_date_lim_reglement();
1659  $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR
1660  $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
1661  $this->note_public = 'This is a comment (public)';
1662  $this->note_private = 'This is a comment (private)';
1663  $this->note = 'This is a comment (private)';
1664  $this->fk_incoterms = 0;
1665  $this->location_incoterms = '';
1666 
1667  if (empty($option) || $option != 'nolines') {
1668  // Lines
1669  $nbp = 5;
1670  $xnbp = 0;
1671  while ($xnbp < $nbp) {
1672  $line = new FactureLigne($this->db);
1673  $line->desc = $langs->trans('Description'). ' ' .$xnbp;
1674  $line->qty = 1;
1675  $line->subprice = 100;
1676  $line->tva_tx = 19.6;
1677  $line->localtax1_tx = 0;
1678  $line->localtax2_tx = 0;
1679  $line->remise_percent = 0;
1680  if ($xnbp == 1) { // Qty is negative (product line)
1681  $prodid = mt_rand(1, $num_prods);
1682  $line->fk_product = $prodids[$prodid];
1683  $line->qty = -1;
1684  $line->total_ht = -100;
1685  $line->total_ttc = -119.6;
1686  $line->total_tva = -19.6;
1687  } elseif ($xnbp == 2) { // UP is negative (free line)
1688  $line->subprice = -100;
1689  $line->total_ht = -100;
1690  $line->total_ttc = -119.6;
1691  $line->total_tva = -19.6;
1692  $line->remise_percent = 0;
1693  } elseif ($xnbp == 3) { // Discount is 50% (product line)
1694  $prodid = mt_rand(1, $num_prods);
1695  $line->fk_product = $prodids[$prodid];
1696  $line->total_ht = 50;
1697  $line->total_ttc = 59.8;
1698  $line->total_tva = 9.8;
1699  $line->remise_percent = 50;
1700  } else // (product line)
1701  {
1702  $prodid = mt_rand(1, $num_prods);
1703  $line->fk_product = $prodids[$prodid];
1704  $line->total_ht = 100;
1705  $line->total_ttc = 119.6;
1706  $line->total_tva = 19.6;
1707  $line->remise_percent = 00;
1708  }
1709 
1710  $this->lines[$xnbp] = $line;
1711  $xnbp++;
1712 
1713  $this->total_ht += $line->total_ht;
1714  $this->total_tva += $line->total_tva;
1715  $this->total_ttc += $line->total_ttc;
1716  }
1717  $this->revenuestamp = 0;
1718 
1719  // Add a line "offered"
1720  $line = new FactureLigne($this->db);
1721  $line->desc = $langs->trans('Description'). ' (offered line)';
1722  $line->qty = 1;
1723  $line->subprice = 100;
1724  $line->tva_tx = 19.6;
1725  $line->localtax1_tx = 0;
1726  $line->localtax2_tx = 0;
1727  $line->remise_percent = 100;
1728  $line->total_ht = 0;
1729  $line->total_ttc = 0; // 90 * 1.196
1730  $line->total_tva = 0;
1731  $prodid = mt_rand(1, $num_prods);
1732  $line->fk_product = $prodids[$prodid];
1733 
1734  $this->lines[$xnbp] = $line;
1735  $xnbp++;
1736  }
1737 
1738  $this->usenewprice = 0;
1739  }
1740 
1749  public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1750  {
1751  $tables = array(
1752  'facture_rec'
1753  );
1754 
1755  return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1756  }
1757 
1765  public function setFrequencyAndUnit($frequency, $unit)
1766  {
1767  if (!$this->table_element) {
1768  dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with property table_element not defined', LOG_ERR);
1769  return -1;
1770  }
1771 
1772  if (!empty($frequency) && empty($unit)) {
1773  dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with params frequency defined but unit not defined', LOG_ERR);
1774  return -2;
1775  }
1776 
1777  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1778  $sql .= " SET frequency = ".($frequency ? ((int) $frequency) : "NULL");
1779  if (!empty($unit)) {
1780  $sql .= ", unit_frequency = '".$this->db->escape($unit)."'";
1781  }
1782  $sql .= " WHERE rowid = ".((int) $this->id);
1783 
1784  dol_syslog(get_class($this).'::setFrequencyAndUnit', LOG_DEBUG);
1785 
1786  if ($this->db->query($sql)) {
1787  $this->frequency = $frequency;
1788  if (!empty($unit)) {
1789  $this->unit_frequency = $unit;
1790  }
1791  return 1;
1792  } else {
1793  $this->error = $this->db->lasterror();
1794  return -1;
1795  }
1796  }
1797 
1805  public function setNextDate($date, $increment_nb_gen_done = 0)
1806  {
1807  if (!$this->table_element) {
1808  dol_syslog(get_class($this).'::setNextDate was called on objet with property table_element not defined', LOG_ERR);
1809  return -1;
1810  }
1811  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1812  $sql .= " SET date_when = " .($date ? "'".$this->db->idate($date)."'" : "NULL");
1813  if ($increment_nb_gen_done > 0) {
1814  $sql .= ", nb_gen_done = nb_gen_done + 1";
1815  }
1816  $sql .= " WHERE rowid = " . (int) $this->id;
1817 
1818  dol_syslog(get_class($this).'::setNextDate', LOG_DEBUG);
1819 
1820  if ($this->db->query($sql)) {
1821  $this->date_when = $date;
1822  if ($increment_nb_gen_done > 0) {
1823  $this->nb_gen_done++;
1824  }
1825  return 1;
1826  } else {
1827  $this->error = $this->db->lasterror();
1828  return -1;
1829  }
1830  }
1831 
1838  public function setMaxPeriod($nb)
1839  {
1840  if (!$this->table_element) {
1841  dol_syslog(get_class($this).'::setMaxPeriod was called on objet with property table_element not defined', LOG_ERR);
1842  return -1;
1843  }
1844 
1845  if (empty($nb)) {
1846  $nb = 0;
1847  }
1848 
1849  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1850  $sql .= " SET nb_gen_max = ". (int) $nb;
1851  $sql .= " WHERE rowid = " . (int) $this->id;
1852 
1853  dol_syslog(get_class($this).'::setMaxPeriod', LOG_DEBUG);
1854 
1855  if ($this->db->query($sql)) {
1856  $this->nb_gen_max = $nb;
1857  return 1;
1858  } else {
1859  dol_print_error($this->db);
1860  return -1;
1861  }
1862  }
1863 
1870  public function setAutoValidate($validate)
1871  {
1872  if (!$this->table_element) {
1873  dol_syslog(get_class($this).'::setAutoValidate was called on objet with property table_element not defined', LOG_ERR);
1874  return -1;
1875  }
1876 
1877  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1878  $sql .= " SET auto_validate = ".((int) $validate);
1879  $sql .= " WHERE rowid = " . (int) $this->id;
1880 
1881  dol_syslog(get_class($this).'::setAutoValidate', LOG_DEBUG);
1882 
1883  if ($this->db->query($sql)) {
1884  $this->auto_validate = $validate;
1885  return 1;
1886  } else {
1887  dol_print_error($this->db);
1888  return -1;
1889  }
1890  }
1891 
1898  public function setGeneratePdf($validate)
1899  {
1900  if (!$this->table_element) {
1901  dol_syslog(get_class($this).'::setGeneratePdf was called on objet with property table_element not defined', LOG_ERR);
1902  return -1;
1903  }
1904 
1905  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1906  $sql .= " SET generate_pdf = ". (int) $validate;
1907  $sql .= " WHERE rowid = " . (int) $this->id;
1908 
1909  dol_syslog(get_class($this).'::setGeneratePdf', LOG_DEBUG);
1910 
1911  if ($this->db->query($sql)) {
1912  $this->generate_pdf = $validate;
1913  return 1;
1914  } else {
1915  dol_print_error($this->db);
1916  return -1;
1917  }
1918  }
1919 
1926  public function setModelPdf($model)
1927  {
1928  if (!$this->table_element) {
1929  dol_syslog(get_class($this).'::setModelPdf was called on objet with property table_element not defined', LOG_ERR);
1930  return -1;
1931  }
1932 
1933  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1934  $sql .= " SET modelpdf = '".$this->db->escape($model)."'";
1935  $sql .= " WHERE rowid = " . (int) $this->id;
1936 
1937  dol_syslog(get_class($this).'::setModelPdf', LOG_DEBUG);
1938 
1939  if ($this->db->query($sql)) {
1940  $this->model_pdf = $model;
1941  return 1;
1942  } else {
1943  dol_print_error($this->db);
1944  return -1;
1945  }
1946  }
1947 }
1948 
1949 
1950 
1956 {
1960  public $element = 'invoice_supplier_det_rec';
1961 
1965  public $table_element = 'facture_fourn_det_rec';
1966 
1967  public $fk_facture_fourn;
1968  public $fk_parent;
1969  public $fk_product;
1970  public $ref_supplier;
1971  public $label;
1972  public $description;
1973  public $pu_ht;
1974  public $pu_ttc;
1975  public $qty;
1976  public $remise_percent;
1977  public $fk_remise_except;
1978  public $vat_src_code;
1979  public $tva_tx;
1980  public $localtax1_tx;
1981  public $localtax1_type;
1982  public $localtax2_tx;
1983  public $localtax2_type;
1984 
1985  public $product_type;
1986  public $date_start;
1987  public $date_end;
1988  public $info_bits;
1989  public $special_code;
1990  public $rang;
1991 
1992  public $fk_user_author;
1993  public $fk_user_modif;
1994  public $fk_multicurrency;
1995  public $multicurrency_subprice;
1996 
1997 
1998  /* Overrides fields in CommonObject
1999  public $total_ht;
2000  public $total_tva;
2001  public $total_localtax1;
2002  public $total_localtax2;
2003  public $total_ttc;
2004 
2005  public $fk_unit;
2006  public $import_key;
2007  public $multicurrency_code;
2008  public $multicurrency_total_ht;
2009  public $multicurrency_total_tva;
2010  public $multicurrency_total_ttc;
2011  */
2012 
2013 
2021  public function delete(User $user, $notrigger = false)
2022  {
2023  $error = 0;
2024  $this->db->begin();
2025 
2026  if (! $error) {
2027  if (! $notrigger) {
2028  // Call triggers
2029  $result = $this->call_trigger('LINESUPPLIERBILLREC_DELETE', $user);
2030  if ($result < 0) {
2031  $error++;
2032  } // Do also here what you must do to rollback action if trigger fail
2033  // End call triggers
2034  }
2035  }
2036 
2037  if (! $error) {
2038  $result = $this->deleteExtraFields();
2039  if ($result < 0) {
2040  $error++;
2041  }
2042  }
2043 
2044  if (! $error) {
2045  $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element . ' WHERE rowid=' . (int) $this->id;
2046 
2047  $res = $this->db->query($sql);
2048  if ($res === false) {
2049  $error++;
2050  $this->errors[] = $this->db->lasterror();
2051  }
2052  }
2053 
2054  // Commit or rollback
2055  if ($error) {
2056  $this->db->rollback();
2057  return -1;
2058  } else {
2059  $this->db->commit();
2060  return 1;
2061  }
2062  }
2063 
2064 
2071  public function fetch($rowid)
2072  {
2073  $sql = 'SELECT l.rowid,';
2074  $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product,';
2075  $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,';
2076  $sql .= ' l.vat_src_code, l.tva_tx, l.localtax1_tx, l.localtax1_type, l.localtax2_tx, l.localtax2_type,';
2077  $sql .= ' l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc,';
2078  $sql .= ' l.product_type, l.date_start, l.date_end,';
2079  $sql .= ' l.info_bits, l.special_code, l.rang, l.fk_unit, l.import_key,';
2080  $sql .= ' l.fk_user_author, l.fk_user_modif, l.fk_multicurrency,';
2081  $sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2082  $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2083  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det_rec as l';
2084  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
2085  $sql .= ' WHERE l.rowid = '. (int) $rowid;
2086  $sql .= ' ORDER BY l.rang';
2087 
2088  dol_syslog('FactureRec::fetch', LOG_DEBUG);
2089  $result = $this->db->query($sql);
2090  if ($result) {
2091  $objp = $this->db->fetch_object($result);
2092 
2093  $this->id = $objp->rowid;
2094  $this->fk_facture_fourn = $objp->fk_facture_fourn;
2095  $this->fk_parent = $objp->fk_parent_line;
2096  $this->fk_product = $objp->fk_product;
2097  $this->ref_supplier = $objp->ref_supplier;
2098  $this->label = $objp->label;
2099  $this->description = $objp->description;
2100  $this->pu_ht = $objp->pu_ht;
2101  $this->pu_ttc = $objp->pu_ttc;
2102  $this->qty = $objp->qty;
2103  $this->remise_percent = $objp->remise_percent;
2104  $this->fk_remise_except = $objp->fk_remise_except;
2105  $this->vat_src_code = $objp->vat_src_code;
2106  $this->tva_tx = $objp->tva_tx;
2107  $this->localtax1_tx = $objp->localtax1_tx;
2108  $this->localtax1_type = $objp->localtax1_type;
2109  $this->localtax2_tx = $objp->localtax2_tx;
2110  $this->localtax2_type = $objp->localtax2_type;
2111  $this->total_ht = $objp->total_ht;
2112  $this->total_tva = $objp->total_tva;
2113  $this->total_localtax1 = $objp->total_localtax1;
2114  $this->total_localtax2 = $objp->total_localtax2;
2115  $this->total_ttc = $objp->total_ttc;
2116  $this->product_type = $objp->product_type;
2117  $this->date_start = $objp->date_start;
2118  $this->date_end = $objp->date_end;
2119  $this->info_bits = $objp->info_bits;
2120  $this->special_code = $objp->special_code;
2121  $this->rang = $objp->rang;
2122  $this->fk_unit = $objp->fk_unit;
2123  $this->import_key = $objp->import_key;
2124  $this->fk_user_author = $objp->fk_user_author;
2125  $this->fk_user_modif = $objp->fk_user_modif;
2126  $this->fk_multicurrency = $objp->fk_multicurrency;
2127  $this->multicurrency_code = $objp->multicurrency_code;
2128  $this->multicurrency_subprice = $objp->multicurrency_subprice;
2129  $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
2130  $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
2131  $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2132 
2133  $this->db->free($result);
2134  return 1;
2135  } else {
2136  $this->error = $this->db->lasterror();
2137  return -3;
2138  }
2139  }
2140 
2141 
2149  public function update(User $user, $notrigger = 0)
2150  {
2151  global $conf;
2152 
2153  $error = 0;
2154 
2155  include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
2156 
2157  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
2158  $sql .= ' fk_facture_fourn = ' . (int) $this->fk_facture_fourn;
2159  $sql .= ', fk_parent_line = ' . (int) $this->fk_parent;
2160  $sql .= ', fk_product = ' . (int) $this->fk_product;
2161  $sql .= ', ref = ' . (!empty($this->ref) ? "'" . $this->db->escape($this->ref) . "'" : 'NULL');
2162  $sql .= ", label = " . (!empty($this->label) ? "'" . $this->db->escape($this->label) . "'" : 'NULL');
2163  $sql .= ", description = '" . $this->db->escape($this->description) . "'";
2164  $sql .= ', pu_ht = ' . price2num($this->pu_ht);
2165  $sql .= ', pu_ttc = ' . price2num($this->pu_ttc);
2166  $sql .= ', qty = ' . price2num($this->qty);
2167  $sql .= ", remise_percent = '" . price2num($this->remise_percent) . "'";
2168  $sql .= ', fk_remise_except = ' . (int) $this->fk_remise_except;
2169  $sql .= ", vat_src_code = '" . $this->db->escape($this->vat_src_code) . "'";
2170  $sql .= ', tva_tx = ' . price2num($this->tva_tx);
2171  $sql .= ', localtax1_tx = ' . price2num($this->localtax1_tx);
2172  $sql .= ", localtax1_type = '" . $this->db->escape($this->localtax1_type) . "'";
2173  $sql .= ', localtax2_tx = ' . price2num($this->localtax2_tx);
2174  $sql .= ", localtax2_type = '" . $this->db->escape($this->localtax2_type) . "'";
2175  if (empty($this->skip_update_total)) {
2176  $sql .= ', total_ht = ' . price2num($this->total_ht);
2177  $sql .= ', total_tva = ' . price2num($this->total_tva);
2178  $sql .= ', total_localtax1 = ' . price2num($this->total_localtax1);
2179  $sql .= ', total_localtax2 = ' . price2num($this->total_localtax2);
2180  $sql .= ', total_ttc = ' . price2num($this->total_ttc);
2181  }
2182  $sql .= ', product_type = ' . (int) $this->product_type;
2183  $sql .= ', date_start = ' . (int) $this->date_start;
2184  $sql .= ', date_end = ' . (int) $this->date_end;
2185  $sql .= ", info_bits = " . ((int) $this->info_bits);
2186  $sql .= ', special_code =' . (int) $this->special_code;
2187  $sql .= ', rang = ' . (int) $this->rang;
2188  $sql .= ', fk_unit = ' .($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : 'null');
2189  $sql .= ', fk_user_modif = ' . (int) $user;
2190  $sql .= ' WHERE rowid = ' . (int) $this->id;
2191 
2192  $this->db->begin();
2193 
2194  dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
2195  $resql = $this->db->query($sql);
2196  if ($resql) {
2197  if (!$error) {
2198  $result = $this->insertExtraFields();
2199  if ($result < 0) {
2200  $error++;
2201  }
2202  }
2203 
2204  if (!$error && !$notrigger) {
2205  // Call trigger
2206  $result = $this->call_trigger('LINESUPPLIERBILLREC_MODIFY', $user);
2207  if ($result < 0) {
2208  $error++;
2209  }
2210  // End call triggers
2211  }
2212 
2213  if ($error) {
2214  $this->db->rollback();
2215  return -2;
2216  } else {
2217  $this->db->commit();
2218  return 1;
2219  }
2220  } else {
2221  $this->error = $this->db->lasterror();
2222  $this->db->rollback();
2223  return -2;
2224  }
2225  }
2226 }
$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:921
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