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-2025 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 && (
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 ) {
572 $result = $this->calculationDepreciation();
573 }
574
575 if ($result < 0) {
576 $this->db->rollback();
577 } else {
578 $this->db->commit();
579 }
580
581 return $result;
582 }
583
591 public function delete(User $user, $notrigger = 0)
592 {
593 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_codes_economic WHERE fk_asset = '.((int) $this->id);
594 $this->db->query($sql);
595
596 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_codes_fiscal WHERE fk_asset = '.((int) $this->id);
597 $this->db->query($sql);
598
599 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_options_fiscal WHERE fk_asset = '.((int) $this->id);
600 $this->db->query($sql);
601
602 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation_options_economic WHERE fk_asset = '.((int) $this->id);
603 $this->db->query($sql);
604
605 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'asset_depreciation WHERE fk_asset = '.((int) $this->id);
606 $this->db->query($sql);
607
608 return $this->deleteCommon($user, $notrigger);
609 //return $this->deleteCommon($user, $notrigger, 1);
610 }
611
619 public function setDataFromAssetModel(User $user, $notrigger = 0)
620 {
621 global $langs;
622 $langs->load('assets');
623
624 // Clean parameters
625 $this->id = $this->id > 0 ? $this->id : 0;
626 $this->fk_asset_model = $this->fk_asset_model > 0 ? $this->fk_asset_model : 0;
627
628 // Check parameters
629 $error = 0;
630 if (empty($this->id)) {
631 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
632 $error++;
633 }
634 if (empty($this->fk_asset_model)) {
635 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetModel") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
636 $error++;
637 }
638 if ($error) {
639 return -1;
640 }
641
642 $this->db->begin();
643
644 // Get depreciation options
645 //---------------------------
646 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php';
647 $options_model = new AssetDepreciationOptions($this->db);
648 $result = $options_model->fetchDeprecationOptions(0, $this->fk_asset_model);
649 if ($result < 0) {
650 $this->error = $options_model->error;
651 $this->errors = $options_model->errors;
652 $error++;
653 } elseif ($result > 0) {
654 $options = new AssetDepreciationOptions($this->db);
655 $result = $options->fetchDeprecationOptions($this->id);
656 if ($result < 0) {
657 $this->error = $options->error;
658 $this->errors = $options->errors;
659 $error++;
660 }
661
662 if (!$error) {
663 foreach ($options_model->deprecation_options as $mode_key => $fields) {
664 foreach ($fields as $field_key => $value) {
665 $options->deprecation_options[$mode_key][$field_key] = $value;
666 }
667 }
668
669 $result = $options->updateDeprecationOptions($user, $this->id, 0, $notrigger);
670 if ($result < 0) {
671 $this->error = $options->error;
672 $this->errors = $options->errors;
673 $error++;
674 }
675 }
676 }
677
678 // Get accountancy codes
679 //---------------------------
680 if (!$error) {
681 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php';
682 $accountancy_codes_model = new AssetAccountancyCodes($this->db);
683 $result = $accountancy_codes_model->fetchAccountancyCodes(0, $this->fk_asset_model);
684 if ($result < 0) {
685 $this->error = $accountancy_codes_model->error;
686 $this->errors = $accountancy_codes_model->errors;
687 $error++;
688 } elseif ($result > 0) {
689 $accountancy_codes = new AssetAccountancyCodes($this->db);
690 $result = $accountancy_codes->fetchAccountancyCodes($this->id);
691 if ($result < 0) {
692 $this->error = $accountancy_codes->error;
693 $this->errors = $accountancy_codes->errors;
694 $error++;
695 }
696
697 if (!$error) {
698 foreach ($accountancy_codes_model->accountancy_codes as $mode_key => $fields) {
699 foreach ($fields as $field_key => $value) {
700 $accountancy_codes->accountancy_codes[$mode_key][$field_key] = $value;
701 }
702 }
703
704 $result = $accountancy_codes->updateAccountancyCodes($user, $this->id, 0, $notrigger);
705 if ($result < 0) {
706 $this->error = $accountancy_codes->error;
707 $this->errors = $accountancy_codes->errors;
708 $error++;
709 }
710 }
711 }
712 }
713
714 if ($error) {
715 $this->db->rollback();
716 return -1;
717 } else {
718 $this->db->commit();
719 return 1;
720 }
721 }
722
728 public function fetchDepreciationLines()
729 {
730 global $langs;
731 $langs->load('assets');
732 $this->depreciation_lines = array();
733
734 // Clean parameters
735 $this->id = $this->id > 0 ? $this->id : 0;
736
737 // Check parameters
738 $error = 0;
739 if (empty($this->id)) {
740 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
741 $error++;
742 }
743 if ($error) {
744 return -1;
745 }
746
747 // Old request with 'WITH'
748 /*
749 $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
750 $sql .= " SELECT DISTINCT fk_docdet";
751 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
752 $sql .= " WHERE doc_type = 'asset'";
753 $sql .= ")";
754 $sql .= "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht";
755 $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', 1, 0) . " AS bookkeeping";
756 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
757 $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
758 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
759 $sql .= " ORDER BY ad.depreciation_date ASC";
760 */
761
762 $sql = "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht";
763 $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', '1', '0') . " AS bookkeeping";
764 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
765 $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";
766 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
767 $sql .= " ORDER BY ad.depreciation_date ASC";
768
769 $resql = $this->db->query($sql);
770 if (!$resql) {
771 $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror();
772 return -1;
773 }
774
775 while ($obj = $this->db->fetch_object($resql)) {
776 if (!isset($this->depreciation_lines[$obj->depreciation_mode])) {
777 $this->depreciation_lines[$obj->depreciation_mode] = array();
778 }
779 $this->depreciation_lines[$obj->depreciation_mode][] = array(
780 'id' => $obj->rowid,
781 'ref' => $obj->ref,
782 'depreciation_date' => $this->db->jdate($obj->depreciation_date),
783 'depreciation_ht' => $obj->depreciation_ht,
784 'cumulative_depreciation_ht' => $obj->cumulative_depreciation_ht,
785 'bookkeeping' => $obj->bookkeeping,
786 );
787 }
788
789 return 1;
790 }
791
798 {
799 global $langs;
800 $langs->load('assets');
801
802 // Clean parameters
803 $this->id = $this->id > 0 ? $this->id : 0;
804
805 // Check parameters
806 $error = 0;
807 if (empty($this->id)) {
808 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
809 $error++;
810 }
811 if ($error) {
812 return -1;
813 }
814
815 // Old request with 'WITH'
816 /*
817 $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
818 $sql .= " SELECT DISTINCT fk_docdet";
819 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
820 $sql .= " WHERE doc_type = 'asset'";
821 $sql .= ")";
822 $sql .= "SELECT COUNT(*) AS has_bookkeeping";
823 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
824 $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
825 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
826 $sql .= " AND iab.fk_docdet IS NOT NULL";
827 */
828
829 $sql = "SELECT COUNT(*) AS has_bookkeeping";
830 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
831 $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";
832 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
833 $sql .= " AND iab.fk_docdet IS NOT NULL";
834
835 $resql = $this->db->query($sql);
836 if (!$resql) {
837 $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror();
838 return -1;
839 }
840
841 if ($obj = $this->db->fetch_object($resql)) {
842 return $obj->has_bookkeeping > 0 ? 1 : 0;
843 }
844
845 return 0;
846 }
847
860 public function addDepreciationLine($mode, $ref, $depreciation_date, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_debit, $accountancy_code_credit)
861 {
862 global $langs;
863 $langs->load('assets');
864
865 // Clean parameters
866 $this->id = $this->id > 0 ? $this->id : 0;
867 $mode = strtolower(trim($mode));
868 $ref = trim($ref);
869 $accountancy_code_debit = trim($accountancy_code_debit);
870 $accountancy_code_credit = trim($accountancy_code_credit);
871
872 // Check parameters
873 $error = 0;
874 if (empty($this->id)) {
875 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
876 $error++;
877 }
878 if ($error) {
879 return -1;
880 }
881
882 $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)";
883 $sql .= " VALUES ( ";
884 $sql .= " " . (int) $this->id;
885 $sql .= ", '" . $this->db->escape($mode) . "'";
886 $sql .= ", '" . $this->db->escape($ref) . "'";
887 $sql .= ", '" . $this->db->idate($depreciation_date) . "'";
888 $sql .= ", " . (float) $depreciation_ht;
889 $sql .= ", " . (float) $cumulative_depreciation_ht;
890 $sql .= ", '" . $this->db->escape($accountancy_code_debit) . "'";
891 $sql .= ", '" . $this->db->escape($accountancy_code_credit) . "'";
892 $sql .= ")";
893
894 $resql = $this->db->query($sql);
895 if (!$resql) {
896 $this->errors[] = $langs->trans('AssetErrorAddDepreciationLine') . ': ' . $this->db->lasterror();
897 return -1;
898 }
899
900 return 1;
901 }
902
908 public function calculationDepreciation()
909 {
910 global $conf, $langs;
911 $langs->load('assets');
912
913 // Clean parameters
914 $this->id = $this->id > 0 ? $this->id : 0;
915
916 // Check parameters
917 $error = 0;
918 if (empty($this->id)) {
919 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
920 $error++;
921 }
922 if ($error) {
923 return -1;
924 }
925
926 if (! empty($this->not_depreciated)) {
927 return 1;
928 }
929
930 // Get depreciation options
931 //---------------------------
932 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php';
933 $options = new AssetDepreciationOptions($this->db);
934 $result = $options->fetchDeprecationOptions($this->id);
935 if ($result < 0) {
936 $this->error = $options->error;
937 $this->errors = $options->errors;
938 return -1;
939 }
940
941 // Get accountancy codes
942 //---------------------------
943 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php';
944 $accountancy_codes = new AssetAccountancyCodes($this->db);
945 $result = $accountancy_codes->fetchAccountancyCodes($this->id);
946 if ($result < 0) {
947 $this->error = $accountancy_codes->error;
948 $this->errors = $accountancy_codes->errors;
949 return -1;
950 }
951
952 $this->db->begin();
953
954 // Delete old lines
955 $modes = array();
956 foreach ($options->deprecation_options as $mode_key => $fields) {
957 $modes[$mode_key] = $this->db->escape($mode_key);
958 }
959 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation";
960 $sql .= " WHERE fk_asset = " . (int) $this->id;
961 $sql .= " AND depreciation_mode NOT IN ('" . $this->db->sanitize(implode("', '", $modes)) . "')";
962
963 $resql = $this->db->query($sql);
964 if (!$resql) {
965 $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror();
966 $error++;
967 }
968
969 if (!$error) {
970 // Get fiscal period
971 require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
972 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
973 // @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.
974 $dates = getCurrentPeriodOfFiscalYear($this->db, $conf, $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition);
975 $init_fiscal_period_start = $dates['date_start'];
976 $init_fiscal_period_end = $dates['date_end'];
977 if (empty($init_fiscal_period_start) || empty($init_fiscal_period_end)) {
978 $pastmonthyear = $dates['pastmonthyear'];
979 $pastmonth = $dates['pastmonth'];
980 $init_fiscal_period_start = dol_get_first_day((int) $pastmonthyear, (int) $pastmonth, false);
981 $init_fiscal_period_end = dol_get_last_day((int) $pastmonthyear, (int) $pastmonth, false);
982 }
983
984 foreach ($options->deprecation_options as $mode_key => $fields) {
985 // Get last depreciation lines save in bookkeeping
986 //-----------------------------------------------------
987
988 // Old request with 'WITH'
989 /*
990 $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
991 $sql .= " SELECT fk_docdet";
992 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
993 $sql .= " WHERE doc_type = 'asset'";
994 $sql .= ")";
995 $sql .= "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht";
996 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
997 $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
998 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
999 $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
1000 $sql .= " AND iab.fk_docdet IS NOT NULL";
1001 $sql .= " ORDER BY ad.depreciation_date DESC";
1002 $sql .= " LIMIT 1";
1003 */
1004
1005 $sql = "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht";
1006 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
1007 $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";
1008 $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
1009 $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
1010 $sql .= " AND iab.fk_docdet IS NOT NULL";
1011 $sql .= " ORDER BY ad.depreciation_date DESC";
1012 $sql .= " LIMIT 1";
1013
1014 $resql = $this->db->query($sql);
1015 if (!$resql) {
1016 $this->errors[] = $langs->trans('AssetErrorFetchMaxDepreciationDateForMode', $mode_key) . ': ' . $this->db->lasterror();
1017 $error++;
1018 break;
1019 }
1020 $last_depreciation_date = '';
1021 $last_cumulative_depreciation_ht = $this->reversal_amount_ht;
1022 if ($obj = $this->db->fetch_object($resql)) {
1023 $last_depreciation_date = $this->db->jdate($obj->depreciation_date);
1024 $last_cumulative_depreciation_ht = $obj->cumulative_depreciation_ht;
1025 }
1026
1027 // Set last cumulative depreciation
1028 $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table'];
1029 $sql .= " SET total_amount_last_depreciation_ht = " . (empty($last_cumulative_depreciation_ht) ? 0 : $last_cumulative_depreciation_ht);
1030 $sql .= " WHERE fk_asset = " . (int) $this->id;
1031 $resql = $this->db->query($sql);
1032 if (!$resql) {
1033 $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror();
1034 $error++;
1035 break;
1036 }
1037
1038 // Delete old lines
1039 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation";
1040 $sql .= " WHERE fk_asset = " . (int) $this->id;
1041 $sql .= " AND depreciation_mode = '" . $this->db->escape($mode_key) . "'";
1042 $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)";
1043 if ($last_depreciation_date !== "") {
1044 $sql .= " AND ref <> ''";
1045 }
1046 $resql = $this->db->query($sql);
1047 if (!$resql) {
1048 $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror();
1049 $error++;
1050 break;
1051 }
1052
1053 // Get depreciation period
1054 $depreciation_date_start = $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition;
1055 $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');
1056 $depreciation_amount = $fields['amount_base_depreciation_ht'];
1057 if ($fields['duration_type'] == 2) { // Daily
1058 $fiscal_period_start = $depreciation_date_start;
1059 $fiscal_period_end = $depreciation_date_start;
1060 } elseif ($fields['duration_type'] == 1) { // Monthly
1061 $date_temp = dol_getdate((int) $depreciation_date_start);
1062 $fiscal_period_start = dol_get_first_day($date_temp['year'], $date_temp['mon'], false);
1063 $fiscal_period_end = dol_get_last_day($date_temp['year'], $date_temp['mon'], false);
1064 } else { // Annually
1065 $fiscal_period_start = $init_fiscal_period_start;
1066 $fiscal_period_end = $init_fiscal_period_end;
1067 }
1068 $cumulative_depreciation_ht = (float) $last_cumulative_depreciation_ht;
1069 $depreciation_period_amount = $depreciation_amount - (float) $this->reversal_amount_ht;
1070 $start_date = $depreciation_date_start;
1071 $disposal_date = isset($this->disposal_date) && $this->disposal_date !== "" ? $this->disposal_date : "";
1072 $finish_date = $disposal_date !== "" ? $disposal_date : $depreciation_date_end;
1073 $accountancy_code_depreciation_debit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_debit'];
1074 $accountancy_code_depreciation_debit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_debit_key];
1075 $accountancy_code_depreciation_credit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_credit'];
1076 $accountancy_code_credit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_credit_key];
1077
1078 // Reversal depreciation line
1079 //-----------------------------------------------------
1080 if ($last_depreciation_date === "" && ($depreciation_date_start < $fiscal_period_start || is_numeric($this->reversal_date))) {
1081 if (is_numeric($this->reversal_date)) {
1082 if ($this->reversal_date < $fiscal_period_start) {
1083 $this->errors[] = $langs->trans('AssetErrorReversalDateNotGreaterThanCurrentBeginFiscalDateForMode', $mode_key);
1084 $error++;
1085 break;
1086 }
1087
1088 if (empty($this->reversal_amount_ht)) {
1089 $this->errors[] = $langs->trans('AssetErrorReversalAmountNotProvidedForMode', $mode_key);
1090 $error++;
1091 break;
1092 }
1093
1094 $start_date = $this->reversal_date;
1095 $result = $this->addDepreciationLine($mode_key, '', $start_date, (float) $this->reversal_amount_ht, (float) $this->reversal_amount_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit);
1096 if ($result < 0) {
1097 $error++;
1098 break;
1099 }
1100 } else {
1101 $this->errors[] = $langs->trans('AssetErrorReversalDateNotProvidedForMode', $mode_key);
1102 $error++;
1103 break;
1104 }
1105 }
1106
1107 // futures depreciation lines
1108 //-----------------------------------------------------
1109 $nb_days_in_year = getDolGlobalInt('ASSET_DEPRECIATION_DURATION_PER_YEAR', 360);
1110 $nb_days_in_month = getDolGlobalInt('ASSET_DEPRECIATION_DURATION_PER_MONTH', 30);
1111 $period_amount = (float) ($fields['duration'] > 0 ? price2num($depreciation_period_amount / $fields['duration'], 'MT') : 0);
1112 $first_period_found = false;
1113 // TODO fix declaration of $begin_period
1114 $first_period_date = isset($begin_period) && $begin_period > $fiscal_period_start ? $begin_period : $fiscal_period_start;
1115
1116 $ref_date_format = "%Y" . ($fields['duration_type'] == 1 || $fields['duration_type'] == 2 ? '-%m' : '') . ($fields['duration_type'] == 2 ? '-%d' : '');
1117
1118 // Loop security
1119 $idx_loop = 0;
1120 $max_loop = $fields['duration'] + 2;
1121 do {
1122 // Loop security
1123 $idx_loop++;
1124 if ($idx_loop > $max_loop) {
1125 break;
1126 }
1127
1128 if ($last_depreciation_date < $fiscal_period_end && ($first_period_date <= $start_date || $first_period_found)) {
1129 // Disposal not depreciated
1130 if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end && empty($this->disposal_depreciated)) {
1131 break;
1132 }
1133
1134 $first_period_found = true;
1135
1136 $period_begin = dol_print_date($fiscal_period_start, $ref_date_format);
1137 $period_end = dol_print_date($fiscal_period_end, $ref_date_format);
1138 $ref = $period_begin . ($period_begin != $period_end ? ' - ' . $period_end : '');
1139 if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end) {
1140 $ref .= ' - ' . $langs->transnoentitiesnoconv('AssetDisposal');
1141 }
1142
1143 $begin_date = $fiscal_period_start < $start_date && $start_date <= $fiscal_period_end ? $start_date : $fiscal_period_start;
1144 $end_date = $fiscal_period_start < $finish_date && $finish_date <= $fiscal_period_end ? $finish_date : $fiscal_period_end;
1145 if ($fields['duration_type'] == 2) { // Daily
1146 $depreciation_ht = $period_amount;
1147 } elseif ($fields['duration_type'] == 1) { // Monthly
1148 $nb_days = min($nb_days_in_month, num_between_day($begin_date, $end_date, 1));
1149 if ($nb_days >= 28) {
1150 $date_temp = dol_getdate($begin_date);
1151 if ($date_temp['mon'] == 2) {
1152 $nb_days = 30;
1153 }
1154 }
1155 $depreciation_ht = (float) price2num($period_amount * $nb_days / $nb_days_in_month, 'MT');
1156 } else { // Annually, taking care for adjustments to shortened or extended periods (e.g., fiscal years of 9 or 15 months)
1157 $nb_days_real = num_between_day($begin_date, $end_date, 1);
1158 if (($nb_days_real > 366) || (num_between_day($fiscal_period_start, $fiscal_period_end, 1) < $nb_days_in_year)) { // FY Period changed
1159 $nb_days = $nb_days_real;
1160 } else {
1161 $nb_days = min($nb_days_in_year, $nb_days_real);
1162 }
1163 $depreciation_ht = (float) price2num($period_amount * $nb_days / $nb_days_in_year, 'MT');
1164 }
1165 if (getDolGlobalInt('ASSET_ROUND_INTEGER_NUMBER_UPWARDS') == 1) {
1166 if ($idx_loop < $max_loop) { // avoid last depreciation value
1167 $depreciation_ht = ceil($depreciation_ht);
1168 }
1169 }
1170
1171 if ($fiscal_period_start <= $depreciation_date_end && $depreciation_date_end <= $fiscal_period_end) { // last period
1172 $depreciation_ht = (float) price2num($depreciation_amount - (float) $cumulative_depreciation_ht, 'MT');
1173 $cumulative_depreciation_ht = $depreciation_amount;
1174 } else {
1175 $cumulative_depreciation_ht += $depreciation_ht;
1176 }
1177
1178 $result = $this->addDepreciationLine($mode_key, $ref, $fiscal_period_end, $depreciation_ht, (float) $cumulative_depreciation_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit);
1179 if ($result < 0) {
1180 $error++;
1181 break;
1182 }
1183 }
1184
1185 // Next fiscal period (+1 day/month/year)
1186 $fiscal_period_start = dol_time_plus_duree($fiscal_period_end, 1, 'd');
1187
1188 if ($fields['duration_type'] == 0) { // Annually - use fiscal year-end
1189 // Search for the NEXT fiscal year
1190 $next_fy = getNextFiscalYear($this->db, $fiscal_period_end, 'gmt');
1191
1192 if ($next_fy !== null) {
1193 // Exercise found in database
1194 $fiscal_period_start = $next_fy['date_start'];
1195 $fiscal_period_end = $next_fy['date_end'];
1196 } else {
1197 // If there is no subsequent fiscal year in the database, a one-year fiscal year is automatically generated.
1198 // based on the structure of the current fiscal year
1199 $current_fy_start_parts = dol_getdate($fiscal_period_start);
1200
1201 // Calculate the end: 1 year minus 1 day from the start
1202 $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'y'), -1, 'd');
1203
1204 // If the amortization end date is exceeded, there is no need to continue after that.
1205 // The loop will end naturally with the while condition.
1206 }
1207 } elseif ($fields['duration_type'] == 1) { // Monthly
1208 $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'm'), -1, 'd');
1209 } else { // Daily
1210 $fiscal_period_end = $fiscal_period_start;
1211 }
1212 $last_period_date = $disposal_date !== "" && $disposal_date < $depreciation_date_end ? $disposal_date : $depreciation_date_end;
1213 } while ($fiscal_period_start < $last_period_date);
1214
1215 if ($error) {
1216 break;
1217 }
1218 }
1219 }
1220
1221 if ($error) {
1222 $this->db->rollback();
1223 return -1;
1224 } else {
1225 $this->db->commit();
1226 return 1;
1227 }
1228 }
1229
1236 public function setLastCumulativeDepreciation($asset_depreciation_id)
1237 {
1238 global $langs;
1239 $langs->load('assets');
1240
1241 // Clean parameters
1242 $asset_depreciation_id = $asset_depreciation_id > 0 ? $asset_depreciation_id : 0;
1243
1244 // Check parameters
1245 $error = 0;
1246 if (empty($asset_depreciation_id)) {
1247 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetDepreciation") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
1248 $error++;
1249 }
1250 if ($error) {
1251 return -1;
1252 }
1253
1254 $this->db->begin();
1255
1256 require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php';
1257 $options = new AssetDepreciationOptions($this->db);
1258
1259 // Get last depreciation lines save in bookkeeping
1260 //-----------------------------------------------------
1261 $sql = "SELECT fk_asset, depreciation_mode, cumulative_depreciation_ht";
1262 $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation";
1263 $sql .= " WHERE rowid = " . (int) $asset_depreciation_id;
1264 $resql = $this->db->query($sql);
1265 if (!$resql) {
1266 $this->errors[] = $langs->trans('AssetErrorFetchCumulativeDepreciation') . ': ' . $this->db->lasterror();
1267 $error++;
1268 } else {
1269 if ($obj = $this->db->fetch_object($resql)) {
1270 $mode_key = $obj->depreciation_mode;
1271 if (!empty($options->deprecation_options_fields[$mode_key])) {
1272 $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table'];
1273 $sql .= " SET total_amount_last_depreciation_ht = " . $obj->cumulative_depreciation_ht;
1274 $sql .= " WHERE fk_asset = " . (int) $obj->fk_asset;
1275 $resql = $this->db->query($sql);
1276 if (!$resql) {
1277 $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror();
1278 $error++;
1279 }
1280 }
1281 }
1282 }
1283
1284 if ($error) {
1285 $this->db->rollback();
1286 return -1;
1287 } else {
1288 $this->db->commit();
1289 return 1;
1290 }
1291 }
1292
1301 public function dispose($user, $disposal_invoice_id, $notrigger = 0)
1302 {
1303 global $conf, $langs;
1304
1305 // Protection
1306 if ($this->status == self::STATUS_DISPOSED) {
1307 return 0;
1308 }
1309
1310 $this->db->begin();
1311
1312 $required_fields = array('disposal_date', 'disposal_date', 'fk_disposal_type');
1313 foreach ($required_fields as $field) {
1314 $this->fields[$field]['notnull'] = 1;
1315 }
1316 $result = $this->update($user, 1);
1317 foreach ($required_fields as $field) {
1318 $this->fields[$field]['notnull'] = 0;
1319 }
1320 if ($result > 0) {
1321 if ($disposal_invoice_id > 0) {
1322 $this->add_object_linked('facture', $disposal_invoice_id);
1323 }
1324 $result = $this->setStatusCommon($user, self::STATUS_DISPOSED, $notrigger, 'ASSET_DISPOSED');
1325 }
1326 if ($result > 0) {
1327 $result = $this->calculationDepreciation();
1328 }
1329
1330 if ($result < 0) {
1331 $this->db->rollback();
1332 } else {
1333 $this->db->commit();
1334 }
1335
1336 // Define output language
1337 if ($result > 0 && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1338 if (method_exists($this, 'generateDocument')) {
1339 global $hidedetails, $hidedesc, $hideref;
1340 $outputlangs = $langs;
1341 $newlang = '';
1342 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1343 $newlang = GETPOST('lang_id', 'aZ09');
1344 }
1345 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1346 $newlang = $this->thirdparty->default_lang;
1347 }
1348 if (!empty($newlang)) {
1349 $outputlangs = new Translate("", $conf);
1350 $outputlangs->setDefaultLang($newlang);
1351 }
1352 $model = $this->model_pdf;
1353 $ret = $this->fetch($this->id); // Reload to get new records
1354
1355 $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1356 }
1357 }
1358
1359 return $result;
1360 }
1361
1369 public function reopen($user, $notrigger = 0)
1370 {
1371 global $conf, $langs;
1372
1373 // Protection
1374 if ($this->status != self::STATUS_DISPOSED) {
1375 return 0;
1376 }
1377
1378
1379 $this->db->begin();
1380
1381 $this->disposal_date = null;
1382 $this->disposal_amount_ht = null;
1383 $this->fk_disposal_type = null;
1384 $this->disposal_depreciated = 0;
1385 $this->disposal_subject_to_vat = 0;
1386 $result = $this->update($user, 1);
1387 if ($result > 0) {
1388 $this->deleteObjectLinked(null, 'facture');
1389 $result = $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'ASSET_REOPEN');
1390 }
1391 if ($result > 0) {
1392 $result = $this->calculationDepreciation();
1393 }
1394
1395 if ($result < 0) {
1396 $this->db->rollback();
1397 } else {
1398 $this->db->commit();
1399 }
1400
1401 // Define output language
1402 if ($result > 0 && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1403 if (method_exists($this, 'generateDocument')) {
1404 global $hidedetails, $hidedesc, $hideref;
1405 $outputlangs = $langs;
1406 $newlang = '';
1407 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1408 $newlang = GETPOST('lang_id', 'aZ09');
1409 }
1410 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1411 $newlang = $this->thirdparty->default_lang;
1412 }
1413 if (!empty($newlang)) {
1414 $outputlangs = new Translate("", $conf);
1415 $outputlangs->setDefaultLang($newlang);
1416 }
1417 $model = $this->model_pdf;
1418 $ret = $this->fetch($this->id); // Reload to get new records
1419
1420 $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1421 }
1422 }
1423
1424 return $result;
1425 }
1426
1438 public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1439 {
1440 global $db, $conf, $langs, $hookmanager;
1441 global $dolibarr_main_authentication, $dolibarr_main_demo;
1442 global $menumanager;
1443
1444 if (!empty($conf->dol_no_mouse_hover)) {
1445 $notooltip = 1; // Force disable tooltips
1446 }
1447
1448 $result = '';
1449
1450 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Asset").'</u>';
1451 if (isset($this->status)) {
1452 $label .= ' '.$this->getLibStatut(5);
1453 }
1454 $label .= '<br>';
1455 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
1456
1457 $url = dol_buildpath('/asset/card.php', 1).'?id='.$this->id;
1458
1459 if ($option != 'nolink') {
1460 // Add param to save lastsearch_values or not
1461 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1462 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1463 $add_save_lastsearch_values = 1;
1464 }
1465 if ($add_save_lastsearch_values) {
1466 $url .= '&save_lastsearch_values=1';
1467 }
1468 }
1469
1470 $linkclose = '';
1471 if (empty($notooltip)) {
1472 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1473 $label = $langs->trans("ShowAsset");
1474 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1475 }
1476 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
1477 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1478 } else {
1479 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1480 }
1481
1482 if ($option == 'nolink') {
1483 $linkstart = '<span';
1484 } else {
1485 $linkstart = '<a href="'.$url.'"';
1486 }
1487 $linkstart .= $linkclose.'>';
1488 if ($option == 'nolink') {
1489 $linkend = '</span>';
1490 } else {
1491 $linkend = '</a>';
1492 }
1493
1494 $result .= $linkstart;
1495
1496 if (empty($this->showphoto_on_popup)) {
1497 if ($withpicto) {
1498 $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);
1499 }
1500 } else {
1501 if ($withpicto) {
1502 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1503
1504 list($class, $module) = explode('@', $this->picto);
1505 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
1506 $filearray = dol_dir_list($upload_dir, "files");
1507 $filename = $filearray[0]['name'];
1508 if (!empty($filename)) {
1509 $pospoint = strpos($filearray[0]['name'], '.');
1510
1511 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
1512 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
1513 $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>';
1514 } else {
1515 $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>';
1516 }
1517
1518 $result .= '</div>';
1519 } else {
1520 $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);
1521 }
1522 }
1523 }
1524
1525 if ($withpicto != 2) {
1526 $name = $this->ref;
1527 if ($option == 'label') {
1528 $name = $this->label;
1529 } elseif ($option == 'with_label') {
1530 $name .= ' - ' . $this->label;
1531 }
1532 $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name);
1533 }
1534
1535 $result .= $linkend;
1536 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1537
1538 global $action;
1539 $hookmanager->initHooks(array($this->element . 'dao'));
1540 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1541 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1542 if ($reshook > 0) {
1543 $result = $hookmanager->resPrint;
1544 } else {
1545 $result .= $hookmanager->resPrint;
1546 }
1547 return $result;
1548 }
1549
1556 public function getLabelStatus($mode = 0)
1557 {
1558 return $this->LibStatut($this->status, $mode);
1559 }
1560
1567 public function getLibStatut($mode = 0)
1568 {
1569 return $this->LibStatut($this->status, $mode);
1570 }
1571
1572 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1580 public function LibStatut($status, $mode = 0)
1581 {
1582 // phpcs:enable
1583 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1584 global $langs;
1585 //$langs->load("assets");
1586 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInDraft');
1587 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('AssetInProgress');
1588 $this->labelStatus[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed');
1589 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInDraft');
1590 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('AssetInProgress');
1591 $this->labelStatusShort[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed');
1592 }
1593
1594 $statusType = 'status'.$status;
1595 if ($status == self::STATUS_VALIDATED) {
1596 $statusType = 'status4';
1597 }
1598 if ($status == self::STATUS_DISPOSED) {
1599 $statusType = 'status6';
1600 }
1601
1602 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
1603 }
1604
1611 public function info($id)
1612 {
1613 $sql = "SELECT rowid, date_creation as datec, tms as datem, date_valid as datev,";
1614 $sql .= " fk_user_creat, fk_user_modif, fk_user_valid";
1615 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
1616 $sql .= " WHERE t.rowid = ".((int) $id);
1617
1618 $result = $this->db->query($sql);
1619 if ($result) {
1620 if ($this->db->num_rows($result)) {
1621 $obj = $this->db->fetch_object($result);
1622 $this->id = $obj->rowid;
1623
1624 $this->user_creation_id = $obj->fk_user_creat;
1625 $this->user_modification_id = $obj->fk_user_modif;
1626 $this->user_validation_id = $obj->fk_user_valid;
1627 $this->date_creation = $this->db->jdate($obj->datec);
1628 $this->date_modification = $this->db->jdate($obj->datem);
1629 $this->date_validation = $this->db->jdate($obj->datev);
1630 }
1631
1632 $this->db->free($result);
1633 } else {
1634 dol_print_error($this->db);
1635 }
1636 }
1637
1644 public function initAsSpecimen()
1645 {
1646 // Set here init that are not commonf fields
1647 // $this->property1 = ...
1648 // $this->property2 = ...
1649
1650 return $this->initAsSpecimenCommon();
1651 }
1652
1658 public function getNextNumRef()
1659 {
1660 global $langs, $conf;
1661 $langs->load("assets");
1662
1663 if (!getDolGlobalString('ASSET_ASSET_ADDON')) {
1664 $conf->global->ASSET_ASSET_ADDON = 'mod_asset_standard';
1665 }
1666
1667 if (getDolGlobalString('ASSET_ASSET_ADDON')) {
1668 $mybool = false;
1669
1670 $file = getDolGlobalString('ASSET_ASSET_ADDON') . ".php";
1671 $classname = getDolGlobalString('ASSET_ASSET_ADDON');
1672
1673 // Include file with class
1674 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1675 foreach ($dirmodels as $reldir) {
1676 $dir = dol_buildpath($reldir."core/modules/asset/");
1677
1678 // Load file with numbering class (if found)
1679 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1680 }
1681
1682 if (!$mybool) {
1683 dol_print_error(null, "Failed to include file ".$file);
1684 return '';
1685 }
1686
1687 if (class_exists($classname)) {
1688 $obj = new $classname();
1689
1690 '@phan-var-force ModeleNumRefAsset $obj';
1691
1692 $numref = $obj->getNextValue($this);
1693
1694 if ($numref != '' && $numref != '-1') {
1695 return $numref;
1696 } else {
1697 $this->error = $obj->error;
1698 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1699 return "";
1700 }
1701 } else {
1702 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1703 return "";
1704 }
1705 } else {
1706 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1707 return "";
1708 }
1709 }
1710
1718 public function validate($user, $notrigger = 0)
1719 {
1720 global $conf;
1721
1722 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1723
1724 $error = 0;
1725
1726 // Protection
1727 if ($this->status == self::STATUS_VALIDATED) {
1728 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
1729 return 0;
1730 }
1731
1732 $now = dol_now();
1733
1734 $this->db->begin();
1735
1736 // Define new ref
1737 if (/* !$error && */ (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
1738 $num = $this->getNextNumRef();
1739 } else {
1740 $num = $this->ref;
1741 }
1742 $this->newref = dol_sanitizeFileName($num);
1743
1744 // Validate
1745 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1746 $sql .= " SET ref = '".$this->db->escape($num)."',";
1747 $sql .= " status = ".self::STATUS_VALIDATED.",";
1748 $sql .= " date_valid='".$this->db->idate($now)."',";
1749 $sql .= " fk_user_valid = ".((int) $user->id);
1750 $sql .= " WHERE rowid = ".((int) $this->id);
1751
1752 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
1753 $resql = $this->db->query($sql);
1754 if (!$resql) {
1755 dol_print_error($this->db);
1756 $this->error = $this->db->lasterror();
1757 $error++;
1758 }
1759
1760 if (!$error && !$notrigger) {
1761 // Call trigger
1762 $result = $this->call_trigger('ASSET_VALIDATE', $user);
1763 if ($result < 0) {
1764 $error++;
1765 }
1766 // End call triggers
1767 }
1768
1769 if (!$error) {
1770 $this->oldref = $this->ref;
1771
1772 // Rename directory if dir was a temporary ref
1773 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
1774 // Now we rename also files into index
1775 $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)."'";
1776 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'bom/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1777 $resql = $this->db->query($sql);
1778 if (!$resql) {
1779 $error++;
1780 $this->error = $this->db->lasterror();
1781 }
1782 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'asset/".$this->db->escape($this->newref)."'";
1783 $sql .= " WHERE filepath = 'asset/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1784 $resql = $this->db->query($sql);
1785 if (!$resql) {
1786 $error++;
1787 $this->error = $this->db->lasterror();
1788 }
1789
1790 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
1791 $oldref = dol_sanitizeFileName($this->ref);
1792 $newref = dol_sanitizeFileName($num);
1793 $dirsource = $conf->asset->dir_output.'/'.$oldref;
1794 $dirdest = $conf->asset->dir_output.'/'.$newref;
1795 if (!$error && file_exists($dirsource)) {
1796 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
1797
1798 if (@rename($dirsource, $dirdest)) {
1799 dol_syslog("Rename ok");
1800 // Rename docs starting with $oldref with $newref
1801 $listoffiles = dol_dir_list($conf->asset->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
1802 foreach ($listoffiles as $fileentry) {
1803 $dirsource = $fileentry['name'];
1804 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
1805 $dirsource = $fileentry['path'].'/'.$dirsource;
1806 $dirdest = $fileentry['path'].'/'.$dirdest;
1807 @rename($dirsource, $dirdest);
1808 }
1809 }
1810 }
1811 }
1812 }
1813
1814 // Set new ref and current status
1815 if (!$error) {
1816 $this->ref = $num;
1817 $this->status = self::STATUS_VALIDATED;
1818 }
1819
1820 if (!$error) {
1821 $this->db->commit();
1822 return 1;
1823 } else {
1824 $this->db->rollback();
1825 return -1;
1826 }
1827 }
1828
1836 public function setDraft($user, $notrigger = 0)
1837 {
1838 // Protection
1839 if ($this->status <= self::STATUS_DRAFT) {
1840 return 0;
1841 }
1842
1843 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'ASSET_UNVALIDATE');
1844 }
1845}
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