Passed
Push — EXTRACT_CLASSES ( 231cec...0382f2 )
by Rafael
65:54 queued 05:18
created

Asset::createFromClone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 91
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 91
rs 10
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* Copyright (C) 2017       Laurent Destailleur         <[email protected]>
4
 * Copyright (C) 2018       Alexandre Spangaro          <[email protected]>
5
 * Copyright (C) 2024       Frédéric France             <[email protected]>
6
 * Copyright (C) 2024		MDW							<[email protected]>
7
 * Copyright (C) 2024       Rafael San José             <[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
namespace Dolibarr\Code\Asset\Classes;
24
25
/**
26
 * \file        asset/class/asset.class.php
27
 * \ingroup     asset
28
 * \brief       This file is a CRUD class file for Asset (Create/Read/Update/Delete)
29
 */
30
31
use Dolibarr\Core\Base\CommonObject;
32
33
/**
34
 * Class for Asset
35
 */
36
class Asset extends CommonObject
37
{
38
    /**
39
     * @var string ID of module.
40
     */
41
    public $module = 'asset';
42
43
    /**
44
     * @var string ID to identify managed object.
45
     */
46
    public $element = 'asset';
47
48
    /**
49
     * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management.
50
     */
51
    public $table_element = 'asset';
52
53
    /**
54
     * @var string String with name of icon for asset. Must be the part after the 'object_' into object_asset.png
55
     */
56
    public $picto = 'asset';
57
58
    const STATUS_DRAFT = 0;     // In progress
59
    const STATUS_DISPOSED = 9;  // Disposed
60
61
    /**
62
     *  'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
63
     *         Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
64
     *  'label' the translation key.
65
     *  'picto' is code of a picto to show before value in forms
66
     *  'enabled' is a condition when the field must be managed (Example: 1 or 'getDolGlobalString("MY_SETUP_PARAM")'
67
     *  'position' is the sort order of field.
68
     *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
69
     *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
70
     *  'noteditable' says if field is not editable (1 or 0)
71
     *  'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
72
     *  'index' if we want an index in database.
73
     *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...).
74
     *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
75
     *  'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage)
76
     *  'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
77
     *  'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
78
     *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
79
     *  'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
80
     *  'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar'
81
     *  'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
82
     *  'comment' is not used. You can store here any text of your choice. It is not used by application.
83
     *  'validate' is 1 if need to validate with $this->validateField()
84
     *  'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value)
85
     *
86
     *  Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
87
     */
88
89
    /**
90
     * @var array<string,array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}>  Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,array{type:...ring>,comment?:string}> at position 16 could not be parsed: Expected '}' at position 16, but found 'int'.
Loading history...
91
     */
92
    public $fields = array(
93
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
94
        'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => 1, 'noteditable' => 0, 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'validate' => 1, 'comment' => "Reference of object"),
95
        'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'position' => 30, 'notnull' => 1, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => '2', 'validate' => 1,),
96
        '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,),
97
        'qty' => array('type' => 'real', 'label' => 'Qty', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 0, 'default' => '1', 'isameasure' => 1, 'css' => 'maxwidth75imp', 'validate' => 1,),
98
        'acquisition_type' => array('type' => 'smallint', 'label' => 'AssetAcquisitionType', 'enabled' => 1, 'position' => 60, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => array('0' => 'AssetAcquisitionTypeNew', '1' => 'AssetAcquisitionTypeOccasion'), 'validate' => 1,),
99
        '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,),
100
        'not_depreciated' => array('type' => 'boolean', 'label' => 'AssetNotDepreciated', 'enabled' => 1, 'position' => 80, 'notnull' => 0, 'default' => '0', 'visible' => 1, 'validate' => 1,),
101
        'date_acquisition' => array('type' => 'date', 'label' => 'AssetDateAcquisition', 'enabled' => 1, 'position' => 90, 'notnull' => 1, 'visible' => 1,),
102
        'date_start' => array('type' => 'date', 'label' => 'AssetDateStart', 'enabled' => 1, 'position' => 100, 'notnull' => 0, 'visible' => -1,),
103
        'acquisition_value_ht' => array('type' => 'price', 'label' => 'AssetAcquisitionValueHT', 'enabled' => 1, 'position' => 110, 'notnull' => 1, 'visible' => 1, 'isameasure' => 1, 'validate' => 1,),
104
        'recovered_vat' => array('type' => 'price', 'label' => 'AssetRecoveredVAT', 'enabled' => 1, 'position' => 120, 'notnull' => 0, 'visible' => 1, 'isameasure' => 1, 'validate' => 1,),
105
        'reversal_date' => array('type' => 'date', 'label' => 'AssetReversalDate', 'enabled' => 1, 'position' => 130, 'notnull' => 0, 'visible' => 1,),
106
        'reversal_amount_ht' => array('type' => 'price', 'label' => 'AssetReversalAmountHT', 'enabled' => 1, 'position' => 140, 'notnull' => 0, 'visible' => 1, 'isameasure' => 1, 'validate' => 1,),
107
        'disposal_date' => array('type' => 'date', 'label' => 'AssetDisposalDate', 'enabled' => 1, 'position' => 200, 'notnull' => 0, 'visible' => -2,),
108
        'disposal_amount_ht' => array('type' => 'price', 'label' => 'AssetDisposalAmount', 'enabled' => 1, 'position' => 210, 'notnull' => 0, 'visible' => -2, 'default' => '0', 'isameasure' => 1, 'validate' => 1,),
109
        '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,),
110
        'disposal_depreciated' => array('type' => 'boolean', 'label' => 'AssetDisposalDepreciated', 'enabled' => 1, 'position' => 230, 'notnull' => 0, 'default' => '0', 'visible' => -2, 'validate' => 1,),
111
        'disposal_subject_to_vat' => array('type' => 'boolean', 'label' => 'AssetDisposalSubjectToVat', 'enabled' => 1, 'position' => 240, 'notnull' => 0, 'default' => '0', 'visible' => -2, 'validate' => 1,),
112
        'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 300, 'notnull' => 0, 'visible' => 0, 'validate' => 1,),
113
        'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 301, 'notnull' => 0, 'visible' => 0, 'validate' => 1,),
114
        'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
115
        'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
116
        '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',),
117
        'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
118
        'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'position' => 600, 'notnull' => 0, 'visible' => 0,),
119
        'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
120
        'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
121
        '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,),
122
    );
123
    public $rowid;
124
    public $ref;
125
    public $label;
126
    public $fk_asset_model;
127
    public $reversal_amount_ht;
128
    public $acquisition_value_ht;
129
    public $recovered_vat;
130
    public $reversal_date;
131
    public $date_acquisition;
132
    public $date_start;
133
    public $qty;
134
    public $acquisition_type;
135
    public $asset_type;
136
    public $not_depreciated;
137
    public $disposal_date;
138
    public $disposal_amount_ht;
139
    public $fk_disposal_type;
140
    public $disposal_depreciated;
141
    public $disposal_subject_to_vat;
142
    public $supplier_invoice_id;
143
    public $note_public;
144
    public $note_private;
145
    public $date_creation;
146
    public $fk_user_creat;
147
    public $fk_user_modif;
148
    public $last_main_doc;
149
    public $import_key;
150
    public $model_pdf;
151
    public $status;
152
153
    /**
154
     * @var static object oldcopy
155
     */
156
    public $oldcopy;
157
158
159
    /**
160
     * @var AssetDepreciationOptions    Used for computed fields of depreciation options class.
161
     */
162
    public $asset_depreciation_options;
163
    public $asset_accountancy_codes;
164
    /**
165
     * @var array   List of depreciation lines for each mode (sort by depreciation date).
166
     */
167
    public $depreciation_lines = array();
168
169
    /**
170
     * Constructor
171
     *
172
     * @param DoliDB $db Database handler
173
     */
174
    public function __construct(DoliDB $db)
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Asset\Classes\DoliDB was not found. Did you mean DoliDB? If so, make sure to prefix the type with \.
Loading history...
175
    {
176
        global $conf, $langs;
177
178
        $this->db = $db;
179
180
        $this->ismultientitymanaged = 1;
181
        $this->isextrafieldmanaged = 1;
182
183
        if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
184
            $this->fields['rowid']['visible'] = 0;
185
        }
186
        if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
187
            $this->fields['entity']['enabled'] = 0;
188
        }
189
190
        // Unset fields that are disabled
191
        foreach ($this->fields as $key => $val) {
192
            if (isset($val['enabled']) && empty($val['enabled'])) {
193
                unset($this->fields[$key]);
194
            }
195
        }
196
197
        // Translate some data of arrayofkeyval
198
        if (is_object($langs)) {
199
            foreach ($this->fields as $key => $val) {
200
                if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
201
                    foreach ($val['arrayofkeyval'] as $key2 => $val2) {
202
                        $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
203
                    }
204
                }
205
            }
206
        }
207
    }
208
209
    /**
210
     * Create object into database
211
     *
212
     * @param  User $user      User that creates
213
     * @param  int  $notrigger false=launch triggers after, true=disable triggers
214
     * @return int             Return integer <0 if KO, Id of created object if OK
215
     */
216
    public function create(User $user, $notrigger = 0)
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Asset\Classes\User was not found. Did you mean User? If so, make sure to prefix the type with \.
Loading history...
217
    {
218
        if (!isset($this->date_start) || $this->date_start === "") {
219
            $this->date_start = $this->date_acquisition;
220
        }
221
222
        $this->db->begin();
223
224
        $result = $result_create = $this->createCommon($user, $notrigger);
225
        if ($result > 0 && $this->fk_asset_model > 0) {
226
            $result = $this->setDataFromAssetModel($user, $notrigger);
227
        }
228
        if ($result > 0) {
229
            if ($this->supplier_invoice_id > 0) {
230
                $this->add_object_linked('invoice_supplier', $this->supplier_invoice_id);
231
            }
232
        }
233
234
        if ($result < 0) {
235
            $this->db->rollback();
236
        } else {
237
            $this->db->commit();
238
        }
239
240
        return $result > 0 ? $result_create : $result;
241
    }
242
243
    /**
244
     * Clone an object into another one
245
     *
246
     * @param   User    $user       User that creates
247
     * @param   int     $fromid     Id of object to clone
248
     * @return  mixed               New object created, <0 if KO
249
     */
250
    public function createFromClone(User $user, $fromid)
251
    {
252
        global $langs, $extrafields;
253
        $error = 0;
254
255
        dol_syslog(__METHOD__, LOG_DEBUG);
256
257
        //      $object = new self($this->db);
258
        //
259
        //      $this->db->begin();
260
        //
261
        //      // Load source object
262
        //      $result = $object->fetchCommon($fromid);
263
        //      if ($result > 0 && !empty($object->table_element_line)) {
264
        //          $object->fetchLines();
265
        //      }
266
        //
267
        //      // get lines so they will be clone
268
        //      //foreach($this->lines as $line)
269
        //      //  $line->fetch_optionals();
270
        //
271
        //      // Reset some properties
272
        //      unset($object->id);
273
        //      unset($object->fk_user_creat);
274
        //      unset($object->import_key);
275
        //
276
        //      // Clear fields
277
        //      if (property_exists($object, 'ref')) {
278
        //          $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
279
        //      }
280
        //      if (property_exists($object, 'label')) {
281
        //          $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
282
        //      }
283
        //      if (property_exists($object, 'status')) {
284
        //          $object->status = self::STATUS_DRAFT;
285
        //      }
286
        //      if (property_exists($object, 'date_creation')) {
287
        //          $object->date_creation = dol_now();
288
        //      }
289
        //      if (property_exists($object, 'date_modification')) {
290
        //          $object->date_modification = null;
291
        //      }
292
        //      // ...
293
        //      // Clear extrafields that are unique
294
        //      if (is_array($object->array_options) && count($object->array_options) > 0) {
295
        //          $extrafields->fetch_name_optionals_label($this->table_element);
296
        //          foreach ($object->array_options as $key => $option) {
297
        //              $shortkey = preg_replace('/options_/', '', $key);
298
        //              if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
299
        //                  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
300
        //                  unset($object->array_options[$key]);
301
        //              }
302
        //          }
303
        //      }
304
        //
305
        //      // Create clone
306
        //      $object->context['createfromclone'] = 'createfromclone';
307
        //      $result = $object->createCommon($user);
308
        //      if ($result < 0) {
309
        //          $error++;
310
        //          $this->error = $object->error;
311
        //          $this->errors = $object->errors;
312
        //      }
313
        //
314
        //      if (!$error) {
315
        //          // copy internal contacts
316
        //          if ($this->copy_linked_contact($object, 'internal') < 0) {
317
        //              $error++;
318
        //          }
319
        //      }
320
        //
321
        //      if (!$error) {
322
        //          // copy external contacts if same company
323
        //          if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
324
        //              if ($this->copy_linked_contact($object, 'external') < 0) {
325
        //                  $error++;
326
        //              }
327
        //          }
328
        //      }
329
        //
330
        //      unset($object->context['createfromclone']);
331
        //
332
        //      // End
333
        //      if (!$error) {
334
        //          $this->db->commit();
335
        //          return $object;
336
        //      } else {
337
        //          $this->db->rollback();
338
        //          return -1;
339
        //      }
340
        return -1;
341
    }
342
343
    /**
344
     * Load object in memory from the database
345
     *
346
     * @param int    $id   Id object
347
     * @param string $ref  Ref
348
     * @return int         Return integer <0 if KO, 0 if not found, >0 if OK
349
     */
350
    public function fetch($id, $ref = null)
351
    {
352
        $result = $this->fetchCommon($id, $ref);
353
        if ($result > 0) {
354
            if (!empty($this->table_element_line)) {
355
                $this->fetchLines();
356
            }
357
358
            $res = $this->hasDepreciationLinesInBookkeeping();
359
            if ($res < 0) {
360
                return -1;
361
            } elseif ($res > 0) {
362
                $this->fields['date_acquisition']['noteditable'] = '1';
363
                $this->fields['date_start']['noteditable'] = '1';
364
                $this->fields['acquisition_value_ht']['noteditable'] = '1';
365
                $this->fields['recovered_vat']['noteditable'] = '1';
366
                $this->fields['reversal_date']['noteditable'] = '1';
367
                $this->fields['reversal_amount_ht']['noteditable'] = '1';
368
            }
369
        }
370
        return $result;
371
    }
372
373
    /**
374
     * Load object lines in memory from the database
375
     *
376
     * @return int         Return integer <0 if KO, 0 if not found, >0 if OK
377
     */
378
    public function fetchLines()
379
    {
380
        $this->lines = array();
381
382
        return 1;
383
    }
384
385
386
    /**
387
     * Load list of objects in memory from the database.
388
     *
389
     * @param  string       $sortorder      Sort Order
390
     * @param  string       $sortfield      Sort field
391
     * @param  int          $limit          limit
392
     * @param  int          $offset         Offset
393
     * @param  string       $filter         Filter as an Universal Search string.
394
     *                                      Example: '((client:=:1) OR ((client:>=:2) AND (client:<=:3))) AND (client:!=:8) AND (nom:like:'a%')'
395
     * @param  string       $filtermode     No more used
396
     * @return array|int                    int <0 if KO, array of pages if OK
397
     */
398
    public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
399
    {
400
        dol_syslog(__METHOD__, LOG_DEBUG);
401
402
        $records = array();
403
404
        $sql = "SELECT ";
405
        $sql .= $this->getFieldList('t');
406
        $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element . " as t";
407
        if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
408
            $sql .= " WHERE t.entity IN (" . getEntity($this->element) . ")";
409
        } else {
410
            $sql .= " WHERE 1 = 1";
411
        }
412
413
        // Manage filter
414
        $errormessage = '';
415
        $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
416
        if ($errormessage) {
417
            $this->errors[] = $errormessage;
418
            dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
419
420
            return -1;
421
        }
422
423
        if (!empty($sortfield)) {
424
            $sql .= $this->db->order($sortfield, $sortorder);
425
        }
426
        if (!empty($limit)) {
427
            $sql .= $this->db->plimit($limit, $offset);
428
        }
429
430
        $resql = $this->db->query($sql);
431
        if ($resql) {
432
            $num = $this->db->num_rows($resql);
433
            $i = 0;
434
            while ($i < ($limit ? min($limit, $num) : $num)) {
435
                $obj = $this->db->fetch_object($resql);
436
437
                $record = new self($this->db);
438
                $record->setVarsFromFetchObj($obj);
439
440
                $records[$record->id] = $record;
441
442
                $i++;
443
            }
444
            $this->db->free($resql);
445
446
            return $records;
447
        } else {
448
            $this->errors[] = 'Error ' . $this->db->lasterror();
449
            dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
450
451
            return -1;
452
        }
453
    }
454
455
    /**
456
     * Update object into database
457
     *
458
     * @param  User $user      User that modifies
459
     * @param  int  $notrigger 0=launch triggers after, 1=disable triggers
460
     * @return int             Return integer <0 if KO, >0 if OK
461
     */
462
    public function update(User $user, $notrigger = 0)
463
    {
464
        if (!isset($this->date_start) || $this->date_start === "") {
465
            $this->date_start = $this->date_acquisition;
466
        }
467
468
        $this->db->begin();
469
470
        $result = $this->updateCommon($user, $notrigger);
471
        if ($result > 0 && $this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model) {
472
            $result = $this->setDataFromAssetModel($user, $notrigger);
473
        }
474
        if (
475
            $result > 0 && (
476
            $this->date_start != $this->oldcopy->date_start ||
477
                $this->acquisition_value_ht != $this->oldcopy->acquisition_value_ht ||
478
                $this->reversal_date != $this->oldcopy->reversal_date ||
479
                $this->reversal_amount_ht != $this->oldcopy->reversal_amount_ht ||
480
                ($this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model)
481
            )
482
        ) {
483
            $result = $this->calculationDepreciation();
484
        }
485
486
        if ($result < 0) {
487
            $this->db->rollback();
488
        } else {
489
            $this->db->commit();
490
        }
491
492
        return $result;
493
    }
494
495
    /**
496
     * Delete object in database
497
     *
498
     * @param User  $user       User that deletes
499
     * @param int   $notrigger  0=launch triggers after, 1=disable triggers
500
     * @return int              Return integer <0 if KO, >0 if OK
501
     */
502
    public function delete(User $user, $notrigger = 0)
503
    {
504
        return $this->deleteCommon($user, $notrigger);
505
        //return $this->deleteCommon($user, $notrigger, 1);
506
    }
507
508
    /**
509
     * Set asset model
510
     *
511
     * @param  User $user       User that creates
512
     * @param  int $notrigger   0=launch triggers after, 1=disable triggers
513
     * @return int              Return integer <0 if KO, Id of created object if OK
514
     */
515
    public function setDataFromAssetModel(User $user, $notrigger = 0)
516
    {
517
        global $langs;
518
        $langs->load('assets');
519
520
        // Clean parameters
521
        $this->id = $this->id > 0 ? $this->id : 0;
522
        $this->fk_asset_model = $this->fk_asset_model > 0 ? $this->fk_asset_model : 0;
523
524
        // Check parameters
525
        $error = 0;
526
        if (empty($this->id)) {
527
            $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
528
            $error++;
529
        }
530
        if (empty($this->fk_asset_model)) {
531
            $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetModel") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
532
            $error++;
533
        }
534
        if ($error) {
535
            return -1;
536
        }
537
538
        $this->db->begin();
539
540
        // Get depreciation options
541
        //---------------------------
542
        require_once constant('DOL_DOCUMENT_ROOT') . '/asset/class/assetdepreciationoptions.class.php';
543
        $options_model = new AssetDepreciationOptions($this->db);
544
        $result = $options_model->fetchDeprecationOptions(0, $this->fk_asset_model);
545
        if ($result < 0) {
546
            $this->error = $options_model->error;
547
            $this->errors = $options_model->errors;
548
            $error++;
549
        } elseif ($result > 0) {
550
            $options = new AssetDepreciationOptions($this->db);
551
            $result = $options->fetchDeprecationOptions($this->id);
552
            if ($result < 0) {
553
                $this->error = $options->error;
554
                $this->errors = $options->errors;
555
                $error++;
556
            }
557
558
            if (!$error) {
559
                foreach ($options_model->deprecation_options as $mode_key => $fields) {
560
                    foreach ($fields as $field_key => $value) {
561
                        $options->deprecation_options[$mode_key][$field_key] = $value;
562
                    }
563
                }
564
565
                $result = $options->updateDeprecationOptions($user, $this->id, 0, $notrigger);
566
                if ($result < 0) {
567
                    $this->error = $options->error;
568
                    $this->errors = $options->errors;
569
                    $error++;
570
                }
571
            }
572
        }
573
574
        // Get accountancy codes
575
        //---------------------------
576
        if (!$error) {
577
            require_once constant('DOL_DOCUMENT_ROOT') . '/asset/class/assetaccountancycodes.class.php';
578
            $accountancy_codes_model = new AssetAccountancyCodes($this->db);
579
            $result = $accountancy_codes_model->fetchAccountancyCodes(0, $this->fk_asset_model);
580
            if ($result < 0) {
581
                $this->error = $accountancy_codes_model->error;
582
                $this->errors = $accountancy_codes_model->errors;
583
                $error++;
584
            } elseif ($result > 0) {
585
                $accountancy_codes = new AssetAccountancyCodes($this->db);
586
                $result = $accountancy_codes->fetchAccountancyCodes($this->id);
587
                if ($result < 0) {
588
                    $this->error = $accountancy_codes->error;
589
                    $this->errors = $accountancy_codes->errors;
590
                    $error++;
591
                }
592
593
                if (!$error) {
594
                    foreach ($accountancy_codes_model->accountancy_codes as $mode_key => $fields) {
595
                        foreach ($fields as $field_key => $value) {
596
                            $accountancy_codes->accountancy_codes[$mode_key][$field_key] = $value;
597
                        }
598
                    }
599
600
                    $result = $accountancy_codes->updateAccountancyCodes($user, $this->id, 0, $notrigger);
601
                    if ($result < 0) {
602
                        $this->error = $accountancy_codes->error;
603
                        $this->errors = $accountancy_codes->errors;
604
                        $error++;
605
                    }
606
                }
607
            }
608
        }
609
610
        if ($error) {
611
            $this->db->rollback();
612
            return -1;
613
        } else {
614
            $this->db->commit();
615
            return 1;
616
        }
617
    }
618
619
    /**
620
     * Fetch depreciation lines for each mode in $this->depreciation_lines (sort by depreciation date)
621
     *
622
     * @return  int                         Return integer <0 if KO, Id of created object if OK
623
     */
624
    public function fetchDepreciationLines()
625
    {
626
        global $langs;
627
        $langs->load('assets');
628
        $this->depreciation_lines = array();
629
630
        // Clean parameters
631
        $this->id = $this->id > 0 ? $this->id : 0;
632
633
        // Check parameters
634
        $error = 0;
635
        if (empty($this->id)) {
636
            $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
637
            $error++;
638
        }
639
        if ($error) {
640
            return -1;
641
        }
642
643
        // Old request with 'WITH'
644
        /*
645
        $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
646
        $sql .= " SELECT DISTINCT fk_docdet";
647
        $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
648
        $sql .= " WHERE doc_type = 'asset'";
649
        $sql .= ")";
650
        $sql .= "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht";
651
        $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', 1, 0) . " AS bookkeeping";
652
        $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
653
        $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
654
        $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
655
        $sql .= " ORDER BY ad.depreciation_date ASC";
656
        */
657
658
        $sql = "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht";
659
        $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', 1, 0) . " AS bookkeeping";
660
        $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
661
        $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";
662
        $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
663
        $sql .= " ORDER BY ad.depreciation_date ASC";
664
665
        $resql = $this->db->query($sql);
666
        if (!$resql) {
667
            $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror();
668
            return -1;
669
        }
670
671
        while ($obj = $this->db->fetch_object($resql)) {
672
            if (!isset($this->depreciation_lines[$obj->depreciation_mode])) {
673
                $this->depreciation_lines[$obj->depreciation_mode] = array();
674
            }
675
            $this->depreciation_lines[$obj->depreciation_mode][] = array(
676
                'id' => $obj->rowid,
677
                'ref' => $obj->ref,
678
                'depreciation_date' => $this->db->jdate($obj->depreciation_date),
679
                'depreciation_ht' => $obj->depreciation_ht,
680
                'cumulative_depreciation_ht' => $obj->cumulative_depreciation_ht,
681
                'bookkeeping' => $obj->bookkeeping,
682
            );
683
        }
684
685
        return 1;
686
    }
687
688
    /**
689
     * If has depreciation lines in bookkeeping
690
     *
691
     * @return  int         Return integer <0 if KO, 0 if NO, 1 if Yes
692
     */
693
    public function hasDepreciationLinesInBookkeeping()
694
    {
695
        global $langs;
696
        $langs->load('assets');
697
698
        // Clean parameters
699
        $this->id = $this->id > 0 ? $this->id : 0;
700
701
        // Check parameters
702
        $error = 0;
703
        if (empty($this->id)) {
704
            $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
705
            $error++;
706
        }
707
        if ($error) {
708
            return -1;
709
        }
710
711
        // Old request with 'WITH'
712
        /*
713
        $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
714
        $sql .= " SELECT DISTINCT fk_docdet";
715
        $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
716
        $sql .= " WHERE doc_type = 'asset'";
717
        $sql .= ")";
718
        $sql .= "SELECT COUNT(*) AS has_bookkeeping";
719
        $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
720
        $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
721
        $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
722
        $sql .= " AND iab.fk_docdet IS NOT NULL";
723
        */
724
725
        $sql = "SELECT COUNT(*) AS has_bookkeeping";
726
        $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
727
        $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";
728
        $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
729
        $sql .= " AND iab.fk_docdet IS NOT NULL";
730
731
        $resql = $this->db->query($sql);
732
        if (!$resql) {
733
            $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror();
734
            return -1;
735
        }
736
737
        if ($obj = $this->db->fetch_object($resql)) {
738
            return $obj->has_bookkeeping > 0 ? 1 : 0;
739
        }
740
741
        return 0;
742
    }
743
744
    /**
745
     * Add depreciation line for a mode
746
     *
747
     * @param   string      $mode                           Depreciation mode (economic, accelerated_depreciation, ...)
748
     * @param   string      $ref                            Ref line
749
     * @param   int         $depreciation_date              Depreciation date
750
     * @param   double      $depreciation_ht                Depreciation amount HT
751
     * @param   double      $cumulative_depreciation_ht     Depreciation cumulative amount HT
752
     * @param   string      $accountancy_code_debit         Accountancy code Debit
753
     * @param   string      $accountancy_code_credit        Accountancy code Credit
754
     * @return  int                                         Return integer <0 if KO, Id of created line if OK
755
     */
756
    public function addDepreciationLine($mode, $ref, $depreciation_date, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_debit, $accountancy_code_credit)
757
    {
758
        global $langs;
759
        $langs->load('assets');
760
761
        // Clean parameters
762
        $this->id = $this->id > 0 ? $this->id : 0;
763
        $mode = strtolower(trim($mode));
764
        $ref = trim($ref);
765
        $accountancy_code_debit = trim($accountancy_code_debit);
766
        $accountancy_code_credit = trim($accountancy_code_credit);
767
768
        // Check parameters
769
        $error = 0;
770
        if (empty($this->id)) {
771
            $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
772
            $error++;
773
        }
774
        if ($error) {
775
            return -1;
776
        }
777
778
        $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)";
779
        $sql .= " VALUES ( ";
780
        $sql .= " " . (int) $this->id;
781
        $sql .= ", '" . $this->db->escape($mode) . "'";
782
        $sql .= ", '" . $this->db->escape($ref) . "'";
783
        $sql .= ", '" . $this->db->idate($depreciation_date) . "'";
784
        $sql .= ", " . (float) $depreciation_ht;
785
        $sql .= ", " . (float) $cumulative_depreciation_ht;
786
        $sql .= ", '" . $this->db->escape($accountancy_code_debit) . "'";
787
        $sql .= ", '" . $this->db->escape($accountancy_code_credit) . "'";
788
        $sql .= ")";
789
790
        $resql = $this->db->query($sql);
791
        if (!$resql) {
792
            $this->errors[] = $langs->trans('AssetErrorAddDepreciationLine') . ': ' . $this->db->lasterror();
793
            return -1;
794
        }
795
796
        return 1;
797
    }
798
799
    /**
800
     * Calculation depreciation lines (reversal and future) for each mode
801
     *
802
     * @return  int                         Return integer <0 if KO, Id of created object if OK
803
     */
804
    public function calculationDepreciation()
805
    {
806
        global $conf, $langs;
807
        $langs->load('assets');
808
809
        // Clean parameters
810
        $this->id = $this->id > 0 ? $this->id : 0;
811
812
        // Check parameters
813
        $error = 0;
814
        if (empty($this->id)) {
815
            $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
816
            $error++;
817
        }
818
        if ($error) {
819
            return -1;
820
        }
821
822
        // Get depreciation options
823
        //---------------------------
824
        require_once constant('DOL_DOCUMENT_ROOT') . '/asset/class/assetdepreciationoptions.class.php';
825
        $options = new AssetDepreciationOptions($this->db);
826
        $result = $options->fetchDeprecationOptions($this->id);
827
        if ($result < 0) {
828
            $this->error = $options->error;
829
            $this->errors = $options->errors;
830
            return -1;
831
        }
832
833
        // Get accountancy codes
834
        //---------------------------
835
        require_once constant('DOL_DOCUMENT_ROOT') . '/asset/class/assetaccountancycodes.class.php';
836
        $accountancy_codes = new AssetAccountancyCodes($this->db);
837
        $result = $accountancy_codes->fetchAccountancyCodes($this->id);
838
        if ($result < 0) {
839
            $this->error = $accountancy_codes->error;
840
            $this->errors = $accountancy_codes->errors;
841
            return -1;
842
        }
843
844
        $this->db->begin();
845
846
        // Delete old lines
847
        $modes = array();
848
        foreach ($options->deprecation_options as $mode_key => $fields) {
849
            $modes[$mode_key] = $this->db->escape($mode_key);
850
        }
851
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation";
852
        $sql .= " WHERE fk_asset = " . (int) $this->id;
853
        $sql .= " AND depreciation_mode NOT IN ('" . $this->db->sanitize(implode("', '", $modes)) . "')";
854
855
        $resql = $this->db->query($sql);
856
        if (!$resql) {
857
            $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror();
858
            $error++;
859
        }
860
861
        if (!$error) {
862
            // Get fiscal period
863
            require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php';
864
            require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/accounting.lib.php';
865
            $dates = getDefaultDatesForTransfer();
866
            $init_fiscal_period_start = $dates['date_start'];
867
            $init_fiscal_period_end = $dates['date_end'];
868
            if (empty($init_fiscal_period_start) || empty($init_fiscal_period_end)) {
869
                $pastmonthyear = $dates['pastmonthyear'];
870
                $pastmonth = $dates['pastmonth'];
871
                $init_fiscal_period_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
872
                $init_fiscal_period_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
873
            }
874
875
            foreach ($options->deprecation_options as $mode_key => $fields) {
876
                // Get last depreciation lines save in bookkeeping
877
                //-----------------------------------------------------
878
879
                // Old request with 'WITH'
880
                /*
881
                $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS (";
882
                $sql .= " SELECT fk_docdet";
883
                $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
884
                $sql .= " WHERE doc_type = 'asset'";
885
                $sql .= ")";
886
                $sql .= "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht";
887
                $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
888
                $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
889
                $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
890
                $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
891
                $sql .= " AND iab.fk_docdet IS NOT NULL";
892
                $sql .= " ORDER BY ad.depreciation_date DESC";
893
                $sql .= " LIMIT 1";
894
                */
895
896
                $sql = "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht";
897
                $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad";
898
                $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";
899
                $sql .= " WHERE ad.fk_asset = " . (int) $this->id;
900
                $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
901
                $sql .= " AND iab.fk_docdet IS NOT NULL";
902
                $sql .= " ORDER BY ad.depreciation_date DESC";
903
                $sql .= " LIMIT 1";
904
905
                $resql = $this->db->query($sql);
906
                if (!$resql) {
907
                    $this->errors[] = $langs->trans('AssetErrorFetchMaxDepreciationDateForMode', $mode_key) . ': ' . $this->db->lasterror();
908
                    $error++;
909
                    break;
910
                }
911
                $last_depreciation_date = '';
912
                $last_cumulative_depreciation_ht = $this->reversal_amount_ht;
913
                if ($obj = $this->db->fetch_object($resql)) {
914
                    $last_depreciation_date = $this->db->jdate($obj->depreciation_date);
915
                    $last_cumulative_depreciation_ht = $obj->cumulative_depreciation_ht;
916
                }
917
918
                // Set last cumulative depreciation
919
                $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table'];
920
                $sql .= " SET total_amount_last_depreciation_ht = " . (empty($last_cumulative_depreciation_ht) ? 0 : $last_cumulative_depreciation_ht);
921
                $sql .= " WHERE fk_asset = " . (int) $this->id;
922
                $resql = $this->db->query($sql);
923
                if (!$resql) {
924
                    $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror();
925
                    $error++;
926
                    break;
927
                }
928
929
                // Delete old lines
930
                $sql = "DELETE " . MAIN_DB_PREFIX . "asset_depreciation FROM " . MAIN_DB_PREFIX . "asset_depreciation";
931
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab ON ab.doc_type = 'asset' AND ab.fk_docdet = " . MAIN_DB_PREFIX . "asset_depreciation.rowid";
932
                $sql .= " WHERE " . MAIN_DB_PREFIX . "asset_depreciation.fk_asset = " . (int) $this->id;
933
                $sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
934
                $sql .= " AND ab.fk_docdet IS NULL";
935
                if ($last_depreciation_date !== "") {
936
                    $sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.ref != ''";
937
                }
938
                $resql = $this->db->query($sql);
939
                if (!$resql) {
940
                    $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror();
941
                    $error++;
942
                    break;
943
                }
944
945
                // Get depreciation period
946
                $depreciation_date_start = $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition;
947
                $depreciation_date_end = dol_time_plus_duree($depreciation_date_start, $fields['duration'], $fields['duration_type'] == 1 ? 'm' : ($fields['duration_type'] == 2 ? 'd' : 'y'));
948
                $depreciation_amount = $fields['amount_base_depreciation_ht'];
949
                if ($fields['duration_type'] == 2) { // Daily
950
                    $fiscal_period_start = $depreciation_date_start;
951
                    $fiscal_period_end = $depreciation_date_start;
952
                } elseif ($fields['duration_type'] == 1) { // Monthly
953
                    $date_temp = dol_getdate($depreciation_date_start);
954
                    $fiscal_period_start = dol_get_first_day($date_temp['year'], $date_temp['mon'], false);
955
                    $fiscal_period_end = dol_get_last_day($date_temp['year'], $date_temp['mon'], false);
956
                } else { // Annually
957
                    $fiscal_period_start = $init_fiscal_period_start;
958
                    $fiscal_period_end = $init_fiscal_period_end;
959
                }
960
                $cumulative_depreciation_ht = $last_cumulative_depreciation_ht;
961
                $depreciation_period_amount = $depreciation_amount - $this->reversal_amount_ht;
962
                $start_date = $depreciation_date_start;
963
                $disposal_date = isset($this->disposal_date) && $this->disposal_date !== "" ? $this->disposal_date : "";
964
                $finish_date = $disposal_date !== "" ? $disposal_date : $depreciation_date_end;
965
                $accountancy_code_depreciation_debit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_debit'];
966
                $accountancy_code_depreciation_debit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_debit_key];
967
                $accountancy_code_depreciation_credit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_credit'];
968
                $accountancy_code_credit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_credit_key];
969
970
                // Reversal depreciation line
971
                //-----------------------------------------------------
972
                if ($last_depreciation_date === "" && ($depreciation_date_start < $fiscal_period_start || is_numeric($this->reversal_date))) {
973
                    if (is_numeric($this->reversal_date)) {
974
                        if ($this->reversal_date < $fiscal_period_start) {
975
                            $this->errors[] = $langs->trans('AssetErrorReversalDateNotGreaterThanCurrentBeginFiscalDateForMode', $mode_key);
976
                            $error++;
977
                            break;
978
                        }
979
980
                        if (empty($this->reversal_amount_ht)) {
981
                            $this->errors[] = $langs->trans('AssetErrorReversalAmountNotProvidedForMode', $mode_key);
982
                            $error++;
983
                            break;
984
                        }
985
986
                        $start_date = $this->reversal_date;
987
                        $result = $this->addDepreciationLine($mode_key, '', $start_date, $this->reversal_amount_ht, $this->reversal_amount_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit);
988
                        if ($result < 0) {
989
                            $error++;
990
                            break;
991
                        }
992
                    } else {
993
                        $this->errors[] = $langs->trans('AssetErrorReversalDateNotProvidedForMode', $mode_key);
994
                        $error++;
995
                        break;
996
                    }
997
                }
998
999
                // futures depreciation lines
1000
                //-----------------------------------------------------
1001
                $nb_days_in_year = getDolGlobalInt('ASSET_DEPRECIATION_DURATION_PER_YEAR', 365);
1002
                $nb_days_in_month = getDolGlobalInt('ASSET_DEPRECIATION_DURATION_PER_MONTH', 30);
1003
                $period_amount = (float) price2num($depreciation_period_amount / $fields['duration'], 'MT');
1004
                $first_period_found = false;
1005
                // TODO fix declaration of $begin_period
1006
                $first_period_date = isset($begin_period) && $begin_period > $fiscal_period_start ? $begin_period : $fiscal_period_start;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $begin_period seems to never exist and therefore isset should always be false.
Loading history...
1007
1008
                $ref_date_format = "%Y" . ($fields['duration_type'] == 1 || $fields['duration_type'] == 2 ? '-%m' : '') . ($fields['duration_type'] == 2 ? '-%d' : '');
1009
1010
                // Loop security
1011
                $idx_loop = 0;
1012
                $max_loop = $fields['duration'] + 2;
1013
                do {
1014
                    // Loop security
1015
                    $idx_loop++;
1016
                    if ($idx_loop > $max_loop) {
1017
                        break;
1018
                    }
1019
1020
                    if ($last_depreciation_date < $fiscal_period_end && ($first_period_date <= $start_date || $first_period_found)) {
1021
                        // Disposal not depreciated
1022
                        if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end && empty($this->disposal_depreciated)) {
1023
                            break;
1024
                        }
1025
1026
                        $first_period_found = true;
1027
1028
                        $period_begin = dol_print_date($fiscal_period_start, $ref_date_format);
1029
                        $period_end = dol_print_date($fiscal_period_end, $ref_date_format);
1030
                        $ref = $period_begin . ($period_begin != $period_end ? ' - ' . $period_end : '');
1031
                        if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end) {
1032
                            $ref .= ' - ' . $langs->transnoentitiesnoconv('AssetDisposal');
1033
                        }
1034
1035
                        $begin_date = $fiscal_period_start < $start_date && $start_date <= $fiscal_period_end ? $start_date : $fiscal_period_start;
1036
                        $end_date = $fiscal_period_start < $finish_date && $finish_date <= $fiscal_period_end ? $finish_date : $fiscal_period_end;
1037
                        if ($fields['duration_type'] == 2) { // Daily
1038
                            $depreciation_ht = $period_amount;
1039
                        } elseif ($fields['duration_type'] == 1) { // Monthly
1040
                            $nb_days = min($nb_days_in_month, num_between_day($begin_date, $end_date, 1));
1041
                            if ($nb_days >= 28) {
1042
                                $date_temp = dol_getdate($begin_date);
1043
                                if ($date_temp['mon'] == 2) {
1044
                                    $nb_days = 30;
1045
                                }
1046
                            }
1047
                            $depreciation_ht = (float) price2num($period_amount * $nb_days / $nb_days_in_month, 'MT');
1048
                        } else { // Annually
1049
                            $nb_days = min($nb_days_in_year, num_between_day($begin_date, $end_date, 1));
1050
                            $depreciation_ht = (float) price2num($period_amount * $nb_days / $nb_days_in_year, 'MT');
1051
                        }
1052
1053
                        if ($fiscal_period_start <= $depreciation_date_end && $depreciation_date_end <= $fiscal_period_end) { // last period
1054
                            $depreciation_ht = (float) price2num($depreciation_amount - $cumulative_depreciation_ht, 'MT');
1055
                            $cumulative_depreciation_ht = $depreciation_amount;
1056
                        } else {
1057
                            $cumulative_depreciation_ht += $depreciation_ht;
1058
                        }
1059
1060
                        $result = $this->addDepreciationLine($mode_key, $ref, $fiscal_period_end, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit);
1061
                        if ($result < 0) {
1062
                            $error++;
1063
                            break;
1064
                        }
1065
                    }
1066
1067
                    // Next fiscal period (+1 day/month/year)
1068
                    $fiscal_period_start = dol_time_plus_duree($fiscal_period_end, 1, 'd');
1069
                    if ($fields['duration_type'] == 2) { // Daily
1070
                        $fiscal_period_end = $fiscal_period_start;
1071
                    } elseif ($fields['duration_type'] == 1) { // Monthly
1072
                        $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'm'), -1, 'd');
1073
                    } else { // Annually
1074
                        $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'y'), -1, 'd');
1075
                    }
1076
                    $last_period_date = $disposal_date !== "" && $disposal_date < $depreciation_date_end ? $disposal_date : $depreciation_date_end;
1077
                } while ($fiscal_period_start < $last_period_date);
1078
1079
                if ($error) {
1080
                    break;
1081
                }
1082
            }
1083
        }
1084
1085
        if ($error) {
1086
            $this->db->rollback();
1087
            return -1;
1088
        } else {
1089
            $this->db->commit();
1090
            return 1;
1091
        }
1092
    }
1093
1094
    /**
1095
     * Set last cumulative depreciation for each mode
1096
     *
1097
     * @param   int     $asset_depreciation_id      Asset depreciation line ID
1098
     * @return  int                                 Return integer <0 if KO, >0 if OK
1099
     */
1100
    public function setLastCumulativeDepreciation($asset_depreciation_id)
1101
    {
1102
        global $langs;
1103
        $langs->load('assets');
1104
1105
        // Clean parameters
1106
        $asset_depreciation_id = $asset_depreciation_id > 0 ? $asset_depreciation_id : 0;
1107
1108
        // Check parameters
1109
        $error = 0;
1110
        if (empty($asset_depreciation_id)) {
1111
            $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetDepreciation") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')');
1112
            $error++;
1113
        }
1114
        if ($error) {
1115
            return -1;
1116
        }
1117
1118
        $this->db->begin();
1119
1120
        require_once constant('DOL_DOCUMENT_ROOT') . '/asset/class/assetdepreciationoptions.class.php';
1121
        $options = new AssetDepreciationOptions($this->db);
1122
1123
        // Get last depreciation lines save in bookkeeping
1124
        //-----------------------------------------------------
1125
        $sql = "SELECT fk_asset, depreciation_mode, cumulative_depreciation_ht";
1126
        $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation";
1127
        $sql .= " WHERE rowid = " . (int) $asset_depreciation_id;
1128
        $resql = $this->db->query($sql);
1129
        if (!$resql) {
1130
            $this->errors[] = $langs->trans('AssetErrorFetchCumulativeDepreciation') . ': ' . $this->db->lasterror();
1131
            $error++;
1132
        } else {
1133
            if ($obj = $this->db->fetch_object($resql)) {
1134
                $mode_key = $obj->depreciation_mode;
1135
                if (!empty($options->deprecation_options_fields[$mode_key])) {
1136
                    $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table'];
1137
                    $sql .= " SET total_amount_last_depreciation_ht = " . $obj->cumulative_depreciation_ht;
1138
                    $sql .= " WHERE fk_asset = " . (int) $obj->fk_asset;
1139
                    $resql = $this->db->query($sql);
1140
                    if (!$resql) {
1141
                        $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror();
1142
                        $error++;
1143
                    }
1144
                }
1145
            }
1146
        }
1147
1148
        if ($error) {
1149
            $this->db->rollback();
1150
            return -1;
1151
        } else {
1152
            $this->db->commit();
1153
            return 1;
1154
        }
1155
    }
1156
1157
    /**
1158
     *  Set dispose status
1159
     *
1160
     *  @param  User    $user                       Object user that dispose
1161
     *  @param  int     $disposal_invoice_id        Disposal invoice ID
1162
     *  @param  int     $notrigger                  1=Does not execute triggers, 0=Execute triggers
1163
     *  @return int                                 Return integer <0 if KO, 0=Nothing done, >0 if OK
1164
     */
1165
    public function dispose($user, $disposal_invoice_id, $notrigger = 0)
1166
    {
1167
        global $conf, $langs;
1168
1169
        // Protection
1170
        if ($this->status != self::STATUS_DRAFT || $this->status == self::STATUS_DISPOSED) {
1171
            return 0;
1172
        }
1173
1174
        $this->db->begin();
1175
1176
        $required_fields = array('disposal_date', 'disposal_date', 'fk_disposal_type');
1177
        foreach ($required_fields as $field) {
1178
            $this->fields[$field]['notnull'] = 1;
1179
        }
1180
        $result = $this->update($user, 1);
1181
        foreach ($required_fields as $field) {
1182
            $this->fields[$field]['notnull'] = 0;
1183
        }
1184
        if ($result > 0) {
1185
            if ($disposal_invoice_id > 0) {
1186
                $this->add_object_linked('facture', $disposal_invoice_id);
1187
            }
1188
            $result = $this->setStatusCommon($user, self::STATUS_DISPOSED, $notrigger, 'ASSET_DISPOSED');
1189
        }
1190
        if ($result > 0) {
1191
            $result = $this->calculationDepreciation();
1192
        }
1193
1194
        if ($result < 0) {
1195
            $this->db->rollback();
1196
        } else {
1197
            $this->db->commit();
1198
        }
1199
1200
        // Define output language
1201
        if ($result > 0 && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1202
            if (method_exists($this, 'generateDocument')) {
1203
                global $hidedetails, $hidedesc, $hideref;
1204
                $outputlangs = $langs;
1205
                $newlang = '';
1206
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1207
                    $newlang = GETPOST('lang_id', 'aZ09');
1208
                }
1209
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1210
                    $newlang = $this->thirdparty->default_lang;
1211
                }
1212
                if (!empty($newlang)) {
1213
                    $outputlangs = new Translate("", $conf);
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Asset\Classes\Translate was not found. Did you mean Translate? If so, make sure to prefix the type with \.
Loading history...
1214
                    $outputlangs->setDefaultLang($newlang);
1215
                }
1216
                $model = $this->model_pdf;
1217
                $ret = $this->fetch($this->id); // Reload to get new records
1218
1219
                $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
0 ignored issues
show
Bug introduced by
The method generateDocument() does not exist on Dolibarr\Code\Asset\Classes\Asset. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1219
                $this->/** @scrutinizer ignore-call */ 
1220
                       generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
Loading history...
1220
            }
1221
        }
1222
1223
        return $result;
1224
    }
1225
1226
    /**
1227
     *  Set back to validated status
1228
     *
1229
     *  @param  User    $user           Object user that modify
1230
     *  @param  int     $notrigger      1=Does not execute triggers, 0=Execute triggers
1231
     *  @return int                     Return integer <0 if KO, 0=Nothing done, >0 if OK
1232
     */
1233
    public function reopen($user, $notrigger = 0)
1234
    {
1235
        global $conf, $langs;
1236
1237
        // Protection
1238
        if ($this->status != self::STATUS_DISPOSED || $this->status == self::STATUS_DRAFT) {
1239
            return 0;
1240
        }
1241
1242
1243
        $this->db->begin();
1244
1245
        $this->disposal_date = null;
1246
        $this->disposal_amount_ht = null;
1247
        $this->fk_disposal_type = null;
1248
        $this->disposal_depreciated = null;
1249
        $this->disposal_subject_to_vat = null;
1250
        $result = $this->update($user, 1);
1251
        if ($result > 0) {
1252
            $this->deleteObjectLinked(null, 'facture');
1253
            $result = $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'ASSET_REOPEN');
1254
        }
1255
        if ($result > 0) {
1256
            $result = $this->calculationDepreciation();
1257
        }
1258
1259
        if ($result < 0) {
1260
            $this->db->rollback();
1261
        } else {
1262
            $this->db->commit();
1263
        }
1264
1265
        // Define output language
1266
        if ($result > 0 && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1267
            if (method_exists($this, 'generateDocument')) {
1268
                global $hidedetails, $hidedesc, $hideref;
1269
                $outputlangs = $langs;
1270
                $newlang = '';
1271
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1272
                    $newlang = GETPOST('lang_id', 'aZ09');
1273
                }
1274
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1275
                    $newlang = $this->thirdparty->default_lang;
1276
                }
1277
                if (!empty($newlang)) {
1278
                    $outputlangs = new Translate("", $conf);
1279
                    $outputlangs->setDefaultLang($newlang);
1280
                }
1281
                $model = $this->model_pdf;
1282
                $ret = $this->fetch($this->id); // Reload to get new records
1283
1284
                $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1285
            }
1286
        }
1287
1288
        return $result;
1289
    }
1290
1291
    /**
1292
     *  Return a link to the object card (with optionally the picto)
1293
     *
1294
     * @param   int     $withpicto                  Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
1295
     * @param   string  $option                     On what the link point to ('nolink', ...)
1296
     * @param   int     $maxlen                     Max length of name
1297
     * @param   int     $notooltip                  1=Disable tooltip
1298
     * @param   string  $morecss                    Add more css on link
1299
     * @param   int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
1300
     * @return  string                              String with URL
1301
     */
1302
    public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1303
    {
1304
        global $db, $conf, $langs, $hookmanager;
1305
        global $dolibarr_main_authentication, $dolibarr_main_demo;
1306
        global $menumanager;
1307
1308
        if (!empty($conf->dol_no_mouse_hover)) {
1309
            $notooltip = 1; // Force disable tooltips
1310
        }
1311
1312
        $result = '';
1313
1314
        $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Asset") . '</u>';
1315
        if (isset($this->status)) {
1316
            $label .= ' ' . $this->getLibStatut(5);
1317
        }
1318
        $label .= '<br>';
1319
        $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
1320
1321
        $url = dol_buildpath('/asset/card.php', 1) . '?id=' . $this->id;
1322
1323
        if ($option != 'nolink') {
1324
            // Add param to save lastsearch_values or not
1325
            $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1326
            if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1327
                $add_save_lastsearch_values = 1;
1328
            }
1329
            if ($add_save_lastsearch_values) {
1330
                $url .= '&save_lastsearch_values=1';
1331
            }
1332
        }
1333
1334
        $linkclose = '';
1335
        if (empty($notooltip)) {
1336
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1337
                $label = $langs->trans("ShowAsset");
1338
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
1339
            }
1340
            $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
1341
            $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
1342
        } else {
1343
            $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
1344
        }
1345
1346
        if ($option == 'nolink') {
1347
            $linkstart = '<span';
1348
        } else {
1349
            $linkstart = '<a href="' . $url . '"';
1350
        }
1351
        $linkstart .= $linkclose . '>';
1352
        if ($option == 'nolink') {
1353
            $linkend = '</span>';
1354
        } else {
1355
            $linkend = '</a>';
1356
        }
1357
1358
        $result .= $linkstart;
1359
1360
        if (empty($this->showphoto_on_popup)) {
1361
            if ($withpicto) {
1362
                $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);
1363
            }
1364
        } else {
1365
            if ($withpicto) {
1366
                require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
1367
1368
                list($class, $module) = explode('@', $this->picto);
1369
                $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
1370
                $filearray = dol_dir_list($upload_dir, "files");
1371
                $filename = $filearray[0]['name'];
1372
                if (!empty($filename)) {
1373
                    $pospoint = strpos($filearray[0]['name'], '.');
1374
1375
                    $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
1376
                    if (!getDolGlobalString(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
1377
                        $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo' . $module . '" alt="No photo" border="0" src="' . constant('BASE_URL') . '/viewimage.php?modulepart=' . $module . '&entity=' . $conf->entity . '&file=' . urlencode($pathtophoto) . '"></div></div>';
1378
                    } else {
1379
                        $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="' . constant('BASE_URL') . '/viewimage.php?modulepart=' . $module . '&entity=' . $conf->entity . '&file=' . urlencode($pathtophoto) . '"></div>';
1380
                    }
1381
1382
                    $result .= '</div>';
1383
                } else {
1384
                    $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);
1385
                }
1386
            }
1387
        }
1388
1389
        if ($withpicto != 2) {
1390
            $name = $this->ref;
1391
            if ($option == 'label') {
1392
                $name = $this->label;
1393
            } elseif ($option == 'with_label') {
1394
                $name .= ' - ' . $this->label;
1395
            }
1396
            $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name);
1397
        }
1398
1399
        $result .= $linkend;
1400
        //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1401
1402
        global $action;
1403
        $hookmanager->initHooks(array($this->element . 'dao'));
1404
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1405
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1406
        if ($reshook > 0) {
1407
            $result = $hookmanager->resPrint;
1408
        } else {
1409
            $result .= $hookmanager->resPrint;
1410
        }
1411
        return $result;
1412
    }
1413
1414
    /**
1415
     *  Return the label of the status
1416
     *
1417
     *  @param  int     $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
1418
     *  @return string                 Label of status
1419
     */
1420
    public function getLabelStatus($mode = 0)
1421
    {
1422
        return $this->LibStatut($this->status, $mode);
1423
    }
1424
1425
    /**
1426
     *  Return the label of the status
1427
     *
1428
     *  @param  int     $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
1429
     *  @return string                 Label of status
1430
     */
1431
    public function getLibStatut($mode = 0)
1432
    {
1433
        return $this->LibStatut($this->status, $mode);
1434
    }
1435
1436
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1437
    /**
1438
     *  Return the status
1439
     *
1440
     *  @param  int     $status        Id status
1441
     *  @param  int     $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
1442
     *  @return string                 Label of status
1443
     */
1444
    public function LibStatut($status, $mode = 0)
1445
    {
1446
		// phpcs:enable
1447
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1448
            global $langs;
1449
            //$langs->load("assets");
1450
            $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInProgress');
1451
            $this->labelStatus[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed');
1452
            $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInProgress');
1453
            $this->labelStatusShort[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed');
1454
        }
1455
1456
        $statusType = 'status4';
1457
        if ($status == self::STATUS_DISPOSED) {
1458
            $statusType = 'status6';
1459
        }
1460
1461
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
1462
    }
1463
1464
    /**
1465
     *  Load the info information in the object
1466
     *
1467
     *  @param  int     $id       Id of object
1468
     *  @return void
1469
     */
1470
    public function info($id)
1471
    {
1472
        $sql = "SELECT rowid, date_creation as datec, tms as datem,";
1473
        $sql .= " fk_user_creat, fk_user_modif";
1474
        $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element . " as t";
1475
        $sql .= " WHERE t.rowid = " . ((int) $id);
1476
1477
        $result = $this->db->query($sql);
1478
        if ($result) {
1479
            if ($this->db->num_rows($result)) {
1480
                $obj = $this->db->fetch_object($result);
1481
                $this->id = $obj->rowid;
1482
1483
                $this->user_creation_id = $obj->fk_user_creat;
1484
                $this->user_modification_id = $obj->fk_user_modif;
1485
                $this->date_creation     = $this->db->jdate($obj->datec);
1486
                $this->date_modification = $this->db->jdate($obj->datem);
1487
            }
1488
1489
            $this->db->free($result);
1490
        } else {
1491
            dol_print_error($this->db);
1492
        }
1493
    }
1494
1495
    /**
1496
     * Initialise object with example values
1497
     * Id must be 0 if object instance is a specimen
1498
     *
1499
     * @return int
1500
     */
1501
    public function initAsSpecimen()
1502
    {
1503
        // Set here init that are not commonf fields
1504
        // $this->property1 = ...
1505
        // $this->property2 = ...
1506
1507
        return $this->initAsSpecimenCommon();
1508
    }
1509
1510
    /**
1511
     *  Create an array of lines
1512
     *
1513
     *  @return array|int       array of lines if OK, <0 if KO
1514
     */
1515
    public function getLinesArray()
1516
    {
1517
        $this->lines = array();
1518
1519
        return $this->lines;
1520
    }
1521
1522
    /**
1523
     *  Returns the reference to the following non used object depending on the active numbering module.
1524
     *
1525
     *  @return string              Object free reference
1526
     */
1527
    public function getNextNumRef()
1528
    {
1529
        global $langs, $conf;
1530
        $langs->load("assets");
1531
1532
        if (!getDolGlobalString('ASSET_ASSET_ADDON')) {
1533
            $conf->global->ASSET_ASSET_ADDON = 'mod_asset_standard';
1534
        }
1535
1536
        if (getDolGlobalString('ASSET_ASSET_ADDON')) {
1537
            $mybool = false;
1538
1539
            $file = getDolGlobalString('ASSET_ASSET_ADDON') . ".php";
1540
            $classname = getDolGlobalString('ASSET_ASSET_ADDON');
1541
1542
            // Include file with class
1543
            $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1544
            foreach ($dirmodels as $reldir) {
1545
                $dir = dol_buildpath($reldir . "core/modules/asset/");
1546
1547
                // Load file with numbering class (if found)
1548
                $mybool = ((bool) @include_once $dir . $file) || $mybool;
1549
            }
1550
1551
            if ($mybool === false) {
1552
                dol_print_error(null, "Failed to include file " . $file);
1553
                return '';
1554
            }
1555
1556
            if (class_exists($classname)) {
1557
                $obj = new $classname();
1558
                $numref = $obj->getNextValue($this);
1559
1560
                if ($numref != '' && $numref != '-1') {
1561
                    return $numref;
1562
                } else {
1563
                    $this->error = $obj->error;
1564
                    //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1565
                    return "";
1566
                }
1567
            } else {
1568
                print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1569
                return "";
1570
            }
1571
        } else {
1572
            print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1573
            return "";
1574
        }
1575
    }
1576
}
1577