dolibarr 22.0.5
asset.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2018-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
4 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Jose MARTINEZ <jose.martinez@pichinov.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
28require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29
33class Asset extends CommonObject
34{
38 public $module = 'asset';
39
43 public $element = 'asset';
44
48 public $table_element = 'asset';
49
53 public $picto = 'asset';
54
59 public $fk_element = 'fk_asset';
60
67 protected $childtablesoncascade = array(
68 '@AssetAccountancyCodes:/asset/class/assetaccountancycodes.class.php:fk_asset',
69 '@AssetAccountancyCodesFiscal:/asset/class/assetaccountancycodesfiscal.class.php:fk_asset'
70 );
71
72
73 const STATUS_DRAFT = 0; // Draft
74 const STATUS_VALIDATED = 1; // In progress
75 const STATUS_DISPOSED = 9; // Disposed
76
108 public $fields = array(
109 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
110 'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => 4, 'noteditable' => 0, 'default' => '(PROV)', 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'validate' => 1, 'comment' => "Reference of object", "css" => "maxwidth150"),
111 'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'position' => 30, 'notnull' => 1, 'visible' => 1, 'searchall' => 1, 'csslist' => 'tdoverflowmax125', 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1,),
112 'fk_asset_model' => array('type' => 'integer:AssetModel:asset/class/assetmodel.class.php:1:((status:=:1) and (entity:IN:__SHARED_ENTITIES__))', 'label' => 'AssetModel', 'enabled' => 1, 'position' => 40, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'validate' => 1, 'csslist' => 'tdoverflowmax75', 'css' => 'maxwidth300'),
113 'qty' => array('type' => 'real', 'label' => 'Qty', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 0, 'default' => '1', 'isameasure' => 1, 'css' => 'maxwidth75imp', 'validate' => 1,),
114 'acquisition_type' => array('type' => 'smallint', 'label' => 'AssetAcquisitionType', 'enabled' => 1, 'position' => 60, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => array(0 => 'AssetAcquisitionTypeNew', 1 => 'AssetAcquisitionTypeOccasion'), 'validate' => 1, 'csslist' => 'tdoverflowmax75'),
115 'asset_type' => array('type' => 'smallint', 'label' => 'AssetType', 'enabled' => 1, 'position' => 70, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => array(0 => 'AssetTypeIntangible', 1 => 'AssetTypeTangible', 2 => 'AssetTypeInProgress', 3 => 'AssetTypeFinancial'), 'validate' => 1, 'csslist' => 'tdoverflowmax75'),
116 'not_depreciated' => array('type' => 'boolean', 'label' => 'AssetNotDepreciated', 'enabled' => 1, 'position' => 80, 'notnull' => 0, 'default' => '0', 'visible' => 1, 'validate' => 1, 'csslist' => 'maxwidth50 tdoverflowmax50', 'css' => 'maxwidth50imp'),
117 'date_acquisition' => array('type' => 'date', 'label' => 'AssetDateAcquisition', 'enabled' => 1, 'position' => 90, 'notnull' => 1, 'visible' => 1,),
118 'date_start' => array('type' => 'date', 'label' => 'AssetDateStart', 'enabled' => 1, 'position' => 100, 'notnull' => 0, 'visible' => -1,),
119 'acquisition_value_ht' => array('type' => 'price', 'label' => 'AssetAcquisitionValueHT', 'enabled' => 1, 'position' => 110, 'notnull' => 1, 'visible' => 1, 'isameasure' => 1, 'validate' => 1,),
120 'recovered_vat' => array('type' => 'price', 'label' => 'AssetRecoveredVAT', 'enabled' => 1, 'position' => 120, 'notnull' => 0, 'visible' => 1, 'isameasure' => 1, 'validate' => 1,),
121 'reversal_date' => array('type' => 'date', 'label' => 'AssetReversalDate', 'enabled' => 1, 'position' => 130, 'notnull' => 0, 'visible' => 1,),
122 'reversal_amount_ht' => array('type' => 'price', 'label' => 'AssetReversalAmountHT', 'enabled' => 1, 'position' => 140, 'notnull' => 0, 'visible' => 1, 'isameasure' => 1, 'validate' => 1, 'csslist' => 'maxwidth50'),
123 'disposal_date' => array('type' => 'date', 'label' => 'AssetDisposalDate', 'enabled' => 1, 'position' => 200, 'notnull' => 0, 'visible' => -2,),
124 'disposal_amount_ht' => array('type' => 'price', 'label' => 'AssetDisposalAmount', 'enabled' => 1, 'position' => 210, 'notnull' => 0, 'visible' => -2, 'default' => '0', 'isameasure' => 1, 'validate' => 1,),
125 'fk_disposal_type' => array('type' => 'sellist:c_asset_disposal_type:label:rowid::active=1', 'label' => 'AssetDisposalType', 'enabled' => 1, 'position' => 220, 'notnull' => 0, 'visible' => -2, 'index' => 1, 'validate' => 1,),
126 'disposal_depreciated' => array('type' => 'boolean', 'label' => 'AssetDisposalDepreciated', 'enabled' => 1, 'position' => 230, 'notnull' => 0, 'default' => '0', 'visible' => -2, 'validate' => 1,),
127 'disposal_subject_to_vat' => array('type' => 'boolean', 'label' => 'AssetDisposalSubjectToVat', 'enabled' => 1, 'position' => 240, 'notnull' => 0, 'default' => '0', 'visible' => -2, 'validate' => 1,),
128 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 300, 'notnull' => 0, 'visible' => 0, 'validate' => 1,),
129 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 301, 'notnull' => 0, 'visible' => 0, 'validate' => 1,),
130 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
131 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
132 'date_valid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -2, 'position' => 502, 'notnull' => 0,),
133 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid',),
134 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
135 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'picto' => 'user', 'enabled' => 1, 'visible' => -2, 'position' => 512, 'notnull' => 0, 'csslist' => 'tdoverflowmax100'),
136 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'position' => 600, 'notnull' => 0, 'visible' => 0,),
137 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
138 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
139 'status' => array('type' => 'smallint', 'label' => 'Status', 'enabled' => 1, 'position' => 1000, 'notnull' => 1, 'default' => '0', 'visible' => 2, 'index' => 1, 'arrayofkeyval' => array(0 => 'Draft', 1 => 'Validated', 9 => 'Canceled'), 'validate' => 1,),
140 );
141
145 public $rowid;
149 public $ref;
153 public $label;
157 public $fk_asset_model;
161 public $reversal_amount_ht;
165 public $acquisition_value_ht;
169 public $recovered_vat;
173 public $reversal_date;
177 public $date_acquisition;
181 public $date_start;
185 public $qty;
189 public $acquisition_type;
193 public $asset_type;
197 public $not_depreciated;
201 public $disposal_date;
205 public $disposal_amount_ht;
209 public $fk_disposal_type;
213 public $disposal_depreciated;
217 public $disposal_subject_to_vat;
221 public $supplier_invoice_id;
225 public $note_public;
229 public $note_private;
233 public $date_valid;
237 public $fk_user_creat;
241 public $fk_user_modif;
245 public $fk_user_valid;
249 public $last_main_doc;
253 public $import_key;
257 public $model_pdf;
261 public $status;
262
266 public $asset_depreciation_options;
267
271 public $asset_accountancy_codes;
272
276 public $depreciation_lines = array();
277
278
284 public function __construct(DoliDB $db)
285 {
286 global $langs;
287
288 $this->db = $db;
289
290 $this->ismultientitymanaged = 1;
291 $this->isextrafieldmanaged = 1;
292
293 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
294 $this->fields['rowid']['visible'] = 0;
295 }
296 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
297 $this->fields['entity']['enabled'] = 0;
298 }
299
300 // Unset fields that are disabled
301 foreach ($this->fields as $key => $val) {
302 if (isset($val['enabled']) && empty($val['enabled'])) {
303 unset($this->fields[$key]);
304 }
305 }
306
307 // Translate some data of arrayofkeyval
308 if (is_object($langs)) {
309 foreach ($this->fields as $key => $val) {
310 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
311 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
312 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
313 }
314 }
315 }
316 }
317 }
318
326 public function create(User $user, $notrigger = 0)
327 {
328 if (!isset($this->date_start) || $this->date_start === "") {
329 $this->date_start = $this->date_acquisition;
330 }
331
332 $this->db->begin();
333
334 $result = $result_create = $this->createCommon($user, $notrigger);
335 if ($result > 0 && $this->fk_asset_model > 0) {
336 $result = $this->setDataFromAssetModel($user, $notrigger);
337 }
338 if ($result > 0) {
339 if ($this->supplier_invoice_id > 0) {
340 $this->add_object_linked('invoice_supplier', $this->supplier_invoice_id);
341 }
342 }
343
344 if ($result < 0) {
345 $this->db->rollback();
346 } else {
347 $this->db->commit();
348 }
349
350 return $result > 0 ? $result_create : $result;
351 }
352
360 public function createFromClone(User $user, $fromid)
361 {
362 global $langs, $extrafields;
363 $error = 0;
364
365 dol_syslog(__METHOD__, LOG_DEBUG);
366
367 // $object = new self($this->db);
368 //
369 // $this->db->begin();
370 //
371 // // Load source object
372 // $result = $object->fetchCommon($fromid);
373 //
374 //
375 // // Reset some properties
376 // unset($object->id);
377 // unset($object->fk_user_creat);
378 // unset($object->import_key);
379 //
380 // // Clear fields
381 // if (property_exists($object, 'ref')) {
382 // $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
383 // }
384 // if (property_exists($object, 'label')) {
385 // $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
386 // }
387 // if (property_exists($object, 'status')) {
388 // $object->status = self::STATUS_DRAFT;
389 // }
390 // if (property_exists($object, 'date_creation')) {
391 // $object->date_creation = dol_now();
392 // }
393 // if (property_exists($object, 'date_modification')) {
394 // $object->date_modification = null;
395 // }
396 // // ...
397 // // Clear extrafields that are unique
398 // if (is_array($object->array_options) && count($object->array_options) > 0) {
399 // $extrafields->fetch_name_optionals_label($this->table_element);
400 // foreach ($object->array_options as $key => $option) {
401 // $shortkey = preg_replace('/options_/', '', $key);
402 // if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
403 // //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
404 // unset($object->array_options[$key]);
405 // }
406 // }
407 // }
408 //
409 // // Create clone
410 // $object->context['createfromclone'] = 'createfromclone';
411 // $result = $object->createCommon($user);
412 // if ($result < 0) {
413 // $error++;
414 // $this->error = $object->error;
415 // $this->errors = $object->errors;
416 // }
417 //
418 // if (!$error) {
419 // // copy internal contacts
420 // if ($this->copy_linked_contact($object, 'internal') < 0) {
421 // $error++;
422 // }
423 // }
424 //
425 // if (!$error) {
426 // // copy external contacts if same company
427 // if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
428 // if ($this->copy_linked_contact($object, 'external') < 0) {
429 // $error++;
430 // }
431 // }
432 // }
433 //
434 // unset($object->context['createfromclone']);
435 //
436 // // End
437 // if (!$error) {
438 // $this->db->commit();
439 // return $object;
440 // } else {
441 // $this->db->rollback();
442 // return -1;
443 // }
444
445 return -1;
446 }
447
455 public function fetch($id, $ref = null)
456 {
457 $result = $this->fetchCommon($id, $ref);
458 if ($result > 0) {
459 $res = $this->hasDepreciationLinesInBookkeeping();
460 if ($res < 0) {
461 return -1;
462 } elseif ($res > 0) {
463 $this->fields['date_acquisition']['noteditable'] = 1;
464 $this->fields['date_start']['noteditable'] = 1;
465 $this->fields['acquisition_value_ht']['noteditable'] = 1;
466 $this->fields['recovered_vat']['noteditable'] = 1;
467 $this->fields['reversal_date']['noteditable'] = 1;
468 $this->fields['reversal_amount_ht']['noteditable'] = 1;
469 }
470 }
471
472 return $result;
473 }
474
475
488 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
489 {
490 dol_syslog(__METHOD__, LOG_DEBUG);
491
492 $records = array();
493
494 $sql = "SELECT ";
495 $sql .= $this->getFieldList('t');
496 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
497 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
498 $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
499 } else {
500 $sql .= " WHERE 1 = 1";
501 }
502
503 // Manage filter
504 $errormessage = '';
505 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
506 if ($errormessage) {
507 $this->errors[] = $errormessage;
508 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
509
510 return -1;
511 }
512
513 if (!empty($sortfield)) {
514 $sql .= $this->db->order($sortfield, $sortorder);
515 }
516 if (!empty($limit)) {
517 $sql .= $this->db->plimit($limit, $offset);
518 }
519
520 $resql = $this->db->query($sql);
521 if ($resql) {
522 $num = $this->db->num_rows($resql);
523 $i = 0;
524 while ($i < ($limit ? min($limit, $num) : $num)) {
525 $obj = $this->db->fetch_object($resql);
526
527 $record = new self($this->db);
528 $record->setVarsFromFetchObj($obj);
529
530 $records[$record->id] = $record;
531
532 $i++;
533 }
534 $this->db->free($resql);
535
536 return $records;
537 } else {
538 $this->errors[] = 'Error '.$this->db->lasterror();
539 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
540
541 return -1;
542 }
543 }
544
552 public function update(User $user, $notrigger = 0)
553 {
554 if (!isset($this->date_start) || $this->date_start === "") {
555 $this->date_start = $this->date_acquisition;
556 }
557
558 $this->db->begin();
559
560 $result = $this->updateCommon($user, $notrigger);
561 if ($result > 0 && $this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model) {
562 $result = $this->setDataFromAssetModel($user, $notrigger);
563 }
564 if ($result > 0 && is_object($this->oldcopy) && (
565 $this->date_start != $this->oldcopy->date_start ||
566 $this->acquisition_value_ht != $this->oldcopy->acquisition_value_ht ||
567 $this->reversal_date != $this->oldcopy->reversal_date ||
568 $this->reversal_amount_ht != $this->oldcopy->reversal_amount_ht ||
569 ($this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model)
570 )) {
571 $result = $this->calculationDepreciation();
572 }
573
574 if ($result < 0) {
575 $this->db->rollback();
576 } else {
577 $this->db->commit();
578 }
579
580 return $result;
581 }
582
590 public function delete(User $user, $notrigger = 0)
591 {
592 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_codes_economic WHERE fk_asset = '.((int) $this->id);
593 $this->db->query($sql);
594
595 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_codes_fiscal WHERE fk_asset = '.((int) $this->id);
596 $this->db->query($sql);
597
598 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_options_fiscal WHERE fk_asset = '.((int) $this->id);
599 $this->db->query($sql);
600
601 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_options_economic WHERE fk_asset = '.((int) $this->id);
602 $this->db->query($sql);
603
604 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation WHERE fk_asset = '.((int) $this->id);
605 $this->db->query($sql);
606
607 return $this->deleteCommon($user, $notrigger);
608 //return $this->deleteCommon($user, $notrigger, 1);
609 }
610
618 public function setDataFromAssetModel(User $user, $notrigger = 0)
619 {
620 global $langs;
621 $langs->load('assets');
622
623 // Clean parameters
624 $this->id = $this->id > 0 ? $this->id : 0;
625 $this->fk_asset_model = $this->fk_asset_model > 0 ? $this->fk_asset_model : 0;
626
627 // Check parameters
628 $error = 0;
629 if (empty($this->id)) {
630 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
631 $error++;
632 }
633 if (empty($this->fk_asset_model)) {
634 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetModel") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
635 $error++;
636 }
637 if ($error) {
638 return -1;
639 }
640
641 $this->db->begin();
642
643 // Get depreciation options
644 //---------------------------
645 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php';
646 $options_model = new AssetDepreciationOptions($this->db);
647 $result = $options_model->fetchDeprecationOptions(0, $this->fk_asset_model);
648 if ($result < 0) {
649 $this->error = $options_model->error;
650 $this->errors = $options_model->errors;
651 $error++;
652 } elseif ($result > 0) {
653 $options = new AssetDepreciationOptions($this->db);
654 $result = $options->fetchDeprecationOptions($this->id);
655 if ($result < 0) {
656 $this->error = $options->error;
657 $this->errors = $options->errors;
658 $error++;
659 }
660
661 if (!$error) {
662 foreach ($options_model->deprecation_options as $mode_key => $fields) {
663 foreach ($fields as $field_key => $value) {
664 $options->deprecation_options[$mode_key][$field_key] = $value;
665 }
666 }
667
668 $result = $options->updateDeprecationOptions($user, $this->id, 0, $notrigger);
669 if ($result < 0) {
670 $this->error = $options->error;
671 $this->errors = $options->errors;
672 $error++;
673 }
674 }
675 }
676
677 // Get accountancy codes
678 //---------------------------
679 if (!$error) {
680 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php';
681 $accountancy_codes_model = new AssetAccountancyCodes($this->db);
682 $result = $accountancy_codes_model->fetchAccountancyCodes(0, $this->fk_asset_model);
683 if ($result < 0) {
684 $this->error = $accountancy_codes_model->error;
685 $this->errors = $accountancy_codes_model->errors;
686 $error++;
687 } elseif ($result > 0) {
688 $accountancy_codes = new AssetAccountancyCodes($this->db);
689 $result = $accountancy_codes->fetchAccountancyCodes($this->id);
690 if ($result < 0) {
691 $this->error = $accountancy_codes->error;
692 $this->errors = $accountancy_codes->errors;
693 $error++;
694 }
695
696 if (!$error) {
697 foreach ($accountancy_codes_model->accountancy_codes as $mode_key => $fields) {
698 foreach ($fields as $field_key => $value) {
699 $accountancy_codes->accountancy_codes[$mode_key][$field_key] = $value;
700 }
701 }
702
703 $result = $accountancy_codes->updateAccountancyCodes($user, $this->id, 0, $notrigger);
704 if ($result < 0) {
705 $this->error = $accountancy_codes->error;
706 $this->errors = $accountancy_codes->errors;
707 $error++;
708 }
709 }
710 }
711 }
712
713 if ($error) {
714 $this->db->rollback();
715 return -1;
716 } else {
717 $this->db->commit();
718 return 1;
719 }
720 }
721
727 public function fetchDepreciationLines()
728 {
729 global $langs;
730 $langs->load('assets');
731 $this->depreciation_lines = array();
732
733 // Clean parameters
734 $this->id = $this->id > 0 ? $this->id : 0;
735
736 // Check parameters
737 $error = 0;
738 if (empty($this->id)) {
739 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
740 $error++;
741 }
742 if ($error) {
743 return -1;
744 }
745
746 // Old request with 'WITH'
747 /*
748 $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
749 $sql .= " SELECT DISTINCT fk_docdet";
750 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
751 $sql .= " WHERE doc_type = 'asset'";
752 $sql .= ")";
753 $sql .= "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht";
754 $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', 1, 0) . " AS bookkeeping";
755 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
756 $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
757 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
758 $sql .= " ORDER BY ad.depreciation_date ASC";
759 */
760
761 $sql = "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht";
762 $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', '1', '0') . " AS bookkeeping";
763 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
764 $sql .= " LEFT JOIN (SELECT DISTINCT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE doc_type = 'asset') AS iab ON iab.fk_docdet = ad.rowid";
765 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
766 $sql .= " ORDER BY ad.depreciation_date ASC";
767
768 $resql = $this->db->query($sql);
769 if (!$resql) {
770 $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror();
771 return -1;
772 }
773
774 while ($obj = $this->db->fetch_object($resql)) {
775 if (!isset($this->depreciation_lines[$obj->depreciation_mode])) {
776 $this->depreciation_lines[$obj->depreciation_mode] = array();
777 }
778 $this->depreciation_lines[$obj->depreciation_mode][] = array(
779 'id' => $obj->rowid,
780 'ref' => $obj->ref,
781 'depreciation_date' => $this->db->jdate($obj->depreciation_date),
782 'depreciation_ht' => $obj->depreciation_ht,
783 'cumulative_depreciation_ht' => $obj->cumulative_depreciation_ht,
784 'bookkeeping' => $obj->bookkeeping,
785 );
786 }
787
788 return 1;
789 }
790
797 {
798 global $langs;
799 $langs->load('assets');
800
801 // Clean parameters
802 $this->id = $this->id > 0 ? $this->id : 0;
803
804 // Check parameters
805 $error = 0;
806 if (empty($this->id)) {
807 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
808 $error++;
809 }
810 if ($error) {
811 return -1;
812 }
813
814 // Old request with 'WITH'
815 /*
816 $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
817 $sql .= " SELECT DISTINCT fk_docdet";
818 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
819 $sql .= " WHERE doc_type = 'asset'";
820 $sql .= ")";
821 $sql .= "SELECT COUNT(*) AS has_bookkeeping";
822 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
823 $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
824 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
825 $sql .= " AND iab.fk_docdet IS NOT NULL";
826 */
827
828 $sql = "SELECT COUNT(*) AS has_bookkeeping";
829 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
830 $sql .= " LEFT JOIN (SELECT DISTINCT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE doc_type = 'asset') AS iab ON iab.fk_docdet = ad.rowid";
831 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
832 $sql .= " AND iab.fk_docdet IS NOT NULL";
833
834 $resql = $this->db->query($sql);
835 if (!$resql) {
836 $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror();
837 return -1;
838 }
839
840 if ($obj = $this->db->fetch_object($resql)) {
841 return $obj->has_bookkeeping > 0 ? 1 : 0;
842 }
843
844 return 0;
845 }
846
859 public function addDepreciationLine($mode, $ref, $depreciation_date, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_debit, $accountancy_code_credit)
860 {
861 global $langs;
862 $langs->load('assets');
863
864 // Clean parameters
865 $this->id = $this->id > 0 ? $this->id : 0;
866 $mode = strtolower(trim($mode));
867 $ref = trim($ref);
868 $accountancy_code_debit = trim($accountancy_code_debit);
869 $accountancy_code_credit = trim($accountancy_code_credit);
870
871 // Check parameters
872 $error = 0;
873 if (empty($this->id)) {
874 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
875 $error++;
876 }
877 if ($error) {
878 return -1;
879 }
880
881 $sql = "INSERT INTO " . MAIN_DB_PREFIX . "asset_depreciation(fk_asset, depreciation_mode, ref, depreciation_date, depreciation_ht, cumulative_depreciation_ht, accountancy_code_debit, accountancy_code_credit)";
882 $sql .= " VALUES ( ";
883 $sql .= " " . (int) $this->id;
884 $sql .= ", '" . $this->db->escape($mode) . "'";
885 $sql .= ", '" . $this->db->escape($ref) . "'";
886 $sql .= ", '" . $this->db->idate($depreciation_date) . "'";
887 $sql .= ", " . (float) $depreciation_ht;
888 $sql .= ", " . (float) $cumulative_depreciation_ht;
889 $sql .= ", '" . $this->db->escape($accountancy_code_debit) . "'";
890 $sql .= ", '" . $this->db->escape($accountancy_code_credit) . "'";
891 $sql .= ")";
892
893 $resql = $this->db->query($sql);
894 if (!$resql) {
895 $this->errors[] = $langs->trans('AssetErrorAddDepreciationLine') . ': ' . $this->db->lasterror();
896 return -1;
897 }
898
899 return 1;
900 }
901
907 public function calculationDepreciation()
908 {
909 global $conf, $langs;
910 $langs->load('assets');
911
912 // Clean parameters
913 $this->id = $this->id > 0 ? $this->id : 0;
914
915 // Check parameters
916 $error = 0;
917 if (empty($this->id)) {
918 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
919 $error++;
920 }
921 if ($error) {
922 return -1;
923 }
924
925 if (! empty($this->not_depreciated)) {
926 return 1;
927 }
928
929 // Get depreciation options
930 //---------------------------
931 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php';
932 $options = new AssetDepreciationOptions($this->db);
933 $result = $options->fetchDeprecationOptions($this->id);
934 if ($result < 0) {
935 $this->error = $options->error;
936 $this->errors = $options->errors;
937 return -1;
938 }
939
940 // Get accountancy codes
941 //---------------------------
942 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php';
943 $accountancy_codes = new AssetAccountancyCodes($this->db);
944 $result = $accountancy_codes->fetchAccountancyCodes($this->id);
945 if ($result < 0) {
946 $this->error = $accountancy_codes->error;
947 $this->errors = $accountancy_codes->errors;
948 return -1;
949 }
950
951 $this->db->begin();
952
953 // Delete old lines
954 $modes = array();
955 foreach ($options->deprecation_options as $mode_key => $fields) {
956 $modes[$mode_key] = $this->db->escape($mode_key);
957 }
958 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation";
959 $sql .= " WHERE fk_asset = " . (int) $this->id;
960 $sql .= " AND depreciation_mode NOT IN ('" . $this->db->sanitize(implode("', '", $modes)) . "')";
961
962 $resql = $this->db->query($sql);
963 if (!$resql) {
964 $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror();
965 $error++;
966 }
967
968 if (!$error) {
969 // Get fiscal period
970 require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
971 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
972 // @FIXME getCurrentPeriodOfFiscalYear return the first period found. What if there is several ? And what if not closed ? And what if end date not yet defined.
973 $dates = getCurrentPeriodOfFiscalYear($this->db, $conf, $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition);
974 $init_fiscal_period_start = $dates['date_start'];
975 $init_fiscal_period_end = $dates['date_end'];
976 if (empty($init_fiscal_period_start) || empty($init_fiscal_period_end)) {
977 $pastmonthyear = $dates['pastmonthyear'];
978 $pastmonth = $dates['pastmonth'];
979 $init_fiscal_period_start = dol_get_first_day((int) $pastmonthyear, (int) $pastmonth, false);
980 $init_fiscal_period_end = dol_get_last_day((int) $pastmonthyear, (int) $pastmonth, false);
981 }
982
983 foreach ($options->deprecation_options as $mode_key => $fields) {
984 // Get last depreciation lines save in bookkeeping
985 //-----------------------------------------------------
986
987 // Old request with 'WITH'
988 /*
989 $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
990 $sql .= " SELECT fk_docdet";
991 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
992 $sql .= " WHERE doc_type = 'asset'";
993 $sql .= ")";
994 $sql .= "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht";
995 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
996 $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
997 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
998 $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
999 $sql .= " AND iab.fk_docdet IS NOT NULL";
1000 $sql .= " ORDER BY ad.depreciation_date DESC";
1001 $sql .= " LIMIT 1";
1002 */
1003
1004 $sql = "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht";
1005 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
1006 $sql .= " LEFT JOIN (SELECT DISTINCT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE doc_type = 'asset') AS iab ON iab.fk_docdet = ad.rowid";
1007 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
1008 $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
1009 $sql .= " AND iab.fk_docdet IS NOT NULL";
1010 $sql .= " ORDER BY ad.depreciation_date DESC";
1011 $sql .= " LIMIT 1";
1012
1013 $resql = $this->db->query($sql);
1014 if (!$resql) {
1015 $this->errors[] = $langs->trans('AssetErrorFetchMaxDepreciationDateForMode', $mode_key) . ': ' . $this->db->lasterror();
1016 $error++;
1017 break;
1018 }
1019 $last_depreciation_date = '';
1020 $last_cumulative_depreciation_ht = $this->reversal_amount_ht;
1021 if ($obj = $this->db->fetch_object($resql)) {
1022 $last_depreciation_date = $this->db->jdate($obj->depreciation_date);
1023 $last_cumulative_depreciation_ht = $obj->cumulative_depreciation_ht;
1024 }
1025
1026 // Set last cumulative depreciation
1027 $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table'];
1028 $sql .= " SET total_amount_last_depreciation_ht = " . (empty($last_cumulative_depreciation_ht) ? 0 : $last_cumulative_depreciation_ht);
1029 $sql .= " WHERE fk_asset = " . (int) $this->id;
1030 $resql = $this->db->query($sql);
1031 if (!$resql) {
1032 $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror();
1033 $error++;
1034 break;
1035 }
1036
1037 // Delete old lines
1038 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation";
1039 $sql .= " WHERE fk_asset = " . (int) $this->id;
1040 $sql .= " AND depreciation_mode = '" . $this->db->escape($mode_key) . "'";
1041 $sql .= " AND NOT EXISTS (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE doc_type = 'asset' AND fk_docdet = " . MAIN_DB_PREFIX . "asset_depreciation.rowid)";
1042 if ($last_depreciation_date !== "") {
1043 $sql .= " AND ref <> ''";
1044 }
1045 $resql = $this->db->query($sql);
1046 if (!$resql) {
1047 $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror();
1048 $error++;
1049 break;
1050 }
1051
1052 // Get depreciation period
1053 $depreciation_date_start = $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition;
1054 $depreciation_date_end = dol_time_plus_duree(dol_time_plus_duree((int) $depreciation_date_start, (float) $fields['duration'], $fields['duration_type'] == 1 ? 'm' : ($fields['duration_type'] == 2 ? 'd' : 'y')), -1, 'd');
1055 $depreciation_amount = $fields['amount_base_depreciation_ht'];
1056 if ($fields['duration_type'] == 2) { // Daily
1057 $fiscal_period_start = $depreciation_date_start;
1058 $fiscal_period_end = $depreciation_date_start;
1059 } elseif ($fields['duration_type'] == 1) { // Monthly
1060 $date_temp = dol_getdate((int) $depreciation_date_start);
1061 $fiscal_period_start = dol_get_first_day($date_temp['year'], $date_temp['mon'], false);
1062 $fiscal_period_end = dol_get_last_day($date_temp['year'], $date_temp['mon'], false);
1063 } else { // Annually
1064 $fiscal_period_start = $init_fiscal_period_start;
1065 $fiscal_period_end = $init_fiscal_period_end;
1066 }
1067 $cumulative_depreciation_ht = (float) $last_cumulative_depreciation_ht;
1068 $depreciation_period_amount = $depreciation_amount - (float) $this->reversal_amount_ht;
1069 $start_date = $depreciation_date_start;
1070 $disposal_date = isset($this->disposal_date) && $this->disposal_date !== "" ? $this->disposal_date : "";
1071 $finish_date = $disposal_date !== "" ? $disposal_date : $depreciation_date_end;
1072 $accountancy_code_depreciation_debit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_debit'];
1073 $accountancy_code_depreciation_debit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_debit_key] ?? '';
1074 $accountancy_code_depreciation_credit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_credit'];
1075 $accountancy_code_credit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_credit_key] ?? '';
1076
1077 // Reversal depreciation line
1078 //-----------------------------------------------------
1079 if ($last_depreciation_date === "" && ($depreciation_date_start < $fiscal_period_start || is_numeric($this->reversal_date))) {
1080 if (is_numeric($this->reversal_date)) {
1081 if ($this->reversal_date < $fiscal_period_start) {
1082 $this->errors[] = $langs->trans('AssetErrorReversalDateNotGreaterThanCurrentBeginFiscalDateForMode', $mode_key);
1083 $error++;
1084 break;
1085 }
1086
1087 if (empty($this->reversal_amount_ht)) {
1088 $this->errors[] = $langs->trans('AssetErrorReversalAmountNotProvidedForMode', $mode_key);
1089 $error++;
1090 break;
1091 }
1092
1093 $start_date = $this->reversal_date;
1094 $result = $this->addDepreciationLine($mode_key, '', $start_date, (float) $this->reversal_amount_ht, (float) $this->reversal_amount_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit);
1095 if ($result < 0) {
1096 $error++;
1097 break;
1098 }
1099 } else {
1100 $this->errors[] = $langs->trans('AssetErrorReversalDateNotProvidedForMode', $mode_key);
1101 $error++;
1102 break;
1103 }
1104 }
1105
1106 // futures depreciation lines
1107 //-----------------------------------------------------
1108 $nb_days_in_year = getDolGlobalInt('ASSET_DEPRECIATION_DURATION_PER_YEAR', 360);
1109 $nb_days_in_month = getDolGlobalInt('ASSET_DEPRECIATION_DURATION_PER_MONTH', 30);
1110 $period_amount = (float) ($fields['duration'] > 0 ? price2num($depreciation_period_amount / $fields['duration'], 'MT') : 0);
1111 $first_period_found = false;
1112 // TODO fix declaration of $begin_period
1113 $first_period_date = isset($begin_period) && $begin_period > $fiscal_period_start ? $begin_period : $fiscal_period_start;
1114
1115 $ref_date_format = "%Y" . ($fields['duration_type'] == 1 || $fields['duration_type'] == 2 ? '-%m' : '') . ($fields['duration_type'] == 2 ? '-%d' : '');
1116
1117 // Loop security
1118 $idx_loop = 0;
1119 $max_loop = $fields['duration'] + 2;
1120 do {
1121 // Loop security
1122 $idx_loop++;
1123 if ($idx_loop > $max_loop) {
1124 break;
1125 }
1126
1127 if ($last_depreciation_date < $fiscal_period_end && ($first_period_date <= $start_date || $first_period_found)) {
1128 // Disposal not depreciated
1129 if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end && empty($this->disposal_depreciated)) {
1130 break;
1131 }
1132
1133 $first_period_found = true;
1134
1135 $period_begin = dol_print_date($fiscal_period_start, $ref_date_format);
1136 $period_end = dol_print_date($fiscal_period_end, $ref_date_format);
1137 $ref = $period_begin . ($period_begin != $period_end ? ' - ' . $period_end : '');
1138 if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end) {
1139 $ref .= ' - ' . $langs->transnoentitiesnoconv('AssetDisposal');
1140 }
1141
1142 $begin_date = $fiscal_period_start < $start_date && $start_date <= $fiscal_period_end ? $start_date : $fiscal_period_start;
1143 $end_date = $fiscal_period_start < $finish_date && $finish_date <= $fiscal_period_end ? $finish_date : $fiscal_period_end;
1144 if ($fields['duration_type'] == 2) { // Daily
1145 $depreciation_ht = $period_amount;
1146 } elseif ($fields['duration_type'] == 1) { // Monthly
1147 $nb_days = min($nb_days_in_month, num_between_day($begin_date, $end_date, 1));
1148 if ($nb_days >= 28) {
1149 $date_temp = dol_getdate($begin_date);
1150 if ($date_temp['mon'] == 2) {
1151 $nb_days = 30;
1152 }
1153 }
1154 $depreciation_ht = (float) price2num($period_amount * $nb_days / $nb_days_in_month, 'MT');
1155 } else { // Annually, taking care for adjustments to shortened or extended periods (e.g., fiscal years of 9 or 15 months)
1156 $nb_days_real = num_between_day($begin_date, $end_date, 1);
1157 if (($nb_days_real > 366) || (num_between_day($fiscal_period_start, $fiscal_period_end, 1) < $nb_days_in_year)) { // FY Period changed
1158 $nb_days = $nb_days_real;
1159 } else {
1160 $nb_days = min($nb_days_in_year, $nb_days_real);
1161 }
1162 $depreciation_ht = (float) price2num($period_amount * $nb_days / $nb_days_in_year, 'MT');
1163 }
1164 if (getDolGlobalInt('ASSET_ROUND_INTEGER_NUMBER_UPWARDS') == 1) {
1165 if ($idx_loop < $max_loop) { // avoid last depreciation value
1166 $depreciation_ht = ceil($depreciation_ht);
1167 }
1168 }
1169
1170 if ($fiscal_period_start <= $depreciation_date_end && $depreciation_date_end <= $fiscal_period_end) { // last period
1171 $depreciation_ht = (float) price2num($depreciation_amount - (float) $cumulative_depreciation_ht, 'MT');
1172 $cumulative_depreciation_ht = $depreciation_amount;
1173 } else {
1174 $cumulative_depreciation_ht += $depreciation_ht;
1175 }
1176
1177 $result = $this->addDepreciationLine($mode_key, $ref, $fiscal_period_end, $depreciation_ht, (float) $cumulative_depreciation_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit);
1178 if ($result < 0) {
1179 $error++;
1180 break;
1181 }
1182 }
1183
1184 // Next fiscal period (+1 day/month/year)
1185 $fiscal_period_start = dol_time_plus_duree($fiscal_period_end, 1, 'd');
1186
1187 if ($fields['duration_type'] == 0) { // Annually - use fiscal year-end
1188 // Search for the NEXT fiscal year
1189 $next_fy = getNextFiscalYear($this->db, $fiscal_period_end, 'gmt');
1190
1191 if ($next_fy !== null) {
1192 // Exercise found in database
1193 $fiscal_period_start = $next_fy['date_start'];
1194 $fiscal_period_end = $next_fy['date_end'];
1195 } else {
1196 // If there is no subsequent fiscal year in the database, a one-year fiscal year is automatically generated.
1197 // based on the structure of the current fiscal year
1198 $current_fy_start_parts = dol_getdate($fiscal_period_start);
1199
1200 // Calculate the end: 1 year minus 1 day from the start
1201 $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'y'), -1, 'd');
1202
1203 // If the amortization end date is exceeded, there is no need to continue after that.
1204 // The loop will end naturally with the while condition.
1205 }
1206 } elseif ($fields['duration_type'] == 1) { // Monthly
1207 $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'm'), -1, 'd');
1208 } else { // Daily
1209 $fiscal_period_end = $fiscal_period_start;
1210 }
1211 $last_period_date = $disposal_date !== "" && $disposal_date < $depreciation_date_end ? $disposal_date : $depreciation_date_end;
1212 } while ($fiscal_period_start < $last_period_date);
1213
1214 if ($error) {
1215 break;
1216 }
1217 }
1218 }
1219
1220 if ($error) {
1221 $this->db->rollback();
1222 return -1;
1223 } else {
1224 $this->db->commit();
1225 return 1;
1226 }
1227 }
1228
1235 public function setLastCumulativeDepreciation($asset_depreciation_id)
1236 {
1237 global $langs;
1238 $langs->load('assets');
1239
1240 // Clean parameters
1241 $asset_depreciation_id = $asset_depreciation_id > 0 ? $asset_depreciation_id : 0;
1242
1243 // Check parameters
1244 $error = 0;
1245 if (empty($asset_depreciation_id)) {
1246 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetDepreciation") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
1247 $error++;
1248 }
1249 if ($error) {
1250 return -1;
1251 }
1252
1253 $this->db->begin();
1254
1255 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php';
1256 $options = new AssetDepreciationOptions($this->db);
1257
1258 // Get last depreciation lines save in bookkeeping
1259 //-----------------------------------------------------
1260 $sql = "SELECT fk_asset, depreciation_mode, cumulative_depreciation_ht";
1261 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation";
1262 $sql .= " WHERE rowid = " . (int) $asset_depreciation_id;
1263 $resql = $this->db->query($sql);
1264 if (!$resql) {
1265 $this->errors[] = $langs->trans('AssetErrorFetchCumulativeDepreciation') . ': ' . $this->db->lasterror();
1266 $error++;
1267 } else {
1268 if ($obj = $this->db->fetch_object($resql)) {
1269 $mode_key = $obj->depreciation_mode;
1270 if (!empty($options->deprecation_options_fields[$mode_key])) {
1271 $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table'];
1272 $sql .= " SET total_amount_last_depreciation_ht = " . $obj->cumulative_depreciation_ht;
1273 $sql .= " WHERE fk_asset = " . (int) $obj->fk_asset;
1274 $resql = $this->db->query($sql);
1275 if (!$resql) {
1276 $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror();
1277 $error++;
1278 }
1279 }
1280 }
1281 }
1282
1283 if ($error) {
1284 $this->db->rollback();
1285 return -1;
1286 } else {
1287 $this->db->commit();
1288 return 1;
1289 }
1290 }
1291
1300 public function dispose($user, $disposal_invoice_id, $notrigger = 0)
1301 {
1302 global $conf, $langs;
1303
1304 // Protection
1305 if ($this->status == self::STATUS_DISPOSED) {
1306 return 0;
1307 }
1308
1309 $this->db->begin();
1310
1311 $required_fields = array('disposal_date', 'disposal_date', 'fk_disposal_type');
1312 foreach ($required_fields as $field) {
1313 $this->fields[$field]['notnull'] = 1;
1314 }
1315 $result = $this->update($user, 1);
1316 foreach ($required_fields as $field) {
1317 $this->fields[$field]['notnull'] = 0;
1318 }
1319 if ($result > 0) {
1320 if ($disposal_invoice_id > 0) {
1321 $this->add_object_linked('facture', $disposal_invoice_id);
1322 }
1323 $result = $this->setStatusCommon($user, self::STATUS_DISPOSED, $notrigger, 'ASSET_DISPOSED');
1324 }
1325 if ($result > 0) {
1326 $result = $this->calculationDepreciation();
1327 }
1328
1329 if ($result < 0) {
1330 $this->db->rollback();
1331 } else {
1332 $this->db->commit();
1333 }
1334
1335 // Define output language
1336 if ($result > 0 && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1337 if (method_exists($this, 'generateDocument')) {
1338 global $hidedetails, $hidedesc, $hideref;
1339 $outputlangs = $langs;
1340 $newlang = '';
1341 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1342 $newlang = GETPOST('lang_id', 'aZ09');
1343 }
1344 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1345 $newlang = $this->thirdparty->default_lang;
1346 }
1347 if (!empty($newlang)) {
1348 $outputlangs = new Translate("", $conf);
1349 $outputlangs->setDefaultLang($newlang);
1350 }
1351 $model = $this->model_pdf;
1352 $ret = $this->fetch($this->id); // Reload to get new records
1353
1354 $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1355 }
1356 }
1357
1358 return $result;
1359 }
1360
1368 public function reopen($user, $notrigger = 0)
1369 {
1370 global $conf, $langs;
1371
1372 // Protection
1373 if ($this->status != self::STATUS_DISPOSED) {
1374 return 0;
1375 }
1376
1377
1378 $this->db->begin();
1379
1380 $this->disposal_date = null;
1381 $this->disposal_amount_ht = null;
1382 $this->fk_disposal_type = null;
1383 $this->disposal_depreciated = 0;
1384 $this->disposal_subject_to_vat = 0;
1385 $result = $this->update($user, 1);
1386 if ($result > 0) {
1387 $this->deleteObjectLinked(null, 'facture');
1388 $result = $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'ASSET_REOPEN');
1389 }
1390 if ($result > 0) {
1391 $result = $this->calculationDepreciation();
1392 }
1393
1394 if ($result < 0) {
1395 $this->db->rollback();
1396 } else {
1397 $this->db->commit();
1398 }
1399
1400 // Define output language
1401 if ($result > 0 && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1402 if (method_exists($this, 'generateDocument')) {
1403 global $hidedetails, $hidedesc, $hideref;
1404 $outputlangs = $langs;
1405 $newlang = '';
1406 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1407 $newlang = GETPOST('lang_id', 'aZ09');
1408 }
1409 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1410 $newlang = $this->thirdparty->default_lang;
1411 }
1412 if (!empty($newlang)) {
1413 $outputlangs = new Translate("", $conf);
1414 $outputlangs->setDefaultLang($newlang);
1415 }
1416 $model = $this->model_pdf;
1417 $ret = $this->fetch($this->id); // Reload to get new records
1418
1419 $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1420 }
1421 }
1422
1423 return $result;
1424 }
1425
1437 public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1438 {
1439 global $db, $conf, $langs, $hookmanager;
1440 global $dolibarr_main_authentication, $dolibarr_main_demo;
1441 global $menumanager;
1442
1443 if (!empty($conf->dol_no_mouse_hover)) {
1444 $notooltip = 1; // Force disable tooltips
1445 }
1446
1447 $result = '';
1448
1449 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Asset").'</u>';
1450 if (isset($this->status)) {
1451 $label .= ' '.$this->getLibStatut(5);
1452 }
1453 $label .= '<br>';
1454 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
1455
1456 $url = dol_buildpath('/asset/card.php', 1).'?id='.$this->id;
1457
1458 if ($option != 'nolink') {
1459 // Add param to save lastsearch_values or not
1460 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1461 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1462 $add_save_lastsearch_values = 1;
1463 }
1464 if ($add_save_lastsearch_values) {
1465 $url .= '&save_lastsearch_values=1';
1466 }
1467 }
1468
1469 $linkclose = '';
1470 if (empty($notooltip)) {
1471 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1472 $label = $langs->trans("ShowAsset");
1473 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1474 }
1475 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
1476 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1477 } else {
1478 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1479 }
1480
1481 if ($option == 'nolink') {
1482 $linkstart = '<span';
1483 } else {
1484 $linkstart = '<a href="'.$url.'"';
1485 }
1486 $linkstart .= $linkclose.'>';
1487 if ($option == 'nolink') {
1488 $linkend = '</span>';
1489 } else {
1490 $linkend = '</a>';
1491 }
1492
1493 $result .= $linkstart;
1494
1495 if (empty($this->showphoto_on_popup)) {
1496 if ($withpicto) {
1497 $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);
1498 }
1499 } else {
1500 if ($withpicto) {
1501 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1502
1503 list($class, $module) = explode('@', $this->picto);
1504 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
1505 $filearray = dol_dir_list($upload_dir, "files");
1506 $filename = $filearray[0]['name'];
1507 if (!empty($filename)) {
1508 $pospoint = strpos($filearray[0]['name'], '.');
1509
1510 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
1511 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
1512 $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo'.$module.'" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div></div>';
1513 } else {
1514 $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div>';
1515 }
1516
1517 $result .= '</div>';
1518 } else {
1519 $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);
1520 }
1521 }
1522 }
1523
1524 if ($withpicto != 2) {
1525 $name = $this->ref;
1526 if ($option == 'label') {
1527 $name = $this->label;
1528 } elseif ($option == 'with_label') {
1529 $name .= ' - ' . $this->label;
1530 }
1531 $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name);
1532 }
1533
1534 $result .= $linkend;
1535 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1536
1537 global $action;
1538 $hookmanager->initHooks(array($this->element . 'dao'));
1539 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1540 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1541 if ($reshook > 0) {
1542 $result = $hookmanager->resPrint;
1543 } else {
1544 $result .= $hookmanager->resPrint;
1545 }
1546 return $result;
1547 }
1548
1555 public function getLabelStatus($mode = 0)
1556 {
1557 return $this->LibStatut($this->status, $mode);
1558 }
1559
1566 public function getLibStatut($mode = 0)
1567 {
1568 return $this->LibStatut($this->status, $mode);
1569 }
1570
1571 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1579 public function LibStatut($status, $mode = 0)
1580 {
1581 // phpcs:enable
1582 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1583 global $langs;
1584 //$langs->load("assets");
1585 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInDraft');
1586 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('AssetInProgress');
1587 $this->labelStatus[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed');
1588 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInDraft');
1589 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('AssetInProgress');
1590 $this->labelStatusShort[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed');
1591 }
1592
1593 $statusType = 'status'.$status;
1594 if ($status == self::STATUS_VALIDATED) {
1595 $statusType = 'status4';
1596 }
1597 if ($status == self::STATUS_DISPOSED) {
1598 $statusType = 'status6';
1599 }
1600
1601 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
1602 }
1603
1610 public function info($id)
1611 {
1612 $sql = "SELECT rowid, date_creation as datec, tms as datem, date_valid as datev,";
1613 $sql .= " fk_user_creat, fk_user_modif, fk_user_valid";
1614 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
1615 $sql .= " WHERE t.rowid = ".((int) $id);
1616
1617 $result = $this->db->query($sql);
1618 if ($result) {
1619 if ($this->db->num_rows($result)) {
1620 $obj = $this->db->fetch_object($result);
1621 $this->id = $obj->rowid;
1622
1623 $this->user_creation_id = $obj->fk_user_creat;
1624 $this->user_modification_id = $obj->fk_user_modif;
1625 $this->user_validation_id = $obj->fk_user_valid;
1626 $this->date_creation = $this->db->jdate($obj->datec);
1627 $this->date_modification = $this->db->jdate($obj->datem);
1628 $this->date_validation = $this->db->jdate($obj->datev);
1629 }
1630
1631 $this->db->free($result);
1632 } else {
1633 dol_print_error($this->db);
1634 }
1635 }
1636
1643 public function initAsSpecimen()
1644 {
1645 // Set here init that are not commonf fields
1646 // $this->property1 = ...
1647 // $this->property2 = ...
1648
1649 return $this->initAsSpecimenCommon();
1650 }
1651
1657 public function getNextNumRef()
1658 {
1659 global $langs, $conf;
1660 $langs->load("assets");
1661
1662 if (!getDolGlobalString('ASSET_ASSET_ADDON')) {
1663 $conf->global->ASSET_ASSET_ADDON = 'mod_asset_standard';
1664 }
1665
1666 if (getDolGlobalString('ASSET_ASSET_ADDON')) {
1667 $mybool = false;
1668
1669 $file = getDolGlobalString('ASSET_ASSET_ADDON') . ".php";
1670 $classname = getDolGlobalString('ASSET_ASSET_ADDON');
1671
1672 // Include file with class
1673 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1674 foreach ($dirmodels as $reldir) {
1675 $dir = dol_buildpath($reldir."core/modules/asset/");
1676
1677 // Load file with numbering class (if found)
1678 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1679 }
1680
1681 if (!$mybool) {
1682 dol_print_error(null, "Failed to include file ".$file);
1683 return '';
1684 }
1685
1686 if (class_exists($classname)) {
1687 $obj = new $classname();
1688
1689 '@phan-var-force ModeleNumRefAsset $obj';
1690
1691 $numref = $obj->getNextValue($this);
1692
1693 if ($numref != '' && $numref != '-1') {
1694 return $numref;
1695 } else {
1696 $this->error = $obj->error;
1697 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1698 return "";
1699 }
1700 } else {
1701 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1702 return "";
1703 }
1704 } else {
1705 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1706 return "";
1707 }
1708 }
1709
1717 public function validate($user, $notrigger = 0)
1718 {
1719 global $conf;
1720
1721 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1722
1723 $error = 0;
1724
1725 // Protection
1726 if ($this->status == self::STATUS_VALIDATED) {
1727 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
1728 return 0;
1729 }
1730
1731 $now = dol_now();
1732
1733 $this->db->begin();
1734
1735 // Define new ref
1736 if (/* !$error && */ (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
1737 $num = $this->getNextNumRef();
1738 } else {
1739 $num = $this->ref;
1740 }
1741 $this->newref = dol_sanitizeFileName($num);
1742
1743 // Validate
1744 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1745 $sql .= " SET ref = '".$this->db->escape($num)."',";
1746 $sql .= " status = ".self::STATUS_VALIDATED.",";
1747 $sql .= " date_valid='".$this->db->idate($now)."',";
1748 $sql .= " fk_user_valid = ".((int) $user->id);
1749 $sql .= " WHERE rowid = ".((int) $this->id);
1750
1751 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
1752 $resql = $this->db->query($sql);
1753 if (!$resql) {
1754 dol_print_error($this->db);
1755 $this->error = $this->db->lasterror();
1756 $error++;
1757 }
1758
1759 if (!$error && !$notrigger) {
1760 // Call trigger
1761 $result = $this->call_trigger('ASSET_VALIDATE', $user);
1762 if ($result < 0) {
1763 $error++;
1764 }
1765 // End call triggers
1766 }
1767
1768 if (!$error) {
1769 $this->oldref = $this->ref;
1770
1771 // Rename directory if dir was a temporary ref
1772 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
1773 // Now we rename also files into index
1774 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'asset/".$this->db->escape($this->newref)."'";
1775 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'bom/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1776 $resql = $this->db->query($sql);
1777 if (!$resql) {
1778 $error++;
1779 $this->error = $this->db->lasterror();
1780 }
1781 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'asset/".$this->db->escape($this->newref)."'";
1782 $sql .= " WHERE filepath = 'asset/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1783 $resql = $this->db->query($sql);
1784 if (!$resql) {
1785 $error++;
1786 $this->error = $this->db->lasterror();
1787 }
1788
1789 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
1790 $oldref = dol_sanitizeFileName($this->ref);
1791 $newref = dol_sanitizeFileName($num);
1792 $dirsource = $conf->asset->dir_output.'/'.$oldref;
1793 $dirdest = $conf->asset->dir_output.'/'.$newref;
1794 if (!$error && file_exists($dirsource)) {
1795 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
1796
1797 if (@rename($dirsource, $dirdest)) {
1798 dol_syslog("Rename ok");
1799 // Rename docs starting with $oldref with $newref
1800 $listoffiles = dol_dir_list($conf->asset->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
1801 foreach ($listoffiles as $fileentry) {
1802 $dirsource = $fileentry['name'];
1803 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
1804 $dirsource = $fileentry['path'].'/'.$dirsource;
1805 $dirdest = $fileentry['path'].'/'.$dirdest;
1806 @rename($dirsource, $dirdest);
1807 }
1808 }
1809 }
1810 }
1811 }
1812
1813 // Set new ref and current status
1814 if (!$error) {
1815 $this->ref = $num;
1816 $this->status = self::STATUS_VALIDATED;
1817 }
1818
1819 if (!$error) {
1820 $this->db->commit();
1821 return 1;
1822 } else {
1823 $this->db->rollback();
1824 return -1;
1825 }
1826 }
1827
1835 public function setDraft($user, $notrigger = 0)
1836 {
1837 // Protection
1838 if ($this->status <= self::STATUS_DRAFT) {
1839 return 0;
1840 }
1841
1842 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'ASSET_UNVALIDATE');
1843 }
1844}
getCurrentPeriodOfFiscalYear($db, $conf, $from_time=null, $gm='tzserver', $withenddateonly=1)
Get current period of fiscal year?
getNextFiscalYear($db, $after_date, $gm='tzserver')
Get next fiscal year period after a given date.
$object ref
Definition info.php:90
Class for AssetAccountancyCodes.
Class for AssetDepreciationOptions.
Class for Asset.
getNomUrl($withpicto=0, $option='', $maxlen=0, $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
hasDepreciationLinesInBookkeeping()
If has depreciation lines in bookkeeping.
setDraft($user, $notrigger=0)
Set draft status.
dispose($user, $disposal_invoice_id, $notrigger=0)
Set dispose status.
validate($user, $notrigger=0)
Validate asset.
createFromClone(User $user, $fromid)
Clone an object into another one.
calculationDepreciation()
Calculation depreciation lines (reversal and future) for each mode.
__construct(DoliDB $db)
Constructor.
create(User $user, $notrigger=0)
Create object into database.
info($id)
Load the info information in the object.
getLabelStatus($mode=0)
Return the label of the status.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
fetch($id, $ref=null)
Load object in memory from the database.
LibStatut($status, $mode=0)
Return the status.
reopen($user, $notrigger=0)
Set back to validated status if disposed status.
getLibStatut($mode=0)
Return the label of the status.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
addDepreciationLine($mode, $ref, $depreciation_date, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_debit, $accountancy_code_credit)
Add depreciation line for a mode.
fetchDepreciationLines()
Fetch depreciation lines for each mode in $this->depreciation_lines (sort by depreciation date)
setLastCumulativeDepreciation($asset_depreciation_id)
Set last cumulative depreciation for each mode.
update(User $user, $notrigger=0)
Update object into database.
setDataFromAssetModel(User $user, $notrigger=0)
Set asset model.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
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=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class to manage translations.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:600
num_between_day($timestampStart, $timestampEnd, $lastday=0)
Function to return number of days between two dates (date must be UTC date !) Example: 2012-01-01 201...
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:125
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:619
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
global $dolibarr_main_demo
Definition index.php:57