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
31require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
32require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
34require_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.
print $langs trans("Ref").' m m m statut
Definition index.php:152
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:123
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after 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.
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...
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