dolibarr 18.0.9
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 as ref_supplier, 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 = $objp->product_ref; // Ref of product
738 $line->product_ref = $objp->product_ref; // Ref of product
739 $line->product_label = $objp->product_label;
740 $line->product_desc = $objp->product_desc;
741 $line->ref_supplier = $objp->ref_supplier;
742 $line->label = $objp->label;
743 $line->description = $objp->description;
744 $line->pu_ht = $objp->pu_ht;
745 $line->subprice = $objp->pu_ht;
746 $line->pu_ttc = $objp->pu_ttc;
747 $line->qty = $objp->qty;
748 $line->remise_percent = $objp->remise_percent;
749 $line->fk_remise_except = $objp->fk_remise_except;
750 $line->vat_src_code = $objp->vat_src_code;
751 $line->tva_tx = $objp->tva_tx;
752 $line->localtax1_tx = $objp->localtax1_tx;
753 $line->localtax1_type = $objp->localtax1_type;
754 $line->localtax2_tx = $objp->localtax2_tx;
755 $line->localtax2_type = $objp->localtax2_type;
756 $line->total_ht = $objp->total_ht;
757 $line->total_tva = $objp->total_tva;
758 $line->total_localtax1 = $objp->total_localtax1;
759 $line->total_localtax2 = $objp->total_localtax2;
760 $line->total_ttc = $objp->total_ttc;
761 $line->product_type = $objp->product_type;
762 $line->date_start = $this->db->jdate($objp->date_start);
763 $line->date_end = $this->db->jdate($objp->date_end);
764 $line->info_bits = $objp->info_bits ;
765 $line->special_code = $objp->special_code;
766 $line->rang = $objp->rang;
767 $line->fk_unit = $objp->fk_unit;
768 $line->import_key = $objp->import_key;
769 $line->fk_user_author = $objp->fk_user_author;
770 $line->fk_user_modif = $objp->fk_user_modif;
771 $line->fk_multicurrency = $objp->fk_multicurrency;
772 $line->multicurrency_code = $objp->multicurrency_code;
773 $line->multicurrency_subprice = $objp->multicurrency_subprice;
774 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
775 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
776 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
777
778 $line->fetch_optionals();
779
780 $this->lines[$i] = $line;
781
782 $i++;
783 }
784
785 $this->db->free($result);
786 return 1;
787 } else {
788 $this->error = $this->db->lasterror();
789 return -3;
790 }
791 }
792
793
802 public function delete(User $user, $notrigger = 0, $idwarehouse = -1)
803 {
804 $rowid = $this->id;
805
806 dol_syslog(get_class($this)."::delete rowid=".((int) $rowid), LOG_DEBUG);
807
808 $error = 0;
809 $this->db->begin();
810
811 $main = MAIN_DB_PREFIX.'facture_fourn_det_rec';
812 $ef = $main."_extrafields";
813
814 $sqlef = "DELETE FROM ".$ef." WHERE fk_object IN (SELECT rowid FROM ".$main." WHERE fk_facture_fourn = ". (int) $rowid .")";
815 $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_fourn_det_rec WHERE fk_facture_fourn = ". (int) $rowid;
816
817 if ($this->db->query($sqlef) && $this->db->query($sql)) {
818 $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_fourn_rec WHERE rowid = ". (int) $rowid;
819 dol_syslog($sql);
820 if ($this->db->query($sql)) {
821 // Delete linked object
822 $res = $this->deleteObjectLinked();
823 if ($res < 0) {
824 $error = -3;
825 }
826 // Delete extrafields
827 $res = $this->deleteExtraFields();
828 if ($res < 0) {
829 $error = -4;
830 }
831 } else {
832 $this->error = $this->db->lasterror();
833 $error = -1;
834 }
835 } else {
836 $this->error = $this->db->lasterror();
837 $error = -2;
838 }
839 if (!$error && !$notrigger) {
840 // Call trigger
841 $result = $this->call_trigger('SUPPLIERBILLREC_DELETE', $user);
842 if ($result < 0) {
843 $error++;
844 }
845 // End call triggers
846 }
847 if (! $error) {
848 $this->db->commit();
849 return 1;
850 } else {
851 $this->db->rollback();
852 return $error;
853 }
854 }
855
882 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)
883 {
884 global $mysoc, $user;
885
886 include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
887
888 $facid = $this->id; //Supplier invoice template ID linked to
889
890 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);
891
892 // Check if object of the line is product or service
893 if ($type < 0) {
894 return -1;
895 }
896
897 if ($this->suspended == self::STATUS_NOTSUSPENDED) {
898 $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
899
900 // Clean vat code
901 $reg = array();
902 $vat_src_code = '';
903 if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
904 $vat_src_code = $reg[1];
905 $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
906 }
907
908 // Clean parameters
909 $fk_product = empty($fk_product) ? 0 : $fk_product;
910 $label = empty($label) ? '' : $label;
911 $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
912 $qty = price2num($qty);
913 $pu_ht = price2num($pu_ht);
914 $pu_ttc = price2num($pu_ttc);
915 if (!preg_match('/\‍((.*)\‍)/', $txtva)) {
916 $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
917 }
918 $txlocaltax1 = price2num($txlocaltax1);
919 $txlocaltax2 = price2num($txlocaltax2);
920 $txtva = !empty($txtva) ? $txtva : 0;
921 $txlocaltax1 = !empty($txlocaltax1) ? $txlocaltax1 : 0;
922 $txlocaltax2 = !empty($txlocaltax2) ? $txlocaltax2 : 0;
923 $info_bits = !empty($info_bits) ? $info_bits : 0;
924 $info_bits = !empty($info_bits) ? $info_bits : 0;
925 $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
926
927 // Calcul du total TTC et de la TVA pour la ligne a partir de qty, pu, remise_percent et txtva
928 // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
929 // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
930
931 $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);
932 $total_ht = $tabprice[0];
933 $total_tva = $tabprice[1];
934 $total_ttc = $tabprice[2];
935 $total_localtax1 = $tabprice[9];
936 $total_localtax2 = $tabprice[10];
937 $pu_ht = $tabprice[3];
938
939 // MultiCurrency
940 $multicurrency_total_ht = $tabprice[16];
941 $multicurrency_total_tva = $tabprice[17];
942 $multicurrency_total_ttc = $tabprice[18];
943 $pu_ht_devise = $tabprice[19];
944
945 $this->db->begin();
946 $product_type = $type;
947 if ($fk_product) {
948 $product = new Product($this->db);
949 $result = $product->fetch($fk_product);
950 if ($result < 0) {
951 return -1;
952 }
953 $product_type = $product->type;
954 if (empty($label)) {
955 $label = $product->label;
956 }
957 }
958
959 $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec (';
960 $sql .= 'fk_facture_fourn';
961 $sql .= ', fk_product';
962 $sql .= ', ref';
963 $sql .= ', label';
964 $sql .= ', description';
965 $sql .= ', pu_ht';
966 $sql .= ', pu_ttc';
967 $sql .= ', qty';
968 $sql .= ', remise_percent';
969 $sql .= ', fk_remise_except';
970 $sql .= ', vat_src_code';
971 $sql .= ', tva_tx';
972 $sql .= ', localtax1_tx';
973 $sql .= ', localtax1_type';
974 $sql .= ', localtax2_tx';
975 $sql .= ', localtax2_type';
976 $sql .= ', total_ht';
977 $sql .= ', total_tva';
978 $sql .= ', total_localtax1';
979 $sql .= ', total_localtax2';
980 $sql .= ', total_ttc';
981 $sql .= ', product_type';
982 $sql .= ', date_start';
983 $sql .= ', date_end';
984 $sql .= ', info_bits';
985 $sql .= ', special_code';
986 $sql .= ', rang';
987 $sql .= ', fk_unit';
988 $sql .= ', fk_user_author';
989 $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
990 $sql .= ') VALUES (';
991 $sql .= ' ' . (int) $facid; // source supplier invoice id
992 $sql .= ', ' . (!empty($fk_product) ? "'" . $this->db->escape($fk_product) . "'" : 'null');
993 $sql .= ', ' . (!empty($ref) ? "'" . $this->db->escape($ref) . "'" : 'null');
994 $sql .= ', ' . (!empty($label) ? "'" . $this->db->escape($label) . "'" : 'null');
995 $sql .= ", '" . $this->db->escape($desc) . "'";
996 $sql .= ', ' . price2num($pu_ht);
997 $sql .= ', ' . price2num($pu_ttc);
998 $sql .= ', ' . price2num($qty);
999 $sql .= ', ' . price2num($remise_percent);
1000 $sql .= ', null';
1001 $sql .= ", '" . $this->db->escape($vat_src_code) . "'";
1002 $sql .= ', ' . price2num($txtva);
1003 $sql .= ', ' . price2num($txlocaltax1);
1004 $sql .= ", '" . $this->db->escape(isset($localtaxes_type[0]) ? $localtaxes_type[0] : '') . "'";
1005 $sql .= ', ' . price2num($txlocaltax2);
1006 $sql .= ", '" . $this->db->escape(isset($localtaxes_type[2]) ? $localtaxes_type[2] : '') . "'";
1007 $sql .= ', ' . price2num($total_ht);
1008 $sql .= ', ' . price2num($total_tva);
1009 $sql .= ', ' . price2num($total_localtax1);
1010 $sql .= ', ' . price2num($total_localtax2);
1011 $sql .= ', ' . price2num($total_ttc);
1012 $sql .= ', ' . (int) $product_type;
1013 $sql .= ', ' . ($date_start > 0 ? (int) $date_start : 'NULL');
1014 $sql .= ', ' . ($date_end > 0 ? (int) $date_end : 'NULL');
1015 $sql .= ', ' . (int) $info_bits;
1016 $sql .= ', ' . (int) $special_code;
1017 $sql .= ', ' . (int) $rang;
1018 $sql .= ', ' . ($fk_unit ? (int) $fk_unit : 'NULL');
1019 $sql .= ', ' . (int) $user->id;
1020 $sql .= ', ' . (int) $this->fk_multicurrency;
1021 $sql .= ", '" . $this->db->escape($this->multicurrency_code) . "'";
1022 $sql .= ', ' . price2num($pu_ht_devise, 'CU');
1023 $sql .= ', ' . price2num($multicurrency_total_ht, 'CT');
1024 $sql .= ', ' . price2num($multicurrency_total_tva, 'CT');
1025 $sql .= ', ' . price2num($multicurrency_total_ttc, 'CT');
1026 $sql .= ')';
1027
1028 dol_syslog(get_class($this). '::addline', LOG_DEBUG);
1029 if ($this->db->query($sql)) {
1030 $lineId = $this->db->last_insert_id(MAIN_DB_PREFIX. 'facture_fourn_det_rec');
1031 $this->update_price();
1032 $this->id = $facid;
1033 $this->db->commit();
1034 return $lineId;
1035 } else {
1036 $this->db->rollback();
1037 $this->error = $this->db->lasterror();
1038
1039 return -1;
1040 }
1041 } else {
1042 $this->error = 'Recurring Invoice is suspended. adding lines not allowed.';
1043
1044 return -1;
1045 }
1046 }
1047
1074 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)
1075 {
1076 global $mysoc, $user;
1077
1078 $facid = $this->id;
1079
1080 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);
1081 include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
1082
1083 // Check parameters
1084 if ($type < 0) {
1085 return -1;
1086 }
1087
1088 if ($this->brouillon) {
1089 // Clean parameters
1090 $fk_product = empty($fk_product) ? 0 : $fk_product;
1091 $label = empty($label) ? '' : $label;
1092 $remise_percent = empty($remise_percent) ? 0 : price2num($remise_percent);
1093 $qty = price2num($qty);
1094 $info_bits = empty($info_bits) ? 0 : $info_bits;
1095 $pu_ht = price2num($pu_ht);
1096 $pu_ttc = price2num($pu_ttc);
1097 $pu_ht_devise = price2num($pu_ht_devise);
1098
1099 if (!preg_match('/\‍((.*)\‍)/', $txtva)) {
1100 $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
1101 }
1102
1103 $txlocaltax1 = empty($txlocaltax1) ? 0 : price2num($txlocaltax1);
1104 $txlocaltax2 = empty($txlocaltax2) ? 0 : price2num($txlocaltax2);
1105 $this->multicurrency_subprice = empty($this->multicurrency_subprice) ? 0 : $this->multicurrency_subprice;
1106 $this->multicurrency_total_ht = empty($this->multicurrency_total_ht) ? 0 : $this->multicurrency_total_ht;
1107 $this->multicurrency_total_tva = empty($this->multicurrency_total_tva) ? 0 : $this->multicurrency_total_tva;
1108 $this->multicurrency_total_ttc = empty($this->multicurrency_total_ttc) ? 0 : $this->multicurrency_total_ttc;
1109
1110 $pu = $price_base_type == 'HT' ? $pu_ht : $pu_ttc;
1111
1112
1113 // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
1114 // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
1115 // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
1116
1117 $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
1118
1119 // Clean vat code
1120 $vat_src_code = '';
1121 $reg = array();
1122 if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
1123 $vat_src_code = $reg[1];
1124 $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
1125 }
1126
1127 $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);
1128
1129 $total_ht = $tabprice[0];
1130 $total_tva = $tabprice[1];
1131 $total_ttc = $tabprice[2];
1132 $total_localtax1 = $tabprice[9];
1133 $total_localtax2 = $tabprice[10];
1134 $pu_ht = $tabprice[3];
1135 $pu_tva = $tabprice[4];
1136 $pu_ttc = $tabprice[5];
1137
1138 // MultiCurrency
1139 $multicurrency_total_ht = $tabprice[16];
1140 $multicurrency_total_tva = $tabprice[17];
1141 $multicurrency_total_ttc = $tabprice[18];
1142 $pu_ht_devise = $tabprice[19];
1143
1144 $product_type = $type;
1145 if ($fk_product) {
1146 $product = new Product($this->db);
1147 $result = $product->fetch($fk_product);
1148 $product_type = $product->type;
1149 }
1150
1151 $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
1152 $sql .= ' fk_facture_fourn = ' . ((int) $facid);
1153 $sql .= ', fk_product = ' . ($fk_product > 0 ? ((int) $fk_product) : 'null');
1154 $sql .= ", ref = '" . $this->db->escape($ref) . "'";
1155 $sql .= ", label = '" . $this->db->escape($label) . "'";
1156 $sql .= ", description = '" . $this->db->escape($desc) . "'";
1157 $sql .= ', pu_ht = ' . price2num($pu_ht);
1158 $sql .= ', qty = ' . price2num($qty);
1159 $sql .= ", remise_percent = '" . price2num($remise_percent) . "'";
1160 $sql .= ", vat_src_code = '" . $this->db->escape($vat_src_code) . "'";
1161 $sql .= ', tva_tx = ' . price2num($txtva);
1162 $sql .= ', localtax1_tx = ' . (float) $txlocaltax1;
1163 $sql .= ", localtax1_type = '" . $this->db->escape($localtaxes_type[0]) . "'";
1164 $sql .= ', localtax2_tx = ' . (float) $txlocaltax2;
1165 $sql .= ", localtax2_type = '" . $this->db->escape($localtaxes_type[2]) . "'";
1166 $sql .= ", total_ht = '" . price2num($total_ht) . "'";
1167 $sql .= ", total_tva = '" . price2num($total_tva) . "'";
1168 $sql .= ", total_localtax1 = '" . price2num($total_localtax1) . "'";
1169 $sql .= ", total_localtax2 = '" . price2num($total_localtax2) . "'";
1170 $sql .= ", total_ttc = '" . price2num($total_ttc) . "'";
1171 $sql .= ', product_type = ' . (int) $product_type;
1172 $sql .= ', date_start = ' . (empty($date_start) ? 'NULL' : (int) $date_start);
1173 $sql .= ', date_end = ' . (empty($date_end) ? 'NULL' : (int) $date_end);
1174 $sql .= ', info_bits = ' . (int) $info_bits;
1175 $sql .= ', special_code = ' . (int) $special_code;
1176 $sql .= ', rang = ' . (int) $rang;
1177 $sql .= ', fk_unit = ' . ($fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : 'null');
1178 $sql .= ', fk_user_modif = ' . (int) $user;
1179 $sql .= ', multicurrency_subprice = '.price2num($pu_ht_devise);
1180 $sql .= ', multicurrency_total_ht = '.price2num($multicurrency_total_ht);
1181 $sql .= ', multicurrency_total_tva = '.price2num($multicurrency_total_tva);
1182 $sql .= ', multicurrency_total_ttc = '.price2num($multicurrency_total_ttc);
1183 $sql .= ' WHERE rowid = ' . (int) $rowid;
1184
1185 dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
1186 if ($this->db->query($sql)) {
1187 $this->id = $facid;
1188 $this->update_price();
1189 return 1;
1190 } else {
1191 $this->error = $this->db->lasterror();
1192 return -1;
1193 }
1194 }
1195 }
1196
1197
1203 public function getNextDate()
1204 {
1205 if (empty($this->date_when)) {
1206 return false;
1207 }
1208 return dol_time_plus_duree($this->date_when, $this->frequency, $this->unit_frequency);
1209 }
1210
1216 public function isMaxNbGenReached()
1217 {
1218 $ret = false;
1219 if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) {
1220 $ret = true;
1221 }
1222 return $ret;
1223 }
1224
1231 public function strikeIfMaxNbGenReached($ret)
1232 {
1233 // Special case to strike the date
1234 return ($this->isMaxNbGenReached() ? '<strike>' : '').$ret.($this->isMaxNbGenReached() ? '</strike>' : '');
1235 }
1236
1247 public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0)
1248 {
1249 global $conf, $langs, $db, $user, $hookmanager;
1250
1251 $error = 0;
1252 $nb_create = 0;
1253
1254 // Load translation files required by the page
1255 $langs->loadLangs(array('main', 'bills'));
1256
1257 $now = dol_now();
1258 $tmparray = dol_getdate($now);
1259 $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
1260
1261 dol_syslog('createRecurringInvoices restrictioninvoiceid=' .$restrictioninvoiceid. ' forcevalidation=' .$forcevalidation);
1262
1263 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_fourn_rec';
1264 $sql .= ' WHERE frequency > 0'; // A recurring supplier invoice is an invoice with a frequency
1265 $sql .= " AND (date_when IS NULL OR date_when <= '".$this->db->idate($today)."')";
1266 $sql .= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)';
1267 $sql .= ' AND suspended = 0';
1268 $sql .= ' AND entity = '. (int) $conf->entity; // MUST STAY = $conf->entity here
1269 if ($restrictioninvoiceid > 0) {
1270 $sql .= ' AND rowid = '. (int) $restrictioninvoiceid;
1271 }
1272 $sql .= $this->db->order('entity', 'ASC');
1273 //print $sql;exit;
1274 $parameters = array(
1275 'restrictioninvoiceid' => $restrictioninvoiceid,
1276 'forcevalidation' => $forcevalidation,
1277 );
1278 $reshook = $hookmanager->executeHooks('beforeCreationOfRecurringInvoices', $parameters, $sql); // note that $sql might be modified by hooks
1279
1280 $resql = $this->db->query($sql);
1281 if ($resql) {
1282 $i = 0;
1283 $num = $this->db->num_rows($resql);
1284
1285 if ($num) {
1286 $this->output .= $langs->trans('FoundXQualifiedRecurringInvoiceTemplate', $num)."\n";
1287 } else {
1288 $this->output .= $langs->trans('NoQualifiedRecurringInvoiceTemplateFound');
1289 }
1290
1291 $saventity = $conf->entity;
1292 $laststep="None";
1293
1294 while ($i < $num) { // Loop on each template invoice. If $num = 0, test is false at first pass.
1295 $line = $this->db->fetch_object($resql);
1296
1297 $this->db->begin();
1298
1299 $invoiceidgenerated = 0;
1300
1301 $new_fac_fourn = null;
1302 $facturerec = new FactureFournisseurRec($this->db);
1303 $laststep="Fetch {$line->rowid}";
1304 $facturerec->fetch($line->rowid);
1305
1306 if ($facturerec->id > 0) {
1307 // Set entity context
1308 $conf->entity = $facturerec->entity;
1309
1310 dol_syslog('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', ref=' .$facturerec->ref. ', entity=' .$facturerec->entity);
1311
1312 $new_fac_fourn = new FactureFournisseur($this->db);
1313 $new_fac_fourn->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice
1314 $new_fac_fourn->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice
1315
1316 $new_fac_fourn->type = self::TYPE_STANDARD;
1317 $new_fac_fourn->brouillon = 1;
1318 $new_fac_fourn->statut = self::STATUS_DRAFT;
1319 $new_fac_fourn->status = self::STATUS_DRAFT;
1320 $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.
1321 $new_fac_fourn->socid = $facturerec->socid;
1322 $new_fac_fourn->lines = $facturerec->lines;
1323 $new_fac_fourn->ref_supplier = $facturerec->ref_supplier;
1324 $new_fac_fourn->model_pdf = $facturerec->model_pdf;
1325 $new_fac_fourn->fk_project = $facturerec->fk_project;
1326 $new_fac_fourn->libelle = $facturerec->libelle;
1327
1328 $invoiceidgenerated = $new_fac_fourn->create($user);
1329 $laststep="Create invoiceidgenerated $invoiceidgenerated";
1330 if ($invoiceidgenerated <= 0) {
1331 $this->errors = $new_fac_fourn->errors;
1332 $this->error = $new_fac_fourn->error;
1333 $error++;
1334 }
1335 if (!$error && ($facturerec->auto_validate || $forcevalidation)) {
1336 $result = $new_fac_fourn->validate($user);
1337 $laststep = "Validate by user {$user->login}";
1338 if ($result <= 0) {
1339 $this->errors = $new_fac_fourn->errors;
1340 $this->error = $new_fac_fourn->error;
1341 $error++;
1342 }
1343 }
1344
1345 if (!$error && $facturerec->generate_pdf) {
1346 // We refresh the object in order to have all necessary data (like date_lim_reglement)
1347 $laststep = "Refresh {$new_fac_fourn->id}";
1348 $new_fac_fourn->fetch($new_fac_fourn->id);
1349 $laststep = "GenerateDocument {$new_fac_fourn->id}";
1350 $result = $new_fac_fourn->generateDocument($facturerec->model_pdf, $langs);
1351 if ($result < 0) {
1352 $this->errors = $new_fac_fourn->errors;
1353 $this->error = $new_fac_fourn->error;
1354 $error++;
1355 }
1356 }
1357 } else {
1358 $error++;
1359 $this->error = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity."\n";
1360 $this->errors[] = 'Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity;
1361 dol_syslog('createRecurringInvoices Failed to load invoice template with id=' .$line->rowid. ', entity=' .$conf->entity);
1362 }
1363
1364 if (!$error && $invoiceidgenerated >= 0) {
1365 $facturerec->nb_gen_done++;
1366 $facturerec->date_last_gen = dol_now();
1367 $facturerec->date_when= $facturerec->getNextDate();
1368 $facturerec->update($user);
1369 $this->db->commit('createRecurringInvoices Process invoice template id=' .$facturerec->id. ', title=' .$facturerec->titre);
1370 dol_syslog('createRecurringInvoices Process invoice template ' .$facturerec->titre. ' is finished with a success generation');
1371 $nb_create++;
1372 $this->output .= $langs->trans('InvoiceGeneratedFromTemplate', $new_fac_fourn->ref, $facturerec->titre)."\n";
1373 } else {
1374 $this->db->rollback('createRecurringInvoices Process invoice template error={$error} invoiceidgenerated={$invoiceidgenerated} LastStep={$laststep} id=' .$facturerec->id. ', title=' .$facturerec->titre);
1375 }
1376
1377 $parameters = array(
1378 'cpt' => $i,
1379 'total' => $num,
1380 'errorCount' => $error,
1381 'invoiceidgenerated' => $invoiceidgenerated,
1382 'facturerec' => $facturerec, // it's an object which PHP passes by "reference", so modifiable by hooks.
1383 'this' => $this, // it's an object which PHP passes by "reference", so modifiable by hooks.
1384 );
1385 $reshook = $hookmanager->executeHooks('afterCreationOfRecurringInvoice', $parameters, $new_fac_fourn); // note: $facture can be modified by hooks (warning: $facture can be null)
1386
1387 $i++;
1388 }
1389
1390 $conf->entity = $saventity; // Restore entity context
1391 } else {
1392 dol_print_error($this->db);
1393 }
1394
1395 $this->output = trim($this->output);
1396
1397 return $error ? $error : 0;
1398 }
1399
1412 public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = '', $save_lastsearch_value = -1)
1413 {
1414 global $langs, $hookmanager;
1415
1416 $result = '';
1417
1418 $label = '<u>'.$langs->trans('RepeatableInvoice').'</u>';
1419 if (!empty($this->ref)) {
1420 $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1421 }
1422 if ($this->frequency > 0) {
1423 $label .= '<br><b>'.$langs->trans('Frequency').':</b> '.$langs->trans('FrequencyPer_'.$this->unit_frequency, $this->frequency);
1424 }
1425 if (!empty($this->date_last_gen)) {
1426 $label .= '<br><b>'.$langs->trans('DateLastGeneration').':</b> '.dol_print_date($this->date_last_gen, 'dayhour');
1427 }
1428 if ($this->frequency > 0) {
1429 if (!empty($this->date_when)) {
1430 $label .= '<br><b>'.$langs->trans('NextDateToExecution').':</b> ';
1431 $label .= (empty($this->suspended) ? '' : '<strike>').dol_print_date($this->date_when, 'day').(empty($this->suspended) ? '' : '</strike>'); // No hour for this property
1432 if (!empty($this->suspended)) {
1433 $label .= ' ('.$langs->trans('Disabled').')';
1434 }
1435 }
1436 }
1437
1438 $url = DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$this->id;
1439
1440 if ($short) {
1441 return $url;
1442 }
1443
1444 if ($option != 'nolink') {
1445 // Add param to save lastsearch_values or not
1446 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1447 if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER['PHP_SELF'])) {
1448 $add_save_lastsearch_values = 1;
1449 }
1450 if ($add_save_lastsearch_values) {
1451 $url .= '&save_lastsearch_values=1';
1452 }
1453 }
1454
1455 $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
1456 $linkend = '</a>';
1457
1458 $result .= $linkstart;
1459 if ($withpicto) {
1460 $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);
1461 }
1462 if ($withpicto != 2) {
1463 $result .= $this->ref;
1464 }
1465 $result .= $linkend;
1466 global $action;
1467 $hookmanager->initHooks(array($this->element . 'dao'));
1468 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1469 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1470 if ($reshook > 0) {
1471 $result = $hookmanager->resPrint;
1472 } else {
1473 $result .= $hookmanager->resPrint;
1474 }
1475 return $result;
1476 }
1477
1485 public function getLibStatut($mode = 0, $alreadypaid = -1)
1486 {
1487 return $this->LibStatut($this->frequency ? 1 : 0, $this->suspended, $mode, $alreadypaid, empty($this->type) ? 0 : $this->type);
1488 }
1489
1490 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1501 public function LibStatut($recur, $status, $mode = 0, $alreadypaid = -1, $type = 0)
1502 {
1503 // phpcs:enable
1504 global $langs;
1505 $langs->load('bills');
1506
1507 $labelStatus = $langs->transnoentitiesnoconv('Active');
1508 $statusType = 'status0';
1509
1510 //print "$recur,$status,$mode,$alreadypaid,$type";
1511 if ($mode == 0) {
1512 if ($recur) {
1513 if ($status == self::STATUS_SUSPENDED) {
1514 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1515 } else {
1516 $labelStatus = $langs->transnoentitiesnoconv('Active');
1517 }
1518 } else {
1519 if ($status == self::STATUS_SUSPENDED) {
1520 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1521 } else {
1522 $labelStatus = $langs->transnoentitiesnoconv('Draft');
1523 }
1524 }
1525 } elseif ($mode == 1) {
1526 $prefix = 'Short';
1527 if ($recur) {
1528 if ($status == self::STATUS_SUSPENDED) {
1529 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1530 } else {
1531 $labelStatus = $langs->transnoentitiesnoconv('Active');
1532 }
1533 } else {
1534 if ($status == self::STATUS_SUSPENDED) {
1535 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1536 } else {
1537 $labelStatus = $langs->transnoentitiesnoconv('Draft');
1538 }
1539 }
1540 } elseif ($mode == 2) {
1541 if ($recur) {
1542 if ($status == self::STATUS_SUSPENDED) {
1543 $statusType = 'status6';
1544 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1545 } else {
1546 $statusType = 'status4';
1547 $labelStatus = $langs->transnoentitiesnoconv('Active');
1548 }
1549 } else {
1550 if ($status == self::STATUS_SUSPENDED) {
1551 $statusType = 'status6';
1552 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1553 } else {
1554 $statusType = 'status0';
1555 $labelStatus = $langs->transnoentitiesnoconv('Draft');
1556 }
1557 }
1558 } elseif ($mode == 3) {
1559 if ($recur) {
1560 $prefix = 'Short';
1561 if ($status == self::STATUS_SUSPENDED) {
1562 $statusType = 'status6';
1563 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1564 } else {
1565 $statusType = 'status4';
1566 $labelStatus = $langs->transnoentitiesnoconv('Active');
1567 }
1568 } else {
1569 if ($status == self::STATUS_SUSPENDED) {
1570 $statusType = 'status6';
1571 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1572 } else {
1573 $statusType = 'status0';
1574 $labelStatus = $langs->transnoentitiesnoconv('Draft');
1575 }
1576 }
1577 } elseif ($mode == 4) {
1578 $prefix = '';
1579 if ($recur) {
1580 if ($status == self::STATUS_SUSPENDED) {
1581 $statusType = 'status6';
1582 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1583 } else {
1584 $statusType = 'status4';
1585 $labelStatus = $langs->transnoentitiesnoconv('Active');
1586 }
1587 } else {
1588 if ($status == self::STATUS_SUSPENDED) {
1589 $statusType = 'status6';
1590 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1591 } else {
1592 $statusType = 'status0';
1593 $labelStatus = $langs->transnoentitiesnoconv('Draft');
1594 }
1595 }
1596 } elseif ($mode == 5 || $mode == 6) {
1597 $prefix = '';
1598 if ($mode == 5) {
1599 $prefix = 'Short';
1600 }
1601 if ($recur) {
1602 if ($status == self::STATUS_SUSPENDED) {
1603 $statusType = 'status6';
1604 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1605 } else {
1606 $statusType = 'status4';
1607 $labelStatus = $langs->transnoentitiesnoconv('Active');
1608 }
1609 } else {
1610 if ($status == self::STATUS_SUSPENDED) {
1611 $statusType = 'status6';
1612 $labelStatus = $langs->transnoentitiesnoconv('Disabled');
1613 } else {
1614 $statusType = 'status0';
1615 $labelStatus = $langs->transnoentitiesnoconv('Draft');
1616 }
1617 }
1618 }
1619
1620 $labelStatusShort = $labelStatus;
1621
1622 return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1623 }
1624
1633 public function initAsSpecimen($option = '')
1634 {
1635 global $user, $langs, $conf;
1636
1637 $now = dol_now();
1638 $arraynow = dol_getdate($now);
1639 $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
1640
1641 // Load array of products prodids
1642 $num_prods = 0;
1643 $prodids = array();
1644
1645 $sql = 'SELECT rowid';
1646 $sql .= ' FROM ' .MAIN_DB_PREFIX. 'product';
1647 $sql .= ' WHERE entity IN (' .getEntity('product'). ')';
1648 $sql .= $this->db->plimit(100);
1649
1650 $resql = $this->db->query($sql);
1651 if ($resql) {
1652 $num_prods = $this->db->num_rows($resql);
1653 $i = 0;
1654 while ($i < $num_prods) {
1655 $i++;
1656 $row = $this->db->fetch_row($resql);
1657 $prodids[$i] = $row[0];
1658 }
1659 }
1660
1661 // Initialize parameters
1662 $this->id = 0;
1663 $this->ref = 'SPECIMEN';
1664 $this->title = 'SPECIMEN';
1665 $this->specimen = 1;
1666 $this->socid = 1;
1667 $this->date = $nownotime;
1668 $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
1669 $this->cond_reglement_id = 1;
1670 $this->cond_reglement_code = 'RECEP';
1671 $this->date_lim_reglement = $this->calculate_date_lim_reglement();
1672 $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR
1673 $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
1674 $this->note_public = 'This is a comment (public)';
1675 $this->note_private = 'This is a comment (private)';
1676 $this->note = 'This is a comment (private)';
1677 $this->fk_incoterms = 0;
1678 $this->location_incoterms = '';
1679
1680 if (empty($option) || $option != 'nolines') {
1681 // Lines
1682 $nbp = 5;
1683 $xnbp = 0;
1684 while ($xnbp < $nbp) {
1685 $line = new FactureLigne($this->db);
1686 $line->desc = $langs->trans('Description'). ' ' .$xnbp;
1687 $line->qty = 1;
1688 $line->subprice = 100;
1689 $line->tva_tx = 19.6;
1690 $line->localtax1_tx = 0;
1691 $line->localtax2_tx = 0;
1692 $line->remise_percent = 0;
1693 if ($xnbp == 1) { // Qty is negative (product line)
1694 $prodid = mt_rand(1, $num_prods);
1695 $line->fk_product = $prodids[$prodid];
1696 $line->qty = -1;
1697 $line->total_ht = -100;
1698 $line->total_ttc = -119.6;
1699 $line->total_tva = -19.6;
1700 } elseif ($xnbp == 2) { // UP is negative (free line)
1701 $line->subprice = -100;
1702 $line->total_ht = -100;
1703 $line->total_ttc = -119.6;
1704 $line->total_tva = -19.6;
1705 $line->remise_percent = 0;
1706 } elseif ($xnbp == 3) { // Discount is 50% (product line)
1707 $prodid = mt_rand(1, $num_prods);
1708 $line->fk_product = $prodids[$prodid];
1709 $line->total_ht = 50;
1710 $line->total_ttc = 59.8;
1711 $line->total_tva = 9.8;
1712 $line->remise_percent = 50;
1713 } else // (product line)
1714 {
1715 $prodid = mt_rand(1, $num_prods);
1716 $line->fk_product = $prodids[$prodid];
1717 $line->total_ht = 100;
1718 $line->total_ttc = 119.6;
1719 $line->total_tva = 19.6;
1720 $line->remise_percent = 00;
1721 }
1722
1723 $this->lines[$xnbp] = $line;
1724 $xnbp++;
1725
1726 $this->total_ht += $line->total_ht;
1727 $this->total_tva += $line->total_tva;
1728 $this->total_ttc += $line->total_ttc;
1729 }
1730 $this->revenuestamp = 0;
1731
1732 // Add a line "offered"
1733 $line = new FactureLigne($this->db);
1734 $line->desc = $langs->trans('Description'). ' (offered line)';
1735 $line->qty = 1;
1736 $line->subprice = 100;
1737 $line->tva_tx = 19.6;
1738 $line->localtax1_tx = 0;
1739 $line->localtax2_tx = 0;
1740 $line->remise_percent = 100;
1741 $line->total_ht = 0;
1742 $line->total_ttc = 0; // 90 * 1.196
1743 $line->total_tva = 0;
1744 $prodid = mt_rand(1, $num_prods);
1745 $line->fk_product = $prodids[$prodid];
1746
1747 $this->lines[$xnbp] = $line;
1748 $xnbp++;
1749 }
1750
1751 $this->usenewprice = 0;
1752 }
1753
1762 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1763 {
1764 $tables = array(
1765 'facture_rec'
1766 );
1767
1768 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1769 }
1770
1778 public function setFrequencyAndUnit($frequency, $unit)
1779 {
1780 if (!$this->table_element) {
1781 dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with property table_element not defined', LOG_ERR);
1782 return -1;
1783 }
1784
1785 if (!empty($frequency) && empty($unit)) {
1786 dol_syslog(get_class($this). '::setFrequencyAndUnit was called on objet with params frequency defined but unit not defined', LOG_ERR);
1787 return -2;
1788 }
1789
1790 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1791 $sql .= " SET frequency = ".($frequency ? ((int) $frequency) : "NULL");
1792 if (!empty($unit)) {
1793 $sql .= ", unit_frequency = '".$this->db->escape($unit)."'";
1794 }
1795 $sql .= " WHERE rowid = ".((int) $this->id);
1796
1797 dol_syslog(get_class($this).'::setFrequencyAndUnit', LOG_DEBUG);
1798
1799 if ($this->db->query($sql)) {
1800 $this->frequency = $frequency;
1801 if (!empty($unit)) {
1802 $this->unit_frequency = $unit;
1803 }
1804 return 1;
1805 } else {
1806 $this->error = $this->db->lasterror();
1807 return -1;
1808 }
1809 }
1810
1818 public function setNextDate($date, $increment_nb_gen_done = 0)
1819 {
1820 if (!$this->table_element) {
1821 dol_syslog(get_class($this).'::setNextDate was called on objet with property table_element not defined', LOG_ERR);
1822 return -1;
1823 }
1824 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1825 $sql .= " SET date_when = " .($date ? "'".$this->db->idate($date)."'" : "NULL");
1826 if ($increment_nb_gen_done > 0) {
1827 $sql .= ", nb_gen_done = nb_gen_done + 1";
1828 }
1829 $sql .= " WHERE rowid = " . (int) $this->id;
1830
1831 dol_syslog(get_class($this).'::setNextDate', LOG_DEBUG);
1832
1833 if ($this->db->query($sql)) {
1834 $this->date_when = $date;
1835 if ($increment_nb_gen_done > 0) {
1836 $this->nb_gen_done++;
1837 }
1838 return 1;
1839 } else {
1840 $this->error = $this->db->lasterror();
1841 return -1;
1842 }
1843 }
1844
1851 public function setMaxPeriod($nb)
1852 {
1853 if (!$this->table_element) {
1854 dol_syslog(get_class($this).'::setMaxPeriod was called on objet with property table_element not defined', LOG_ERR);
1855 return -1;
1856 }
1857
1858 if (empty($nb)) {
1859 $nb = 0;
1860 }
1861
1862 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1863 $sql .= " SET nb_gen_max = ". (int) $nb;
1864 $sql .= " WHERE rowid = " . (int) $this->id;
1865
1866 dol_syslog(get_class($this).'::setMaxPeriod', LOG_DEBUG);
1867
1868 if ($this->db->query($sql)) {
1869 $this->nb_gen_max = $nb;
1870 return 1;
1871 } else {
1872 dol_print_error($this->db);
1873 return -1;
1874 }
1875 }
1876
1883 public function setAutoValidate($validate)
1884 {
1885 if (!$this->table_element) {
1886 dol_syslog(get_class($this).'::setAutoValidate was called on objet with property table_element not defined', LOG_ERR);
1887 return -1;
1888 }
1889
1890 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1891 $sql .= " SET auto_validate = ".((int) $validate);
1892 $sql .= " WHERE rowid = " . (int) $this->id;
1893
1894 dol_syslog(get_class($this).'::setAutoValidate', LOG_DEBUG);
1895
1896 if ($this->db->query($sql)) {
1897 $this->auto_validate = $validate;
1898 return 1;
1899 } else {
1900 dol_print_error($this->db);
1901 return -1;
1902 }
1903 }
1904
1911 public function setGeneratePdf($validate)
1912 {
1913 if (!$this->table_element) {
1914 dol_syslog(get_class($this).'::setGeneratePdf was called on objet with property table_element not defined', LOG_ERR);
1915 return -1;
1916 }
1917
1918 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1919 $sql .= " SET generate_pdf = ". (int) $validate;
1920 $sql .= " WHERE rowid = " . (int) $this->id;
1921
1922 dol_syslog(get_class($this).'::setGeneratePdf', LOG_DEBUG);
1923
1924 if ($this->db->query($sql)) {
1925 $this->generate_pdf = $validate;
1926 return 1;
1927 } else {
1928 dol_print_error($this->db);
1929 return -1;
1930 }
1931 }
1932
1939 public function setModelPdf($model)
1940 {
1941 if (!$this->table_element) {
1942 dol_syslog(get_class($this).'::setModelPdf was called on objet with property table_element not defined', LOG_ERR);
1943 return -1;
1944 }
1945
1946 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1947 $sql .= " SET modelpdf = '".$this->db->escape($model)."'";
1948 $sql .= " WHERE rowid = " . (int) $this->id;
1949
1950 dol_syslog(get_class($this).'::setModelPdf', LOG_DEBUG);
1951
1952 if ($this->db->query($sql)) {
1953 $this->model_pdf = $model;
1954 return 1;
1955 } else {
1956 dol_print_error($this->db);
1957 return -1;
1958 }
1959 }
1960}
1961
1962
1963
1969{
1973 public $element = 'invoice_supplier_det_rec';
1974
1978 public $table_element = 'facture_fourn_det_rec';
1979
1980 public $fk_facture_fourn;
1981 public $fk_parent;
1982 public $fk_product;
1983 public $ref_supplier;
1984 public $label;
1985 public $description;
1986 public $pu_ht;
1987 public $pu_ttc;
1988 public $qty;
1989 public $remise_percent;
1990 public $fk_remise_except;
1991 public $vat_src_code;
1992 public $tva_tx;
1993 public $localtax1_tx;
1994 public $localtax1_type;
1995 public $localtax2_tx;
1996 public $localtax2_type;
1997
1998 public $product_type;
1999 public $date_start;
2000 public $date_end;
2001 public $info_bits;
2002 public $special_code;
2003 public $rang;
2004
2005 public $fk_user_author;
2006 public $fk_user_modif;
2007 public $fk_multicurrency;
2008 public $multicurrency_subprice;
2009
2010
2011 /* Overrides fields in CommonObject
2012 public $total_ht;
2013 public $total_tva;
2014 public $total_localtax1;
2015 public $total_localtax2;
2016 public $total_ttc;
2017
2018 public $fk_unit;
2019 public $import_key;
2020 public $multicurrency_code;
2021 public $multicurrency_total_ht;
2022 public $multicurrency_total_tva;
2023 public $multicurrency_total_ttc;
2024 */
2025
2026
2034 public function delete(User $user, $notrigger = false)
2035 {
2036 $error = 0;
2037 $this->db->begin();
2038
2039 if (! $error) {
2040 if (! $notrigger) {
2041 // Call triggers
2042 $result = $this->call_trigger('LINESUPPLIERBILLREC_DELETE', $user);
2043 if ($result < 0) {
2044 $error++;
2045 } // Do also here what you must do to rollback action if trigger fail
2046 // End call triggers
2047 }
2048 }
2049
2050 if (! $error) {
2051 $result = $this->deleteExtraFields();
2052 if ($result < 0) {
2053 $error++;
2054 }
2055 }
2056
2057 if (! $error) {
2058 $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element . ' WHERE rowid=' . (int) $this->id;
2059
2060 $res = $this->db->query($sql);
2061 if ($res === false) {
2062 $error++;
2063 $this->errors[] = $this->db->lasterror();
2064 }
2065 }
2066
2067 // Commit or rollback
2068 if ($error) {
2069 $this->db->rollback();
2070 return -1;
2071 } else {
2072 $this->db->commit();
2073 return 1;
2074 }
2075 }
2076
2077
2084 public function fetch($rowid)
2085 {
2086 $sql = 'SELECT l.rowid,';
2087 $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product,';
2088 $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,';
2089 $sql .= ' l.vat_src_code, l.tva_tx, l.localtax1_tx, l.localtax1_type, l.localtax2_tx, l.localtax2_type,';
2090 $sql .= ' l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc,';
2091 $sql .= ' l.product_type, l.date_start, l.date_end,';
2092 $sql .= ' l.info_bits, l.special_code, l.rang, l.fk_unit, l.import_key,';
2093 $sql .= ' l.fk_user_author, l.fk_user_modif, l.fk_multicurrency,';
2094 $sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2095 $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2096 $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det_rec as l';
2097 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
2098 $sql .= ' WHERE l.rowid = '. (int) $rowid;
2099 $sql .= ' ORDER BY l.rang';
2100
2101 dol_syslog('FactureRec::fetch', LOG_DEBUG);
2102 $result = $this->db->query($sql);
2103 if ($result) {
2104 $objp = $this->db->fetch_object($result);
2105
2106 $this->id = $objp->rowid;
2107 $this->fk_facture_fourn = $objp->fk_facture_fourn;
2108 $this->fk_parent = $objp->fk_parent_line;
2109 $this->fk_product = $objp->fk_product;
2110 $this->ref_supplier = $objp->ref_supplier;
2111 $this->label = $objp->label;
2112 $this->description = $objp->description;
2113 $this->pu_ht = $objp->pu_ht;
2114 $this->pu_ttc = $objp->pu_ttc;
2115 $this->qty = $objp->qty;
2116 $this->remise_percent = $objp->remise_percent;
2117 $this->fk_remise_except = $objp->fk_remise_except;
2118 $this->vat_src_code = $objp->vat_src_code;
2119 $this->tva_tx = $objp->tva_tx;
2120 $this->localtax1_tx = $objp->localtax1_tx;
2121 $this->localtax1_type = $objp->localtax1_type;
2122 $this->localtax2_tx = $objp->localtax2_tx;
2123 $this->localtax2_type = $objp->localtax2_type;
2124 $this->total_ht = $objp->total_ht;
2125 $this->total_tva = $objp->total_tva;
2126 $this->total_localtax1 = $objp->total_localtax1;
2127 $this->total_localtax2 = $objp->total_localtax2;
2128 $this->total_ttc = $objp->total_ttc;
2129 $this->product_type = $objp->product_type;
2130 $this->date_start = $this->db->jdate($objp->date_start);
2131 $this->date_end = $this->db->jdate($objp->date_end);
2132 $this->info_bits = $objp->info_bits;
2133 $this->special_code = $objp->special_code;
2134 $this->rang = $objp->rang;
2135 $this->fk_unit = $objp->fk_unit;
2136 $this->import_key = $objp->import_key;
2137 $this->fk_user_author = $objp->fk_user_author;
2138 $this->fk_user_modif = $objp->fk_user_modif;
2139 $this->fk_multicurrency = $objp->fk_multicurrency;
2140 $this->multicurrency_code = $objp->multicurrency_code;
2141 $this->multicurrency_subprice = $objp->multicurrency_subprice;
2142 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
2143 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
2144 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2145
2146 $this->db->free($result);
2147 return 1;
2148 } else {
2149 $this->error = $this->db->lasterror();
2150 return -3;
2151 }
2152 }
2153
2154
2162 public function update(User $user, $notrigger = 0)
2163 {
2164 global $conf;
2165
2166 $error = 0;
2167
2168 include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
2169
2170 $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture_fourn_det_rec SET';
2171 $sql .= ' fk_facture_fourn = ' . (int) $this->fk_facture_fourn;
2172 $sql .= ', fk_parent_line = ' . (int) $this->fk_parent;
2173 $sql .= ', fk_product = ' . (int) $this->fk_product;
2174 $sql .= ', ref = ' . (!empty($this->ref) ? "'" . $this->db->escape($this->ref) . "'" : 'NULL');
2175 $sql .= ", label = " . (!empty($this->label) ? "'" . $this->db->escape($this->label) . "'" : 'NULL');
2176 $sql .= ", description = '" . $this->db->escape($this->description) . "'";
2177 $sql .= ', pu_ht = ' . price2num($this->pu_ht);
2178 $sql .= ', pu_ttc = ' . price2num($this->pu_ttc);
2179 $sql .= ', qty = ' . price2num($this->qty);
2180 $sql .= ", remise_percent = '" . price2num($this->remise_percent) . "'";
2181 $sql .= ', fk_remise_except = ' . (int) $this->fk_remise_except;
2182 $sql .= ", vat_src_code = '" . $this->db->escape($this->vat_src_code) . "'";
2183 $sql .= ', tva_tx = ' . price2num($this->tva_tx);
2184 $sql .= ', localtax1_tx = ' . price2num($this->localtax1_tx);
2185 $sql .= ", localtax1_type = '" . $this->db->escape($this->localtax1_type) . "'";
2186 $sql .= ', localtax2_tx = ' . price2num($this->localtax2_tx);
2187 $sql .= ", localtax2_type = '" . $this->db->escape($this->localtax2_type) . "'";
2188 if (empty($this->skip_update_total)) {
2189 $sql .= ', total_ht = ' . price2num($this->total_ht);
2190 $sql .= ', total_tva = ' . price2num($this->total_tva);
2191 $sql .= ', total_localtax1 = ' . price2num($this->total_localtax1);
2192 $sql .= ', total_localtax2 = ' . price2num($this->total_localtax2);
2193 $sql .= ', total_ttc = ' . price2num($this->total_ttc);
2194 }
2195 $sql .= ', product_type = ' . (int) $this->product_type;
2196 $sql .= ', date_start = ' . (int) $this->date_start;
2197 $sql .= ', date_end = ' . (int) $this->date_end;
2198 $sql .= ", info_bits = " . ((int) $this->info_bits);
2199 $sql .= ', special_code =' . (int) $this->special_code;
2200 $sql .= ', rang = ' . (int) $this->rang;
2201 $sql .= ', fk_unit = ' .($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : 'null');
2202 $sql .= ', fk_user_modif = ' . (int) $user->id;
2203 $sql .= ' WHERE rowid = ' . (int) $this->id;
2204
2205 $this->db->begin();
2206
2207 dol_syslog(get_class($this). '::updateline', LOG_DEBUG);
2208 $resql = $this->db->query($sql);
2209 if ($resql) {
2210 if (!$error) {
2211 $result = $this->insertExtraFields();
2212 if ($result < 0) {
2213 $error++;
2214 }
2215 }
2216
2217 if (!$error && !$notrigger) {
2218 // Call trigger
2219 $result = $this->call_trigger('LINESUPPLIERBILLREC_MODIFY', $user);
2220 if ($result < 0) {
2221 $error++;
2222 }
2223 // End call triggers
2224 }
2225
2226 if ($error) {
2227 $this->db->rollback();
2228 return -2;
2229 } else {
2230 $this->db->commit();
2231 return 1;
2232 }
2233 } else {
2234 $this->error = $this->db->lasterror();
2235 $this->db->rollback();
2236 return -2;
2237 }
2238 }
2239}
$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