Passed
Push — master ( 65bdac...4e88da )
by Alxarafe
32:38
created

Form::select_thirdparty_list()   F

Complexity

Conditions 58
Paths > 20000

Size

Total Lines 163
Code Lines 113

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 58
eloc 113
nc 15079680
nop 13
dl 0
loc 163
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (c) 2002-2007  Rodolphe Quiedeville    <[email protected]>
3
 * Copyright (C) 2004-2012  Laurent Destailleur     <[email protected]>
4
 * Copyright (C) 2004       Benoit Mortier          <[email protected]>
5
 * Copyright (C) 2004       Sebastien Di Cintio     <[email protected]>
6
 * Copyright (C) 2004       Eric Seigne             <[email protected]>
7
 * Copyright (C) 2005-2017  Regis Houssin           <[email protected]>
8
 * Copyright (C) 2006       Andre Cianfarani        <[email protected]>
9
 * Copyright (C) 2006       Marc Barilley/Ocebo     <[email protected]>
10
 * Copyright (C) 2007       Franky Van Liedekerke   <[email protected]>
11
 * Copyright (C) 2007       Patrick Raguin          <[email protected]>
12
 * Copyright (C) 2010       Juanjo Menent           <[email protected]>
13
 * Copyright (C) 2010-2014  Philippe Grand          <[email protected]>
14
 * Copyright (C) 2011       Herve Prot              <[email protected]>
15
 * Copyright (C) 2012-2016  Marcos García           <[email protected]>
16
 * Copyright (C) 2012       Cedric Salvador         <[email protected]>
17
 * Copyright (C) 2012-2015  Raphaël Doursenaud      <[email protected]>
18
 * Copyright (C) 2014       Alexandre Spangaro      <[email protected]>
19
 * Copyright (C) 2018       Ferran Marcet           <[email protected]>
20
 * Copyright (C) 2018       Frédéric France         <[email protected]>
21
 * Copyright (C) 2018       Nicolas ZABOURI	        <[email protected]>
22
 * Copyright (C) 2018       Christophe Battarel     <[email protected]>
23
 * Copyright (C) 2018       Josep Lluis Amador      <[email protected]>
24
 * Copyright (C) 2018-2019  Alxarafe                <[email protected]>
25
 *
26
 * This program is free software; you can redistribute it and/or modify
27
 * it under the terms of the GNU General Public License as published by
28
 * the Free Software Foundation; either version 3 of the License, or
29
 * (at your option) any later version.
30
 *
31
 * This program is distributed in the hope that it will be useful,
32
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34
 * GNU General Public License for more details.
35
 *
36
 * You should have received a copy of the GNU General Public License
37
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38
 */
39
namespace Alixar\Base;
40
41
/**
42
 * 	\file       htdocs/core/class/html.form.class.php
43
 *  \ingroup    core
44
 * 	\brief      File of class with all html predefined components
45
 */
46
47
/**
48
 * 	Class to manage generation of HTML components
49
 * 	Only common components must be here.
50
 *
51
 *  TODO Merge all function load_cache_* and loadCache* (except load_cache_vatrates) into one generic function loadCacheTable
52
 */
53
class Form
54
{
55
56
    /**
57
     * @var DoliDB Database handler.
58
     */
59
    // public $db;
60
61
    /**
62
     * @var string Error code (or message)
63
     */
64
    public $error = '';
65
66
    /**
67
     * @var string[]    Array of error strings
68
     */
69
    public $errors = array();
70
    public $num;
71
    // Cache arrays
72
    public $cache_types_paiements = array();
73
    public $cache_conditions_paiements = array();
74
    public $cache_availability = array();
75
    public $cache_demand_reason = array();
76
    public $cache_types_fees = array();
77
    public $cache_vatrates = array();
78
79
    /**
80
     * Constructor
81
     *
82
     * @param		DoliDB		$db      Database handler
0 ignored issues
show
Bug introduced by
The type Alixar\Base\DoliDB was not found. Did you mean DoliDB? If so, make sure to prefix the type with \.
Loading history...
83
     */
84
    public function __construct()
85
    {
86
        // $this->db = $db;
87
    }
88
89
    /**
90
     * Output key field for an editable field
91
     *
92
     * @param   string	$text			Text of label or key to translate
93
     * @param   string	$htmlname		Name of select field ('edit' prefix will be added)
94
     * @param   string	$preselected    Value to show/edit (not used in this function)
95
     * @param	object	$object			Object
96
     * @param	boolean	$perm			Permission to allow button to edit parameter. Set it to 0 to have a not edited field.
97
     * @param	string	$typeofdata		Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...)
98
     * @param	string	$moreparam		More param to add on a href URL.
99
     * @param   int     $fieldrequired  1 if we want to show field as mandatory using the "fieldrequired" CSS.
100
     * @param   int     $notabletag     1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' '
101
     * @param	string	$paramid		Key of parameter for id ('id', 'socid')
102
     * @return	string					HTML edit field
103
     */
104
    function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata = 'string', $moreparam = '', $fieldrequired = 0, $notabletag = 0, $paramid = 'id')
105
    {
106
        global $conf, $langs;
107
108
        $ret = '';
109
110
        // TODO change for compatibility
111
        if (!empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && !preg_match('/^select;/', $typeofdata)) {
112
            if (!empty($perm)) {
113
                $tmp = explode(':', $typeofdata);
114
                $ret .= '<div class="editkey_' . $tmp[0] . (!empty($tmp[1]) ? ' ' . $tmp[1] : '') . '" id="' . $htmlname . '">';
115
                if ($fieldrequired)
116
                    $ret .= '<span class="fieldrequired">';
117
                $ret .= $langs->trans($text);
118
                if ($fieldrequired)
119
                    $ret .= '</span>';
120
                $ret .= '</div>' . "\n";
121
            }
122
            else {
123
                if ($fieldrequired)
124
                    $ret .= '<span class="fieldrequired">';
125
                $ret .= $langs->trans($text);
126
                if ($fieldrequired)
127
                    $ret .= '</span>';
128
            }
129
        }
130
        else {
131
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
132
                $ret .= '<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
133
            }
134
            if ($fieldrequired) {
135
                $ret .= '<span class="fieldrequired">';
136
            }
137
            $ret .= $langs->trans($text);
138
            if ($fieldrequired) {
139
                $ret .= '</span>';
140
            }
141
            if (!empty($notabletag)) {
142
                $ret .= ' ';
143
            }
144
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
145
                $ret .= '</td>';
146
            }
147
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
148
                $ret .= '<td align="right">';
149
            }
150
            if ($htmlname && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
151
                $ret .= '<a href="' . $_SERVER["PHP_SELF"] . '?action=edit' . $htmlname . '&amp;' . $paramid . '=' . $object->id . $moreparam . '">' . img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1)) . '</a>';
152
            }
153
            if (!empty($notabletag) && $notabletag == 1) {
154
                $ret .= ' : ';
155
            }
156
            if (!empty($notabletag) && $notabletag == 3) {
157
                $ret .= ' ';
158
            }
159
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
160
                $ret .= '</td>';
161
            }
162
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
163
                $ret .= '</tr></table>';
164
            }
165
        }
166
167
        return $ret;
168
    }
169
170
    /**
171
     * Output value of a field for an editable field
172
     *
173
     * @param	string	$text			Text of label (not used in this function)
174
     * @param	string	$htmlname		Name of select field
175
     * @param	string	$value			Value to show/edit
176
     * @param	object	$object			Object
177
     * @param	boolean	$perm			Permission to allow button to edit parameter
178
     * @param	string	$typeofdata		Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols%', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datepickerhour', 'ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols', 'select:xxx'...)
179
     * @param	string	$editvalue		When in edit mode, use this value as $value instead of value (for example, you can provide here a formated price instead of value). Use '' to use same than $value
180
     * @param	object	$extObject		External object
181
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
182
     * @param	string	$moreparam		More param to add on the form action href URL
183
     * @param   int     $notabletag     Do no output table tags
184
     * @param	string	$formatfunc		Call a specific function to output field
185
     * @param	string	$paramid		Key of parameter for id ('id', 'socid')
186
     * @return  string					HTML edit field
187
     */
188
    function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 0, $formatfunc = '', $paramid = 'id')
189
    {
190
        global $conf, $langs, $db;
191
192
        $ret = '';
193
194
        // Check parameters
195
        if (empty($typeofdata))
196
            return 'ErrorBadParameter';
197
198
        // When option to edit inline is activated
199
        if (!empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && !preg_match('/^select;|datehourpicker/', $typeofdata)) { // TODO add jquery timepicker
200
            $ret .= $this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg);
201
        } else {
202
            if (GETPOST('action', 'aZ09') == 'edit' . $htmlname) {
203
                $ret .= "\n";
204
                $ret .= '<form method="post" action="' . $_SERVER["PHP_SELF"] . ($moreparam ? '?' . $moreparam : '') . '">';
205
                $ret .= '<input type="hidden" name="action" value="set' . $htmlname . '">';
206
                $ret .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
207
                $ret .= '<input type="hidden" name="' . $paramid . '" value="' . $object->id . '">';
208
                if (empty($notabletag))
209
                    $ret .= '<table class="nobordernopadding centpercent" cellpadding="0" cellspacing="0">';
210
                if (empty($notabletag))
211
                    $ret .= '<tr><td>';
212
                if (preg_match('/^(string|email)/', $typeofdata)) {
213
                    $tmp = explode(':', $typeofdata);
214
                    $ret .= '<input type="text" id="' . $htmlname . '" name="' . $htmlname . '" value="' . ($editvalue ? $editvalue : $value) . '"' . ($tmp[1] ? ' size="' . $tmp[1] . '"' : '') . '>';
215
                } else if (preg_match('/^(numeric|amount)/', $typeofdata)) {
216
                    $tmp = explode(':', $typeofdata);
217
                    $valuetoshow = price2num($editvalue ? $editvalue : $value);
218
                    $ret .= '<input type="text" id="' . $htmlname . '" name="' . $htmlname . '" value="' . ($valuetoshow != '' ? price($valuetoshow) : '') . '"' . ($tmp[1] ? ' size="' . $tmp[1] . '"' : '') . '>';
219
                } else if (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata)) {
220
                    $tmp = explode(':', $typeofdata);
221
                    $cols = $tmp[2];
222
                    $morealt = '';
223
                    if (preg_match('/%/', $cols)) {
224
                        $morealt = ' style="width: ' . $cols . '"';
225
                        $cols = '';
226
                    }
227
228
                    $valuetoshow = ($editvalue ? $editvalue : $value);
229
230
                    $ret .= '<textarea id="' . $htmlname . '" name="' . $htmlname . '" wrap="soft" rows="' . ($tmp[1] ? $tmp[1] : '20') . '"' . ($cols ? ' cols="' . $cols . '"' : 'class="quatrevingtpercent"') . $morealt . '">';
231
                    $ret .= dol_string_neverthesehtmltags($valuetoshow, array('textarea'));
232
                    $ret .= '</textarea>';
233
                } else if ($typeofdata == 'day' || $typeofdata == 'datepicker') {
234
                    $ret .= $this->selectDate($value, $htmlname, 0, 0, 1, 'form' . $htmlname, 1, 0);
235
                } else if ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') {
236
                    $ret .= $this->selectDate($value, $htmlname, 1, 1, 1, 'form' . $htmlname, 1, 0);
237
                } else if (preg_match('/^select;/', $typeofdata)) {
238
                    $arraydata = explode(',', preg_replace('/^select;/', '', $typeofdata));
239
                    foreach ($arraydata as $val) {
240
                        $tmp = explode(':', $val);
241
                        $arraylist[$tmp[0]] = $tmp[1];
242
                    }
243
                    $ret .= $this->selectarray($htmlname, $arraylist, $value);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $arraylist seems to be defined by a foreach iteration on line 239. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
244
                } else if (preg_match('/^ckeditor/', $typeofdata)) {
245
                    $tmp = explode(':', $typeofdata);  // Example: ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols
246
                    require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
247
                    $doleditor = new DolEditor($htmlname, ($editvalue ? $editvalue : $value), ($tmp[2] ? $tmp[2] : ''), ($tmp[3] ? $tmp[3] : '100'), ($tmp[1] ? $tmp[1] : 'dolibarr_notes'), 'In', ($tmp[5] ? $tmp[5] : 0), true, true, ($tmp[6] ? $tmp[6] : '20'), ($tmp[7] ? $tmp[7] : '100'));
0 ignored issues
show
Bug introduced by
The type Alixar\Base\DolEditor was not found. Did you mean DolEditor? If so, make sure to prefix the type with \.
Loading history...
248
                    $ret .= $doleditor->Create(1);
249
                }
250
                if (empty($notabletag))
251
                    $ret .= '</td>';
252
253
                if (empty($notabletag))
254
                    $ret .= '<td align="left">';
255
                //else $ret.='<div class="clearboth"></div>';
256
                $ret .= '<input type="submit" class="button' . (empty($notabletag) ? '' : ' ') . '" name="modify" value="' . $langs->trans("Modify") . '">';
257
                if (preg_match('/ckeditor|textarea/', $typeofdata) && empty($notabletag))
258
                    $ret .= '<br>' . "\n";
259
                $ret .= '<input type="submit" class="button' . (empty($notabletag) ? '' : ' ') . '" name="cancel" value="' . $langs->trans("Cancel") . '">';
260
                if (empty($notabletag))
261
                    $ret .= '</td>';
262
263
                if (empty($notabletag))
264
                    $ret .= '</tr></table>' . "\n";
265
                $ret .= '</form>' . "\n";
266
            }
267
            else {
268
                if (preg_match('/^(email)/', $typeofdata))
269
                    $ret .= dol_print_email($value, 0, 0, 0, 0, 1);
270
                elseif (preg_match('/^(amount|numeric)/', $typeofdata))
271
                    $ret .= ($value != '' ? price($value, '', $langs, 0, -1, -1, $conf->currency) : '');
272
                elseif (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata))
273
                    $ret .= dol_htmlentitiesbr($value);
274
                elseif ($typeofdata == 'day' || $typeofdata == 'datepicker')
275
                    $ret .= dol_print_date($value, 'day');
276
                elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker')
277
                    $ret .= dol_print_date($value, 'dayhour');
278
                else if (preg_match('/^select;/', $typeofdata)) {
279
                    $arraydata = explode(',', preg_replace('/^select;/', '', $typeofdata));
280
                    foreach ($arraydata as $val) {
281
                        $tmp = explode(':', $val);
282
                        $arraylist[$tmp[0]] = $tmp[1];
283
                    }
284
                    $ret .= $arraylist[$value];
285
                } else if (preg_match('/^ckeditor/', $typeofdata)) {
286
                    $tmpcontent = dol_htmlentitiesbr($value);
287
                    if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
288
                        $firstline = preg_replace('/<br>.*/', '', $tmpcontent);
289
                        $firstline = preg_replace('/[\n\r].*/', '', $firstline);
290
                        $tmpcontent = $firstline . ((strlen($firstline) != strlen($tmpcontent)) ? '...' : '');
291
                    }
292
                    $ret .= $tmpcontent;
293
                } else
294
                    $ret .= $value;
295
296
                if ($formatfunc && method_exists($object, $formatfunc)) {
297
                    $ret = $object->$formatfunc($ret);
298
                }
299
            }
300
        }
301
        return $ret;
302
    }
303
304
    /**
305
     * Output edit in place form
306
     *
307
     * @param	object	$object			Object
308
     * @param	string	$value			Value to show/edit
309
     * @param	string	$htmlname		DIV ID (field name)
310
     * @param	int		$condition		Condition to edit
311
     * @param	string	$inputType		Type of input ('string', 'numeric', 'datepicker' ('day' do not work, don't know why), 'textarea:rows:cols', 'ckeditor:dolibarr_zzz:width:height:?:1:rows:cols', 'select:xxx')
312
     * @param	string	$editvalue		When in edit mode, use this value as $value instead of value
313
     * @param	object	$extObject		External object
314
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
315
     * @return	string   		      	HTML edit in place
316
     */
317
    private function editInPlace($object, $value, $htmlname, $condition, $inputType = 'textarea', $editvalue = null, $extObject = null, $custommsg = null)
318
    {
319
        global $conf;
320
321
        $out = '';
322
323
        // Check parameters
324
        if (preg_match('/^text/', $inputType))
325
            $value = dol_nl2br($value);
326
        else if (preg_match('/^numeric/', $inputType))
327
            $value = price($value);
328
        else if ($inputType == 'day' || $inputType == 'datepicker')
329
            $value = dol_print_date($value, 'day');
330
331
        if ($condition) {
332
            $element = false;
333
            $table_element = false;
334
            $fk_element = false;
335
            $loadmethod = false;
336
            $savemethod = false;
337
            $ext_element = false;
338
            $button_only = false;
339
            $inputOption = '';
340
341
            if (is_object($object)) {
342
                $element = $object->element;
343
                $table_element = $object->table_element;
344
                $fk_element = $object->id;
345
            }
346
347
            if (is_object($extObject)) {
348
                $ext_element = $extObject->element;
349
            }
350
351
            if (preg_match('/^(string|email|numeric)/', $inputType)) {
352
                $tmp = explode(':', $inputType);
353
                $inputType = $tmp[0];
354
                if (!empty($tmp[1]))
355
                    $inputOption = $tmp[1];
356
                if (!empty($tmp[2]))
357
                    $savemethod = $tmp[2];
358
                $out .= '<input id="width_' . $htmlname . '" value="' . $inputOption . '" type="hidden"/>' . "\n";
359
            }
360
            else if ((preg_match('/^day$/', $inputType)) || (preg_match('/^datepicker/', $inputType)) || (preg_match('/^datehourpicker/', $inputType))) {
361
                $tmp = explode(':', $inputType);
362
                $inputType = $tmp[0];
363
                if (!empty($tmp[1]))
364
                    $inputOption = $tmp[1];
365
                if (!empty($tmp[2]))
366
                    $savemethod = $tmp[2];
367
368
                $out .= '<input id="timestamp" type="hidden"/>' . "\n"; // Use for timestamp format
369
            }
370
            else if (preg_match('/^(select|autocomplete)/', $inputType)) {
371
                $tmp = explode(':', $inputType);
372
                $inputType = $tmp[0];
373
                $loadmethod = $tmp[1];
374
                if (!empty($tmp[2]))
375
                    $savemethod = $tmp[2];
376
                if (!empty($tmp[3]))
377
                    $button_only = true;
378
            }
379
            else if (preg_match('/^textarea/', $inputType)) {
380
                $tmp = explode(':', $inputType);
381
                $inputType = $tmp[0];
382
                $rows = (empty($tmp[1]) ? '8' : $tmp[1]);
383
                $cols = (empty($tmp[2]) ? '80' : $tmp[2]);
384
            } else if (preg_match('/^ckeditor/', $inputType)) {
385
                $tmp = explode(':', $inputType);
386
                $inputType = $tmp[0];
387
                $toolbar = $tmp[1];
388
                if (!empty($tmp[2]))
389
                    $width = $tmp[2];
390
                if (!empty($tmp[3]))
391
                    $heigth = $tmp[3];
392
                if (!empty($tmp[4]))
393
                    $savemethod = $tmp[4];
394
395
                if (!empty($conf->fckeditor->enabled)) {
396
                    $out .= '<input id="ckeditor_toolbar" value="' . $toolbar . '" type="hidden"/>' . "\n";
397
                } else {
398
                    $inputType = 'textarea';
399
                }
400
            }
401
402
            $out .= '<input id="element_' . $htmlname . '" value="' . $element . '" type="hidden"/>' . "\n";
403
            $out .= '<input id="table_element_' . $htmlname . '" value="' . $table_element . '" type="hidden"/>' . "\n";
404
            $out .= '<input id="fk_element_' . $htmlname . '" value="' . $fk_element . '" type="hidden"/>' . "\n";
405
            $out .= '<input id="loadmethod_' . $htmlname . '" value="' . $loadmethod . '" type="hidden"/>' . "\n";
406
            if (!empty($savemethod))
407
                $out .= '<input id="savemethod_' . $htmlname . '" value="' . $savemethod . '" type="hidden"/>' . "\n";
408
            if (!empty($ext_element))
409
                $out .= '<input id="ext_element_' . $htmlname . '" value="' . $ext_element . '" type="hidden"/>' . "\n";
410
            if (!empty($custommsg)) {
411
                if (is_array($custommsg)) {
412
                    if (!empty($custommsg['success']))
413
                        $out .= '<input id="successmsg_' . $htmlname . '" value="' . $custommsg['success'] . '" type="hidden"/>' . "\n";
414
                    if (!empty($custommsg['error']))
415
                        $out .= '<input id="errormsg_' . $htmlname . '" value="' . $custommsg['error'] . '" type="hidden"/>' . "\n";
416
                } else
417
                    $out .= '<input id="successmsg_' . $htmlname . '" value="' . $custommsg . '" type="hidden"/>' . "\n";
418
            }
419
            if ($inputType == 'textarea') {
420
                $out .= '<input id="textarea_' . $htmlname . '_rows" value="' . $rows . '" type="hidden"/>' . "\n";
421
                $out .= '<input id="textarea_' . $htmlname . '_cols" value="' . $cols . '" type="hidden"/>' . "\n";
422
            }
423
            $out .= '<span id="viewval_' . $htmlname . '" class="viewval_' . $inputType . ($button_only ? ' inactive' : ' active') . '">' . $value . '</span>' . "\n";
424
            $out .= '<span id="editval_' . $htmlname . '" class="editval_' . $inputType . ($button_only ? ' inactive' : ' active') . ' hideobject">' . (!empty($editvalue) ? $editvalue : $value) . '</span>' . "\n";
425
        } else {
426
            $out = $value;
427
        }
428
429
        return $out;
430
    }
431
432
    /**
433
     * 	Show a text and picto with tooltip on text or picto.
434
     *  Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip
435
     *
436
     * 	@param	string		$text				Text to show
437
     * 	@param	string		$htmltext			HTML content of tooltip. Must be HTML/UTF8 encoded.
438
     * 	@param	int			$tooltipon			1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2
439
     * 	@param	int			$direction			-1=image is before, 0=no image, 1=image is after
440
     * 	@param	string		$img				Html code for image (use img_xxx() function to get it)
441
     * 	@param	string		$extracss			Add a CSS style to td tags
442
     * 	@param	int			$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
443
     * 	@param	string		$incbefore			Include code before the text
444
     * 	@param	int			$noencodehtmltext	Do not encode into html entity the htmltext
445
     *  @param  string      $tooltiptrigger		''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
446
     *  @param	int			$forcenowrap		Force no wrap between text and picto (works with notabs=2 only)
447
     * 	@return	string							Code html du tooltip (texte+picto)
448
     * 	@see	Use function textwithpicto if you can.
449
     *  TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip
450
     */
451
    function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger = '', $forcenowrap = 0)
452
    {
453
        global $conf;
454
455
        if ($incbefore) {
456
            $text = $incbefore . $text;
457
        }
458
        if (!$htmltext) {
459
            return $text;
460
        }
461
462
        $tag = 'td';
463
        if ($notabs == 2) {
464
            $tag = 'div';
465
        }
466
        if ($notabs == 3) {
467
            $tag = 'span';
468
        }
469
        // Sanitize tooltip
470
        $htmltext = str_replace("\\", "\\\\", $htmltext);
471
        $htmltext = str_replace("\r", "", $htmltext);
472
        $htmltext = str_replace("\n", "", $htmltext);
473
474
        $extrastyle = '';
475
        if ($direction < 0) {
476
            $extracss = ($extracss ? $extracss . ' ' : '') . 'inline-block';
477
            $extrastyle = 'padding: 0px; padding-left: 3px !important;';
478
        }
479
        if ($direction > 0) {
480
            $extracss = ($extracss ? $extracss . ' ' : '') . 'inline-block';
481
            $extrastyle = 'padding: 0px; padding-right: 3px !important;';
482
        }
483
484
        $classfortooltip = 'classfortooltip';
485
486
        $s = '';
487
        $textfordialog = '';
488
489
        if ($tooltiptrigger == '') {
490
            $htmltext = str_replace('"', "&quot;", $htmltext);
491
        } else {
492
            $classfortooltip = 'classfortooltiponclick';
493
            $textfordialog .= '<div style="display: none;" id="idfortooltiponclick_' . $tooltiptrigger . '" class="classfortooltiponclicktext">' . $htmltext . '</div>';
494
        }
495
        if ($tooltipon == 2 || $tooltipon == 3) {
496
            $paramfortooltipimg = ' class="' . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '"';
497
            if ($tooltiptrigger == '') {
498
                $paramfortooltipimg .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on img tag to store tooltip
499
            } else {
500
                $paramfortooltipimg .= ' dolid="' . $tooltiptrigger . '"';
501
            }
502
        } else {
503
            $paramfortooltipimg = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribut to put on td text tag
504
        }
505
        if ($tooltipon == 1 || $tooltipon == 3) {
506
            $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" ';
507
            if ($tooltiptrigger == '') {
508
                $paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on td tag to store tooltip
509
            } else {
510
                $paramfortooltiptd .= ' dolid="' . $tooltiptrigger . '"';
511
            }
512
        } else {
513
            $paramfortooltiptd = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribut to put on td text tag
514
        }
515
        if (empty($notabs)) {
516
            $s .= '<table class="nobordernopadding" summary=""><tr style="height: auto;">';
517
        } elseif ($notabs == 2) {
518
            $s .= '<div class="inline-block' . ($forcenowrap ? ' nowrap' : '') . '">';
519
        }
520
        // Define value if value is before
521
        if ($direction < 0) {
522
            $s .= '<' . $tag . $paramfortooltipimg;
523
            if ($tag == 'td') {
524
                $s .= ' valign="top" width="14"';
525
            }
526
            $s .= '>' . $textfordialog . $img . '</' . $tag . '>';
527
        }
528
        // Use another method to help avoid having a space in value in order to use this value with jquery
529
        // Define label
530
        if ((string) $text != '') {
531
            $s .= '<' . $tag . $paramfortooltiptd . '>' . $text . '</' . $tag . '>';
532
        }
533
        // Define value if value is after
534
        if ($direction > 0) {
535
            $s .= '<' . $tag . $paramfortooltipimg;
536
            if ($tag == 'td') {
537
                $s .= ' valign="middle" width="14"';
538
            }
539
            $s .= '>' . $textfordialog . $img . '</' . $tag . '>';
540
        }
541
        if (empty($notabs)) {
542
            $s .= '</tr></table>';
543
        } elseif ($notabs == 2) {
544
            $s .= '</div>';
545
        }
546
547
        return $s;
548
    }
549
550
    /**
551
     * 	Show a text with a picto and a tooltip on picto
552
     *
553
     * 	@param	string	$text				Text to show
554
     * 	@param  string	$htmltext	     	Content of tooltip
555
     * 	@param	int		$direction			1=Icon is after text, -1=Icon is before text, 0=no icon
556
     * 	@param	string	$type				Type of picto ('info', 'help', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath
557
     *  @param  string	$extracss           Add a CSS style to td, div or span tag
558
     *  @param  int		$noencodehtmltext   Do not encode into html entity the htmltext
559
     *  @param	int		$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
560
     *  @param  string  $tooltiptrigger     ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
561
     *  @param	int		$forcenowrap		Force no wrap between text and picto (works with notabs=2 only)
562
     * 	@return	string						HTML code of text, picto, tooltip
563
     */
564
    function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger = '', $forcenowrap = 0)
565
    {
566
        global $conf, $langs;
567
568
        $alt = '';
569
        if ($tooltiptrigger)
570
            $alt = $langs->transnoentitiesnoconv("ClickToShowHelp");
571
572
        //For backwards compatibility
573
        if ($type == '0')
574
            $type = 'info';
575
        elseif ($type == '1')
576
            $type = 'help';
577
578
        // If info or help with no javascript, show only text
579
        if (empty($conf->use_javascript_ajax)) {
580
            if ($type == 'info' || $type == 'help')
581
                return $text;
582
            else {
583
                $alt = $htmltext;
584
                $htmltext = '';
585
            }
586
        }
587
588
        // If info or help with smartphone, show only text (tooltip hover can't works)
589
        if (!empty($conf->dol_no_mouse_hover) && empty($tooltiptrigger)) {
590
            if ($type == 'info' || $type == 'help')
591
                return $text;
592
        }
593
        // If info or help with smartphone, show only text (tooltip on lick does not works with dialog on smaprtphone)
594
        if (!empty($conf->dol_no_mouse_hover) && !empty($tooltiptrigger)) {
595
            if ($type == 'info' || $type == 'help')
596
                return $text;
597
        }
598
599
        if ($type == 'info')
600
            $img = img_help(0, $alt);
601
        elseif ($type == 'help')
602
            $img = img_help(($tooltiptrigger != '' ? 2 : 1), $alt);
603
        elseif ($type == 'superadmin')
604
            $img = img_picto($alt, 'redstar');
605
        elseif ($type == 'admin')
606
            $img = img_picto($alt, 'star');
607
        elseif ($type == 'warning')
608
            $img = img_warning($alt);
609
        else
610
            $img = img_picto($alt, $type);
611
612
        return $this->textwithtooltip($text, $htmltext, (($tooltiptrigger && !$img) ? 3 : 2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger, $forcenowrap);
613
    }
614
615
    /**
616
     * Generate select HTML to choose massaction
617
     *
618
     * @param	string	$selected		Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default.
619
     * @param	int		$arrayofaction	array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action.
620
     * @param   int     $alwaysvisible  1=select button always visible
621
     * @return	string					Select list
622
     */
623
    function selectMassAction($selected, $arrayofaction, $alwaysvisible = 0)
624
    {
625
        global $conf, $langs, $hookmanager;
626
627
        if (count($arrayofaction) == 0)
628
            return;
629
630
        $disabled = 0;
631
        $ret = '<div class="centpercent center">';
632
        $ret .= '<select class="flat' . (empty($conf->use_javascript_ajax) ? '' : ' hideobject') . ' massaction massactionselect" name="massaction"' . ($disabled ? ' disabled="disabled"' : '') . '>';
633
634
        // Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks.
635
        $parameters = array();
636
        $reshook = $hookmanager->executeHooks('addMoreMassActions', $parameters);    // Note that $action and $object may have been modified by hook
637
        if (empty($reshook)) {
638
            $ret .= '<option value="0"' . ($disabled ? ' disabled="disabled"' : '') . '>-- ' . $langs->trans("SelectAction") . ' --</option>';
639
            foreach ($arrayofaction as $code => $label) {
0 ignored issues
show
Bug introduced by
The expression $arrayofaction of type integer is not traversable.
Loading history...
640
                $ret .= '<option value="' . $code . '"' . ($disabled ? ' disabled="disabled"' : '') . '>' . $label . '</option>';
641
            }
642
        }
643
        $ret .= $hookmanager->resPrint;
644
645
        $ret .= '</select>';
646
        // Warning: if you set submit button to disabled, post using 'Enter' will no more work if there is no another input submit. So we add a hidden button
647
        $ret .= '<input type="submit" name="confirmmassactioninvisible" style="display: none" tabindex="-1">'; // Hidden button BEFORE so it is the one used when we submit with ENTER.
648
        $ret .= '<input type="submit" disabled name="confirmmassaction" class="button' . (empty($conf->use_javascript_ajax) ? '' : ' hideobject') . ' massaction massactionconfirmed" value="' . dol_escape_htmltag($langs->trans("Confirm")) . '">';
649
        $ret .= '</div>';
650
651
        if (!empty($conf->use_javascript_ajax)) {
652
            $ret .= '<!-- JS CODE TO ENABLE mass action select -->
653
    		<script type="text/javascript">
654
        		function initCheckForSelect(mode)	/* mode is 0 during init of page or click all, 1 when we click on 1 checkbox */
655
        		{
656
        			atleastoneselected=0;
657
    	    		jQuery(".checkforselect").each(function( index ) {
658
    	  				/* console.log( index + ": " + $( this ).text() ); */
659
    	  				if ($(this).is(\':checked\')) atleastoneselected++;
660
    	  			});
661
					console.log("initCheckForSelect mode="+mode+" atleastoneselected="+atleastoneselected);
662
    	  			if (atleastoneselected || ' . $alwaysvisible . ')
663
    	  			{
664
    	  				jQuery(".massaction").show();
665
        			    ' . ($selected ? 'if (atleastoneselected) { jQuery(".massactionselect").val("' . $selected . '"); jQuery(".massactionconfirmed").prop(\'disabled\', false); }' : '') . '
666
        			    ' . ($selected ? 'if (! atleastoneselected) { jQuery(".massactionselect").val("0"); jQuery(".massactionconfirmed").prop(\'disabled\', true); } ' : '') . '
667
    	  			}
668
    	  			else
669
    	  			{
670
    	  				jQuery(".massaction").hide();
671
    	            }
672
        		}
673
674
        	jQuery(document).ready(function () {
675
        		initCheckForSelect(0);
676
        		jQuery(".checkforselect").click(function() {
677
        			initCheckForSelect(1);
678
    	  		});
679
    	  		jQuery(".massactionselect").change(function() {
680
        			var massaction = $( this ).val();
681
        			var urlform = $( this ).closest("form").attr("action").replace("#show_files","");
682
        			if (massaction == "builddoc")
683
                    {
684
                        urlform = urlform + "#show_files";
685
    	            }
686
        			$( this ).closest("form").attr("action", urlform);
687
                    console.log("we select a mass action "+massaction+" - "+urlform);
688
        	        /* Warning: if you set submit button to disabled, post using Enter will no more work if there is no other button */
689
        			if ($(this).val() != \'0\')
690
    	  			{
691
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', false);
692
    	  			}
693
    	  			else
694
    	  			{
695
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', true);
696
    	  			}
697
    	        });
698
        	});
699
    		</script>
700
        	';
701
        }
702
703
        return $ret;
704
    }
705
706
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
707
    /**
708
     *  Return combo list of activated countries, into language of user
709
     *
710
     *  @param	string	$selected       	Id or Code or Label of preselected country
711
     *  @param  string	$htmlname       	Name of html select object
712
     *  @param  string	$htmloption     	Options html on select object
713
     *  @param	integer	$maxlength			Max length for labels (0=no limit)
714
     *  @param	string	$morecss			More css class
715
     *  @param	string	$usecodeaskey		''=Use id as key (default), 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key
716
     *  @param	int		$showempty			Show empty choice
717
     *  @param	int		$disablefavorites	1=Disable favorites,
718
     *  @param	int		$addspecialentries	1=Add dedicated entries for group of countries (like 'European Economic Community', ...)
719
     *  @return string           			HTML string with select
720
     */
721
    function select_country($selected = '', $htmlname = 'country_id', $htmloption = '', $maxlength = 0, $morecss = 'minwidth300', $usecodeaskey = '', $showempty = 1, $disablefavorites = 0, $addspecialentries = 0)
722
    {
723
        // phpcs:enable
724
        global $conf, $langs, $mysoc;
725
726
        $langs->load("dict");
727
728
        $out = '';
729
        $countryArray = array();
730
        $favorite = array();
731
        $label = array();
732
        $atleastonefavorite = 0;
733
734
        $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite";
735
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_country";
736
        $sql .= " WHERE active > 0";
737
        //$sql.= " ORDER BY code ASC";
738
739
        dol_syslog(get_class($this) . "::select_country", LOG_DEBUG);
740
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
741
        if ($resql) {
742
            $out .= '<select id="select' . $htmlname . '" class="flat maxwidth200onsmartphone selectcountry' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '" ' . $htmloption . '>';
743
            $num = $this->db->num_rows($resql);
744
            $i = 0;
745
            if ($num) {
746
                $foundselected = false;
747
748
                while ($i < $num) {
749
                    $obj = $this->db->fetch_object($resql);
750
                    $countryArray[$i]['rowid'] = $obj->rowid;
751
                    $countryArray[$i]['code_iso'] = $obj->code_iso;
752
                    $countryArray[$i]['code_iso3'] = $obj->code_iso3;
753
                    $countryArray[$i]['label'] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country" . $obj->code_iso) != "Country" . $obj->code_iso ? $langs->transnoentitiesnoconv("Country" . $obj->code_iso) : ($obj->label != '-' ? $obj->label : ''));
754
                    $countryArray[$i]['favorite'] = $obj->favorite;
755
                    $favorite[$i] = $obj->favorite;
756
                    $label[$i] = dol_string_unaccent($countryArray[$i]['label']);
757
                    $i++;
758
                }
759
760
                if (empty($disablefavorites))
761
                    array_multisort($favorite, SORT_DESC, $label, SORT_ASC, $countryArray);
762
                else
763
                    $countryArray = dol_sort_array($countryArray, 'label');
764
765
                if ($showempty) {
766
                    $out .= '<option value="">&nbsp;</option>' . "\n";
767
                }
768
769
                if ($addspecialentries) { // Add dedicated entries for groups of countries
770
                    //if ($showempty) $out.= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
771
                    $out .= '<option value="special_allnotme"' . ($selected == 'special_allnotme' ? ' selected' : '') . '>' . $langs->trans("CountriesExceptMe", $langs->transnoentitiesnoconv("Country" . $mysoc->country_code)) . '</option>';
772
                    $out .= '<option value="special_eec"' . ($selected == 'special_eec' ? ' selected' : '') . '>' . $langs->trans("CountriesInEEC") . '</option>';
773
                    if ($mysoc->isInEEC())
774
                        $out .= '<option value="special_eecnotme"' . ($selected == 'special_eecnotme' ? ' selected' : '') . '>' . $langs->trans("CountriesInEECExceptMe", $langs->transnoentitiesnoconv("Country" . $mysoc->country_code)) . '</option>';
775
                    $out .= '<option value="special_noteec"' . ($selected == 'special_noteec' ? ' selected' : '') . '>' . $langs->trans("CountriesNotInEEC") . '</option>';
776
                    $out .= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
777
                }
778
779
                foreach ($countryArray as $row) {
780
                    //if (empty($showempty) && empty($row['rowid'])) continue;
781
                    if (empty($row['rowid'])) {
782
                        continue;
783
                    }
784
785
                    if (empty($disablefavorites) && $row['favorite'] && $row['code_iso'])
786
                        $atleastonefavorite++;
787
                    if (empty($row['favorite']) && $atleastonefavorite) {
788
                        $atleastonefavorite = 0;
789
                        $out .= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
790
                    }
791
                    if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label'])) {
792
                        $foundselected = true;
793
                        $out .= '<option value="' . ($usecodeaskey ? ($usecodeaskey == 'code2' ? $row['code_iso'] : $row['code_iso3']) : $row['rowid']) . '" selected>';
794
                    } else {
795
                        $out .= '<option value="' . ($usecodeaskey ? ($usecodeaskey == 'code2' ? $row['code_iso'] : $row['code_iso3']) : $row['rowid']) . '">';
796
                    }
797
                    if ($row['label'])
798
                        $out .= dol_trunc($row['label'], $maxlength, 'middle');
799
                    else
800
                        $out .= '&nbsp;';
801
                    if ($row['code_iso'])
802
                        $out .= ' (' . $row['code_iso'] . ')';
803
                    $out .= '</option>';
804
                }
805
            }
806
            $out .= '</select>';
807
        }
808
        else {
809
            dol_print_error($this->db);
810
        }
811
812
        // Make select dynamic
813
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
814
        $out .= ajax_combobox('select' . $htmlname);
815
816
        return $out;
817
    }
818
819
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
820
    /**
821
     *  Return select list of incoterms
822
     *
823
     *  @param	string	$selected       		Id or Code of preselected incoterm
824
     *  @param	string	$location_incoterms     Value of input location
825
     *  @param	string	$page       			Defined the form action
826
     *  @param  string	$htmlname       		Name of html select object
827
     *  @param  string	$htmloption     		Options html on select object
828
     * 	@param	int		$forcecombo				Force to load all values and output a standard combobox (with no beautification)
829
     *  @param	array	$events					Event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
830
     *  @return string           				HTML string with select and input
831
     */
832
    function select_incoterms($selected = '', $location_incoterms = '', $page = '', $htmlname = 'incoterm_id', $htmloption = '', $forcecombo = 1, $events = array())
833
    {
834
        // phpcs:enable
835
        global $conf, $langs;
836
837
        $langs->load("dict");
838
839
        $out = '';
840
        $incotermArray = array();
841
842
        $sql = "SELECT rowid, code";
843
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_incoterms";
844
        $sql .= " WHERE active > 0";
845
        $sql .= " ORDER BY code ASC";
846
847
        dol_syslog(get_class($this) . "::select_incoterm", LOG_DEBUG);
848
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
849
        if ($resql) {
850
            if ($conf->use_javascript_ajax && !$forcecombo) {
851
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
852
                $out .= ajax_combobox($htmlname, $events);
853
            }
854
855
            if (!empty($page)) {
856
                $out .= '<form method="post" action="' . $page . '">';
857
                $out .= '<input type="hidden" name="action" value="set_incoterms">';
858
                $out .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
859
            }
860
861
            $out .= '<select id="' . $htmlname . '" class="flat selectincoterm minwidth100imp noenlargeonsmartphone" name="' . $htmlname . '" ' . $htmloption . '>';
862
            $out .= '<option value="0">&nbsp;</option>';
863
            $num = $this->db->num_rows($resql);
864
            $i = 0;
865
            if ($num) {
866
                $foundselected = false;
867
868
                while ($i < $num) {
869
                    $obj = $this->db->fetch_object($resql);
870
                    $incotermArray[$i]['rowid'] = $obj->rowid;
871
                    $incotermArray[$i]['code'] = $obj->code;
872
                    $i++;
873
                }
874
875
                foreach ($incotermArray as $row) {
876
                    if ($selected && ($selected == $row['rowid'] || $selected == $row['code'])) {
877
                        $out .= '<option value="' . $row['rowid'] . '" selected>';
878
                    } else {
879
                        $out .= '<option value="' . $row['rowid'] . '">';
880
                    }
881
882
                    if ($row['code'])
883
                        $out .= $row['code'];
884
885
                    $out .= '</option>';
886
                }
887
            }
888
            $out .= '</select>';
889
890
            $out .= '<input id="location_incoterms" class="maxwidth100onsmartphone" name="location_incoterms" value="' . $location_incoterms . '">';
891
892
            if (!empty($page)) {
893
                $out .= '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '"></form>';
894
            }
895
        } else {
896
            dol_print_error($this->db);
897
        }
898
899
        return $out;
900
    }
901
902
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
903
    /**
904
     * 	Return list of types of lines (product or service)
905
     * 	Example: 0=product, 1=service, 9=other (for external module)
906
     *
907
     * 	@param  string	$selected       Preselected type
908
     * 	@param  string	$htmlname       Name of field in html form
909
     * 	@param	int		$showempty		Add an empty field
910
     * 	@param	int		$hidetext		Do not show label 'Type' before combo box (used only if there is at least 2 choices to select)
911
     * 	@param	integer	$forceall		1=Force to show products and services in combo list, whatever are activated modules, 0=No force, 2=Force to show only Products, 3=Force to show only services, -1=Force none (and set hidden field to 'service')
912
     *  @return	void
913
     */
914
    function select_type_of_lines($selected = '', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0)
915
    {
916
        // phpcs:enable
917
        global $db, $langs, $user, $conf;
918
919
        // If product & services are enabled or both disabled.
920
        if ($forceall == 1 || (empty($forceall) && !empty($conf->product->enabled) && !empty($conf->service->enabled)) || (empty($forceall) && empty($conf->product->enabled) && empty($conf->service->enabled))) {
921
            if (empty($hidetext))
922
                print $langs->trans("Type") . ': ';
923
            print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
924
            if ($showempty) {
925
                print '<option value="-1"';
926
                if ($selected == -1)
927
                    print ' selected';
928
                print '>&nbsp;</option>';
929
            }
930
931
            print '<option value="0"';
932
            if (0 == $selected)
933
                print ' selected';
934
            print '>' . $langs->trans("Product");
935
936
            print '<option value="1"';
937
            if (1 == $selected)
938
                print ' selected';
939
            print '>' . $langs->trans("Service");
940
941
            print '</select>';
942
            //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
943
        }
944
        if ((empty($forceall) && empty($conf->product->enabled) && !empty($conf->service->enabled)) || $forceall == 3) {
945
            print $langs->trans("Service");
946
            print '<input type="hidden" name="' . $htmlname . '" value="1">';
947
        }
948
        if ((empty($forceall) && !empty($conf->product->enabled) && empty($conf->service->enabled)) || $forceall == 2) {
949
            print $langs->trans("Product");
950
            print '<input type="hidden" name="' . $htmlname . '" value="0">';
951
        }
952
        if ($forceall < 0) { // This should happened only for contracts when both predefined product and service are disabled.
953
            print '<input type="hidden" name="' . $htmlname . '" value="1">'; // By default we set on service for contract. If CONTRACT_SUPPORT_PRODUCTS is set, forceall should be 1 not -1
954
        }
955
    }
956
957
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
958
    /**
959
     * 	Load into cache cache_types_fees, array of types of fees
960
     *
961
     * 	@return     int             Nb of lines loaded, <0 if KO
962
     */
963
    function load_cache_types_fees()
964
    {
965
        // phpcs:enable
966
        global $langs;
967
968
        $num = count($this->cache_types_fees);
969
        if ($num > 0)
970
            return 0;    // Cache already loaded
971
972
        dol_syslog(__METHOD__, LOG_DEBUG);
973
974
        $langs->load("trips");
975
976
        $sql = "SELECT c.code, c.label";
977
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_type_fees as c";
978
        $sql .= " WHERE active > 0";
979
980
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
981
        if ($resql) {
982
            $num = $this->db->num_rows($resql);
983
            $i = 0;
984
985
            while ($i < $num) {
986
                $obj = $this->db->fetch_object($resql);
987
988
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
989
                $label = ($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label));
990
                $this->cache_types_fees[$obj->code] = $label;
991
                $i++;
992
            }
993
994
            asort($this->cache_types_fees);
995
996
            return $num;
997
        } else {
998
            dol_print_error($this->db);
999
            return -1;
1000
        }
1001
    }
1002
1003
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1004
    /**
1005
     * 	Return list of types of notes
1006
     *
1007
     * 	@param	string		$selected		Preselected type
1008
     * 	@param  string		$htmlname		Name of field in form
1009
     * 	@param	int			$showempty		Add an empty field
1010
     * 	@return	void
1011
     */
1012
    function select_type_fees($selected = '', $htmlname = 'type', $showempty = 0)
1013
    {
1014
        // phpcs:enable
1015
        global $user, $langs;
1016
1017
        dol_syslog(__METHOD__ . " selected=" . $selected . ", htmlname=" . $htmlname, LOG_DEBUG);
1018
1019
        $this->load_cache_types_fees();
1020
1021
        print '<select id="select_' . $htmlname . '" class="flat" name="' . $htmlname . '">';
1022
        if ($showempty) {
1023
            print '<option value="-1"';
1024
            if ($selected == -1)
1025
                print ' selected';
1026
            print '>&nbsp;</option>';
1027
        }
1028
1029
        foreach ($this->cache_types_fees as $key => $value) {
1030
            print '<option value="' . $key . '"';
1031
            if ($key == $selected)
1032
                print ' selected';
1033
            print '>';
1034
            print $value;
1035
            print '</option>';
1036
        }
1037
1038
        print '</select>';
1039
        if ($user->admin)
1040
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1041
    }
1042
1043
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1044
    /**
1045
     *  Return HTML code to select a company.
1046
     *
1047
     *  @param		int			$selected				Preselected products
1048
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
1049
     *  @param		int			$filter					Filter on thirdparty
1050
     *  @param		int			$limit					Limit on number of returned lines
1051
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
1052
     * 	@param		int			$forcecombo				Force to load all values and output a standard combobox (with no beautification)
1053
     *  @return		string								Return select box for thirdparty.
1054
     *  @deprecated	3.8 Use select_company instead. For exemple $form->select_thirdparty(GETPOST('socid'),'socid','',0) => $form->select_company(GETPOST('socid'),'socid','',1,0,0,array(),0)
1055
     */
1056
    function select_thirdparty($selected = '', $htmlname = 'socid', $filter = '', $limit = 20, $ajaxoptions = array(), $forcecombo = 0)
1057
    {
1058
        // phpcs:enable
1059
        return $this->select_thirdparty_list($selected, $htmlname, $filter, 1, 0, $forcecombo, array(), '', 0, $limit);
1060
    }
1061
1062
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1063
    /**
1064
     *  Output html form to select a third party
1065
     *
1066
     * 	@param	string	$selected       		Preselected type
1067
     * 	@param  string	$htmlname       		Name of field in form
1068
     *  @param  string	$filter         		optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)')
1069
     * 	@param	string	$showempty				Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
1070
     * 	@param	int		$showtype				Show third party type in combolist (customer, prospect or supplier)
1071
     * 	@param	int		$forcecombo				Force to load all values and output a standard combobox (with no beautification)
1072
     *  @param	array	$events					Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
1073
     * 	@param	int		$limit					Maximum number of elements
1074
     *  @param	string	$morecss				Add more css styles to the SELECT component
1075
     * 	@param  string	$moreparam      		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1076
     * 	@param	string	$selected_input_value	Value of preselected input text (for use with ajax)
1077
     *  @param	int		$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
1078
     *  @param	array	$ajaxoptions			Options for ajax_autocompleter
1079
     * 	@param  bool	$multiple				add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
1080
     * 	@return	string							HTML string with select box for thirdparty.
1081
     */
1082
    function select_company($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $limit = 0, $morecss = 'minwidth100', $moreparam = '', $selected_input_value = '', $hidelabel = 1, $ajaxoptions = array(), $multiple = false)
1083
    {
1084
        // phpcs:enable
1085
        global $conf, $user, $langs;
1086
1087
        $out = '';
1088
1089
        if (!empty($conf->use_javascript_ajax) && !empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && !$forcecombo) {
1090
            // No immediate load of all database
1091
            $placeholder = '';
1092
            if ($selected && empty($selected_input_value)) {
1093
                require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
1094
                $societetmp = new Societe($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
Bug introduced by
The type Alixar\Base\Societe was not found. Did you mean Societe? If so, make sure to prefix the type with \.
Loading history...
1095
                $societetmp->fetch($selected);
1096
                $selected_input_value = $societetmp->name;
1097
                unset($societetmp);
1098
            }
1099
            // mode 1
1100
            $urloption = 'htmlname=' . $htmlname . '&outjson=1&filter=' . $filter . ($showtype ? '&showtype=' . $showtype : '');
1101
            $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
1102
            $out .= '<style type="text/css">.ui-autocomplete { z-index: 250; }</style>';
1103
            if (empty($hidelabel))
1104
                print $langs->trans("RefOrLabel") . ' : ';
1105
            else if ($hidelabel > 1) {
1106
                $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
1107
                if ($hidelabel == 2) {
1108
                    $out .= img_picto($langs->trans("Search"), 'search');
1109
                }
1110
            }
1111
            $out .= '<input type="text" class="' . $morecss . '" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' ' . (!empty($conf->global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '') . ' />';
1112
            if ($hidelabel == 3) {
1113
                $out .= img_picto($langs->trans("Search"), 'search');
1114
            }
1115
        } else {
1116
            // Immediate load of all database
1117
            $out .= $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple);
1118
        }
1119
1120
        return $out;
1121
    }
1122
1123
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1124
    /**
1125
     *  Output html form to select a third party.
1126
     *  Note, you must use the select_company to get the component to select a third party. This function must only be called by select_company.
1127
     *
1128
     * 	@param	string	$selected       Preselected type
1129
     * 	@param  string	$htmlname       Name of field in form
1130
     *  @param  string	$filter         Optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)')
1131
     * 	@param	string	$showempty		Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
1132
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
1133
     * 	@param	int		$forcecombo		Force to use standard HTML select component without beautification
1134
     *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
1135
     *  @param	string	$filterkey		Filter on key value
1136
     *  @param	int		$outputmode		0=HTML select string, 1=Array
1137
     *  @param	int		$limit			Limit number of answers
1138
     *  @param	string	$morecss		Add more css styles to the SELECT component
1139
     * 	@param  string	$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1140
     * 	@param  bool	$multiple       add [] in the name of element and add 'multiple' attribut
1141
     * 	@return	string					HTML string with
1142
     */
1143
    function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false)
1144
    {
1145
        // phpcs:enable
1146
        global $conf, $user, $langs;
1147
1148
        $out = '';
1149
        $num = 0;
1150
        $outarray = array();
1151
1152
        if ($selected === '')
1153
            $selected = array();
1154
        else if (!is_array($selected))
1155
            $selected = array($selected);
1156
1157
        // Clean $filter that may contains sql conditions so sql code
1158
        if (function_exists('testSqlAndScriptInject')) {
1159
            if (testSqlAndScriptInject($filter, 3) > 0) {
1160
                $filter = '';
1161
            }
1162
        }
1163
1164
        // On recherche les societes
1165
        $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
1166
1167
        if ($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
1168
            $sql .= " ,s.address, s.zip, s.town";
1169
            $sql .= " , dictp.code as country_code";
1170
        }
1171
1172
        $sql .= " FROM (" . MAIN_DB_PREFIX . "societe as s";
1173
        if (!$user->rights->societe->client->voir && !$user->socid)
1174
            $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
1175
        $sql .= " )";
1176
        if ($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
1177
            $sql .= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "c_country as dictp ON dictp.rowid=s.fk_pays";
1178
        }
1179
        $sql .= " WHERE s.entity IN (" . getEntity('societe') . ")";
1180
        if (!empty($user->socid))
1181
            $sql .= " AND s.rowid = " . $user->socid;
1182
        if ($filter)
1183
            $sql .= " AND (" . $filter . ")";
1184
        if (!$user->rights->societe->client->voir && !$user->socid)
1185
            $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user->id;
1186
        if (!empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX))
1187
            $sql .= " AND s.status <> 0";
1188
        // Add criteria
1189
        if ($filterkey && $filterkey != '') {
1190
            $sql .= " AND (";
1191
            $prefix = empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on
1192
            // For natural search
1193
            $scrit = explode(' ', $filterkey);
1194
            $i = 0;
1195
            if (count($scrit) > 1)
1196
                $sql .= "(";
1197
            foreach ($scrit as $crit) {
1198
                if ($i > 0)
1199
                    $sql .= " AND ";
1200
                $sql .= "(s.nom LIKE '" . $this->db->escape($prefix . $crit) . "%')";
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1201
                $i++;
1202
            }
1203
            if (count($scrit) > 1)
1204
                $sql .= ")";
1205
            if (!empty($conf->barcode->enabled)) {
1206
                $sql .= " OR s.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%'";
1207
            }
1208
            $sql .= " OR s.code_client LIKE '" . $this->db->escape($prefix . $filterkey) . "%' OR s.code_fournisseur LIKE '" . $this->db->escape($prefix . $filterkey) . "%'";
1209
            $sql .= ")";
1210
        }
1211
        $sql .= $this->db->order("nom", "ASC");
1212
        $sql .= $this->db->plimit($limit, 0);
1213
1214
        // Build output string
1215
        dol_syslog(get_class($this) . "::select_thirdparty_list", LOG_DEBUG);
1216
        $resql = $this->db->query($sql);
1217
        if ($resql) {
1218
            if (!$forcecombo) {
1219
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1220
                $out .= ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT);
1221
            }
1222
1223
            // Construct $out and $outarray
1224
            $out .= '<select id="' . $htmlname . '" class="flat' . ($morecss ? ' ' . $morecss : '') . '"' . ($moreparam ? ' ' . $moreparam : '') . ' name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . '>' . "\n";
1225
1226
            $textifempty = '';
1227
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
1228
            //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
1229
            if (!empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) {
1230
                if ($showempty && !is_numeric($showempty))
1231
                    $textifempty = $langs->trans($showempty);
1232
                else
1233
                    $textifempty .= $langs->trans("All");
1234
            }
1235
            if ($showempty)
1236
                $out .= '<option value="-1">' . $textifempty . '</option>' . "\n";
1237
1238
            $num = $this->db->num_rows($resql);
1239
            $i = 0;
1240
            if ($num) {
1241
                while ($i < $num) {
1242
                    $obj = $this->db->fetch_object($resql);
1243
                    $label = '';
1244
                    if ($conf->global->SOCIETE_ADD_REF_IN_LIST) {
1245
                        if (($obj->client) && (!empty($obj->code_client))) {
1246
                            $label = $obj->code_client . ' - ';
1247
                        }
1248
                        if (($obj->fournisseur) && (!empty($obj->code_fournisseur))) {
1249
                            $label .= $obj->code_fournisseur . ' - ';
1250
                        }
1251
                        $label .= ' ' . $obj->name;
1252
                    } else {
1253
                        $label = $obj->name;
1254
                    }
1255
1256
                    if (!empty($obj->name_alias)) {
1257
                        $label .= ' (' . $obj->name_alias . ')';
1258
                    }
1259
1260
                    if ($showtype) {
1261
                        if ($obj->client || $obj->fournisseur)
1262
                            $label .= ' (';
1263
                        if ($obj->client == 1 || $obj->client == 3)
1264
                            $label .= $langs->trans("Customer");
1265
                        if ($obj->client == 2 || $obj->client == 3)
1266
                            $label .= ($obj->client == 3 ? ', ' : '') . $langs->trans("Prospect");
1267
                        if ($obj->fournisseur)
1268
                            $label .= ($obj->client ? ', ' : '') . $langs->trans("Supplier");
1269
                        if ($obj->client || $obj->fournisseur)
1270
                            $label .= ')';
1271
                    }
1272
1273
                    if ($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
1274
                        $label .= '-' . $obj->address . '-' . $obj->zip . ' ' . $obj->town;
1275
                        if (!empty($obj->country_code)) {
1276
                            $label .= ' ' . $langs->trans('Country' . $obj->country_code);
1277
                        }
1278
                    }
1279
1280
                    if (empty($outputmode)) {
1281
                        if (in_array($obj->rowid, $selected)) {
1282
                            $out .= '<option value="' . $obj->rowid . '" selected>' . $label . '</option>';
1283
                        } else {
1284
                            $out .= '<option value="' . $obj->rowid . '">' . $label . '</option>';
1285
                        }
1286
                    } else {
1287
                        array_push($outarray, array('key' => $obj->rowid, 'value' => $label, 'label' => $label));
1288
                    }
1289
1290
                    $i++;
1291
                    if (($i % 10) == 0)
1292
                        $out .= "\n";
1293
                }
1294
            }
1295
            $out .= '</select>' . "\n";
1296
        }
1297
        else {
1298
            dol_print_error($this->db);
1299
        }
1300
1301
        $this->result = array('nbofthirdparties' => $num);
1302
1303
        if ($outputmode)
1304
            return $outarray;
1305
        return $out;
1306
    }
1307
1308
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1309
    /**
1310
     *    	Return HTML combo list of absolute discounts
1311
     *
1312
     *    	@param	string	$selected       Id remise fixe pre-selectionnee
1313
     *    	@param  string	$htmlname       Nom champ formulaire
1314
     *    	@param  string	$filter         Criteres optionnels de filtre
1315
     * 		@param	int		$socid			Id of thirdparty
1316
     * 		@param	int		$maxvalue		Max value for lines that can be selected
1317
     * 		@return	int						Return number of qualifed lines in list
1318
     */
1319
    function select_remises($selected, $htmlname, $filter, $socid, $maxvalue = 0)
1320
    {
1321
        // phpcs:enable
1322
        global $langs, $conf;
1323
1324
        // On recherche les remises
1325
        $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
1326
        $sql .= " re.description, re.fk_facture_source";
1327
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as re";
1328
        $sql .= " WHERE re.fk_soc = " . (int) $socid;
1329
        $sql .= " AND re.entity = " . $conf->entity;
1330
        if ($filter)
1331
            $sql .= " AND " . $filter;
1332
        $sql .= " ORDER BY re.description ASC";
1333
1334
        dol_syslog(get_class($this) . "::select_remises", LOG_DEBUG);
1335
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1336
        if ($resql) {
1337
            print '<select id="select_' . $htmlname . '" class="flat maxwidthonsmartphone" name="' . $htmlname . '">';
1338
            $num = $this->db->num_rows($resql);
1339
1340
            $qualifiedlines = $num;
1341
1342
            $i = 0;
1343
            if ($num) {
1344
                print '<option value="0">&nbsp;</option>';
1345
                while ($i < $num) {
1346
                    $obj = $this->db->fetch_object($resql);
1347
                    $desc = dol_trunc($obj->description, 40);
1348
                    if (preg_match('/\(CREDIT_NOTE\)/', $desc))
1349
                        $desc = preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc);
1350
                    if (preg_match('/\(DEPOSIT\)/', $desc))
1351
                        $desc = preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc);
1352
                    if (preg_match('/\(EXCESS RECEIVED\)/', $desc))
1353
                        $desc = preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc);
1354
                    if (preg_match('/\(EXCESS PAID\)/', $desc))
1355
                        $desc = preg_replace('/\(EXCESS PAID\)/', $langs->trans("ExcessPaid"), $desc);
1356
1357
                    $selectstring = '';
1358
                    if ($selected > 0 && $selected == $obj->rowid)
1359
                        $selectstring = ' selected';
1360
1361
                    $disabled = '';
1362
                    if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue) {
1363
                        $qualifiedlines--;
1364
                        $disabled = ' disabled';
1365
                    }
1366
1367
                    if (!empty($conf->global->MAIN_SHOW_FACNUMBER_IN_DISCOUNT_LIST) && !empty($obj->fk_facture_source)) {
1368
                        $tmpfac = new Facture($this->db);
0 ignored issues
show
Bug introduced by
The type Alixar\Base\Facture was not found. Did you mean Facture? If so, make sure to prefix the type with \.
Loading history...
1369
                        if ($tmpfac->fetch($obj->fk_facture_source) > 0)
1370
                            $desc = $desc . ' - ' . $tmpfac->ref;
1371
                    }
1372
1373
                    print '<option value="' . $obj->rowid . '"' . $selectstring . $disabled . '>' . $desc . ' (' . price($obj->amount_ht) . ' ' . $langs->trans("HT") . ' - ' . price($obj->amount_ttc) . ' ' . $langs->trans("TTC") . ')</option>';
1374
                    $i++;
1375
                }
1376
            }
1377
            print '</select>';
1378
            return $qualifiedlines;
1379
        }
1380
        else {
1381
            dol_print_error($this->db);
1382
            return -1;
1383
        }
1384
    }
1385
1386
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1387
    /**
1388
     * 	Return list of all contacts (for a third party or all)
1389
     *
1390
     * 	@param	int		$socid      	Id ot third party or 0 for all
1391
     * 	@param  string	$selected   	Id contact pre-selectionne
1392
     * 	@param  string	$htmlname  	    Name of HTML field ('none' for a not editable field)
1393
     * 	@param  int		$showempty      0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list
1394
     * 	@param  string	$exclude        List of contacts id to exclude
1395
     * 	@param	string	$limitto		Disable answers that are not id in this array list
1396
     * 	@param	integer	$showfunction   Add function into label
1397
     * 	@param	string	$moreclass		Add more class to class style
1398
     * 	@param	integer	$showsoc	    Add company into label
1399
     * 	@param	int		$forcecombo		Force to use combo box
1400
     *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
1401
     *  @param	bool	$options_only	Return options only (for ajax treatment)
1402
     *  @param	string	$moreparam		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1403
     *  @param	string	$htmlid			Html id to use instead of htmlname
1404
     * 	@return	int						<0 if KO, Nb of contact in list if OK
1405
     *  @deprected						You can use selectcontacts directly (warning order of param was changed)
1406
     */
1407
    function select_contacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $showsoc = 0, $forcecombo = 0, $events = array(), $options_only = false, $moreparam = '', $htmlid = '')
1408
    {
1409
        // phpcs:enable
1410
        print $this->selectcontacts($socid, $selected, $htmlname, $showempty, $exclude, $limitto, $showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events, $moreparam, $htmlid);
1411
        return $this->num;
1412
    }
1413
1414
    /**
1415
     * 	Return HTML code of the SELECT of list of all contacts (for a third party or all).
1416
     *  This also set the number of contacts found into $this->num
1417
     *
1418
     * @since 9.0 Add afterSelectContactOptions hook
1419
     *
1420
     * 	@param	int			$socid      	Id ot third party or 0 for all or -1 for empty list
1421
     * 	@param  array|int	$selected   	Array of ID of pre-selected contact id
1422
     * 	@param  string		$htmlname  	    Name of HTML field ('none' for a not editable field)
1423
     * 	@param  int			$showempty     	0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list
1424
     * 	@param  string		$exclude        List of contacts id to exclude
1425
     * 	@param	string		$limitto		Disable answers that are not id in this array list
1426
     * 	@param	integer		$showfunction   Add function into label
1427
     * 	@param	string		$moreclass		Add more class to class style
1428
     * 	@param	bool		$options_only	Return options only (for ajax treatment)
1429
     * 	@param	integer		$showsoc	    Add company into label
1430
     * 	@param	int			$forcecombo		Force to use combo box (so no ajax beautify effect)
1431
     *  @param	array		$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
1432
     *  @param	string		$moreparam		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1433
     *  @param	string		$htmlid			Html id to use instead of htmlname
1434
     *  @param	bool		$multiple		add [] in the name of element and add 'multiple' attribut
1435
     * 	@return	 int						<0 if KO, Nb of contact in list if OK
1436
     */
1437
    function selectcontacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $options_only = false, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $multiple = false)
1438
    {
1439
        global $conf, $langs, $hookmanager, $action;
1440
1441
        $langs->load('companies');
1442
1443
        if (empty($htmlid))
1444
            $htmlid = $htmlname;
1445
1446
        if ($selected === '')
1447
            $selected = array();
1448
        else if (!is_array($selected))
1449
            $selected = array($selected);
1450
        $out = '';
1451
1452
        if (!is_object($hookmanager)) {
1453
            include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
1454
            $hookmanager = new HookManager($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1455
        }
1456
1457
        // We search third parties
1458
        $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste";
1459
        if ($showsoc > 0)
1460
            $sql .= " , s.nom as company";
1461
        $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople as sp";
1462
        if ($showsoc > 0)
1463
            $sql .= " LEFT OUTER JOIN  " . MAIN_DB_PREFIX . "societe as s ON s.rowid=sp.fk_soc";
1464
        $sql .= " WHERE sp.entity IN (" . getEntity('socpeople') . ")";
1465
        if ($socid > 0 || $socid == -1)
1466
            $sql .= " AND sp.fk_soc=" . $socid;
1467
        if (!empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX))
1468
            $sql .= " AND sp.statut <> 0";
1469
        $sql .= " ORDER BY sp.lastname ASC";
1470
1471
        dol_syslog(get_class($this) . "::select_contacts", LOG_DEBUG);
1472
        $resql = $this->db->query($sql);
1473
        if ($resql) {
1474
            $num = $this->db->num_rows($resql);
1475
1476
            if ($conf->use_javascript_ajax && !$forcecombo && !$options_only) {
1477
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1478
                $out .= ajax_combobox($htmlid, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT);
1479
            }
1480
1481
            if ($htmlname != 'none' || $options_only)
1482
                $out .= '<select class="flat' . ($moreclass ? ' ' . $moreclass : '') . '" id="' . $htmlid . '" name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . ' ' . (!empty($moreparam) ? $moreparam : '') . '>';
1483
            if (($showempty == 1 || ($showempty == 3 && $num > 1)) && !$multiple)
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($showempty == 1 || $sho...num > 1) && ! $multiple, Probably Intended Meaning: $showempty == 1 || ($sho...num > 1 && ! $multiple)
Loading history...
1484
                $out .= '<option value="0"' . (in_array(0, $selected) ? ' selected' : '') . '>&nbsp;</option>';
1485
            if ($showempty == 2)
1486
                $out .= '<option value="0"' . (in_array(0, $selected) ? ' selected' : '') . '>' . $langs->trans("Internal") . '</option>';
1487
            $num = $this->db->num_rows($resql);
1488
            $i = 0;
1489
            if ($num) {
1490
                include_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
1491
                $contactstatic = new Contact($this->db);
0 ignored issues
show
Bug introduced by
The type Alixar\Base\Contact was not found. Did you mean Contact? If so, make sure to prefix the type with \.
Loading history...
1492
1493
                while ($i < $num) {
1494
                    $obj = $this->db->fetch_object($resql);
1495
1496
                    $contactstatic->id = $obj->rowid;
1497
                    $contactstatic->lastname = $obj->lastname;
1498
                    $contactstatic->firstname = $obj->firstname;
1499
                    if ($obj->statut == 1) {
1500
                        if ($htmlname != 'none') {
1501
                            $disabled = 0;
1502
                            if (is_array($exclude) && count($exclude) && in_array($obj->rowid, $exclude))
1503
                                $disabled = 1;
1504
                            if (is_array($limitto) && count($limitto) && !in_array($obj->rowid, $limitto))
1505
                                $disabled = 1;
1506
                            if (!empty($selected) && in_array($obj->rowid, $selected)) {
1507
                                $out .= '<option value="' . $obj->rowid . '"';
1508
                                if ($disabled)
1509
                                    $out .= ' disabled';
1510
                                $out .= ' selected>';
1511
                                $out .= $contactstatic->getFullName($langs);
1512
                                if ($showfunction && $obj->poste)
1513
                                    $out .= ' (' . $obj->poste . ')';
1514
                                if (($showsoc > 0) && $obj->company)
1515
                                    $out .= ' - (' . $obj->company . ')';
1516
                                $out .= '</option>';
1517
                            }
1518
                            else {
1519
                                $out .= '<option value="' . $obj->rowid . '"';
1520
                                if ($disabled)
1521
                                    $out .= ' disabled';
1522
                                $out .= '>';
1523
                                $out .= $contactstatic->getFullName($langs);
1524
                                if ($showfunction && $obj->poste)
1525
                                    $out .= ' (' . $obj->poste . ')';
1526
                                if (($showsoc > 0) && $obj->company)
1527
                                    $out .= ' - (' . $obj->company . ')';
1528
                                $out .= '</option>';
1529
                            }
1530
                        }
1531
                        else {
1532
                            if (in_array($obj->rowid, $selected)) {
1533
                                $out .= $contactstatic->getFullName($langs);
1534
                                if ($showfunction && $obj->poste)
1535
                                    $out .= ' (' . $obj->poste . ')';
1536
                                if (($showsoc > 0) && $obj->company)
1537
                                    $out .= ' - (' . $obj->company . ')';
1538
                            }
1539
                        }
1540
                    }
1541
                    $i++;
1542
                }
1543
            }
1544
            else {
1545
                $out .= '<option value="-1"' . (($showempty == 2 || $multiple) ? '' : ' selected') . ' disabled>';
1546
                $out .= ($socid != -1) ? ($langs->trans($socid ? "NoContactDefinedForThirdParty" : "NoContactDefined")) : $langs->trans('SelectAThirdPartyFirst');
1547
                $out .= '</option>';
1548
            }
1549
1550
            $parameters = array(
1551
                'socid' => $socid,
1552
                'htmlname' => $htmlname,
1553
                'resql' => $resql,
1554
                'out' => &$out,
1555
                'showfunction' => $showfunction,
1556
                'showsoc' => $showsoc,
1557
            );
1558
1559
            $reshook = $hookmanager->executeHooks('afterSelectContactOptions', $parameters, $this, $action);    // Note that $action and $object may have been modified by some hooks
1560
1561
            if ($htmlname != 'none' || $options_only) {
1562
                $out .= '</select>';
1563
            }
1564
1565
            $this->num = $num;
1566
            return $out;
1567
        } else {
1568
            dol_print_error($this->db);
1569
            return -1;
1570
        }
1571
    }
1572
1573
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1574
    /**
1575
     * 	Return select list of users
1576
     *
1577
     *  @param	string	$selected       Id user preselected
1578
     *  @param  string	$htmlname       Field name in form
1579
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
1580
     *  @param  array	$exclude        Array list of users id to exclude
1581
     * 	@param	int		$disabled		If select list must be disabled
1582
     *  @param  array	$include        Array list of users id to include
1583
     * 	@param	int		$enableonly		Array list of users id to be enabled. All other must be disabled
1584
     *  @param	string	$force_entity	'0' or Ids of environment to force
1585
     * 	@return	void
1586
     *  @deprecated		Use select_dolusers instead
1587
     *  @see select_dolusers()
1588
     */
1589
    function select_users($selected = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '0')
1590
    {
1591
        // phpcs:enable
1592
        print $this->select_dolusers($selected, $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity);
1593
    }
1594
1595
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1596
    /**
1597
     * 	Return select list of users
1598
     *
1599
     *  @param	string	$selected       User id or user object of user preselected. If 0 or < -2, we use id of current user. If -1, keep unselected (if empty is allowed)
1600
     *  @param  string	$htmlname       Field name in form
1601
     *  @param  int		$show_empty     0=list with no empty value, 1=add also an empty value into list
1602
     *  @param  array	$exclude        Array list of users id to exclude
1603
     * 	@param	int		$disabled		If select list must be disabled
1604
     *  @param  array|string	$include        Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me
1605
     * 	@param	array	$enableonly		Array list of users id to be enabled. If defined, it means that others will be disabled
1606
     *  @param	string	$force_entity	'0' or Ids of environment to force
1607
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1608
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1609
     *  @param	string	$morefilter		Add more filters into sql request (Example: 'employee = 1')
1610
     *  @param	integer	$show_every		0=default list, 1=add also a value "Everybody" at beginning of list
1611
     *  @param	string	$enableonlytext	If option $enableonlytext is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty.
1612
     *  @param	string	$morecss		More css
1613
     *  @param  int     $noactive       Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on).
1614
     *  @param  int		$outputmode     0=HTML select string, 1=Array
1615
     *  @param  bool	$multiple       add [] in the name of element and add 'multiple' attribut
1616
     * 	@return	string					HTML select string
1617
     *  @see select_dolgroups
1618
     */
1619
    function select_dolusers($selected = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $show_every = 0, $enableonlytext = '', $morecss = '', $noactive = 0, $outputmode = 0, $multiple = false)
1620
    {
1621
        // phpcs:enable
1622
        global $conf, $user, $langs;
1623
1624
        // If no preselected user defined, we take current user
1625
        if ((is_numeric($selected) && ($selected < -2 || empty($selected))) && empty($conf->global->SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE))
1626
            $selected = $user->id;
1627
1628
        if ($selected === '')
1629
            $selected = array();
1630
        else if (!is_array($selected))
1631
            $selected = array($selected);
1632
1633
        $excludeUsers = null;
1634
        $includeUsers = null;
1635
1636
        // Permettre l'exclusion d'utilisateurs
1637
        if (is_array($exclude))
1638
            $excludeUsers = implode(",", $exclude);
1639
        // Permettre l'inclusion d'utilisateurs
1640
        if (is_array($include))
1641
            $includeUsers = implode(",", $include);
1642
        else if ($include == 'hierarchy') {
1643
            // Build list includeUsers to have only hierarchy
1644
            $includeUsers = implode(",", $user->getAllChildIds(0));
1645
        } else if ($include == 'hierarchyme') {
1646
            // Build list includeUsers to have only hierarchy and current user
1647
            $includeUsers = implode(",", $user->getAllChildIds(1));
1648
        }
1649
1650
        $out = '';
1651
        $outarray = array();
1652
1653
        // Forge request to select users
1654
        $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity";
1655
        if (!empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && !$user->entity) {
1656
            $sql .= ", e.label";
1657
        }
1658
        $sql .= " FROM " . MAIN_DB_PREFIX . "user as u";
1659
        if (!empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && !$user->entity) {
1660
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=u.entity";
1661
            if ($force_entity)
1662
                $sql .= " WHERE u.entity IN (0," . $force_entity . ")";
1663
            else
1664
                $sql .= " WHERE u.entity IS NOT NULL";
1665
        }
1666
        else {
1667
            if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1668
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "usergroup_user as ug";
1669
                $sql .= " ON ug.fk_user = u.rowid";
1670
                $sql .= " WHERE ug.entity = " . $conf->entity;
1671
            } else {
1672
                $sql .= " WHERE u.entity IN (0," . $conf->entity . ")";
1673
            }
1674
        }
1675
        if (!empty($user->societe_id))
1676
            $sql .= " AND u.fk_soc = " . $user->societe_id;
1677
        if (is_array($exclude) && $excludeUsers)
1678
            $sql .= " AND u.rowid NOT IN (" . $excludeUsers . ")";
1679
        if ($includeUsers)
1680
            $sql .= " AND u.rowid IN (" . $includeUsers . ")";
1681
        if (!empty($conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive)
1682
            $sql .= " AND u.statut <> 0";
1683
        if (!empty($morefilter))
1684
            $sql .= " " . $morefilter;
1685
1686
        if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { // MAIN_FIRSTNAME_NAME_POSITION is 0 means firstname+lastname
1687
            $sql .= " ORDER BY u.firstname ASC";
1688
        } else {
1689
            $sql .= " ORDER BY u.lastname ASC";
1690
        }
1691
1692
        dol_syslog(get_class($this) . "::select_dolusers", LOG_DEBUG);
1693
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1694
        if ($resql) {
1695
            $num = $this->db->num_rows($resql);
1696
            $i = 0;
1697
            if ($num) {
1698
                // Enhance with select2
1699
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1700
                $out .= ajax_combobox($htmlname);
1701
1702
                // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined
1703
                $out .= '<select class="flat' . ($morecss ? ' minwidth100 ' . $morecss : ' minwidth200') . '" id="' . $htmlname . '" name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . ' ' . ($disabled ? ' disabled' : '') . '>';
1704
                if ($show_empty && !$multiple)
1705
                    $out .= '<option value="-1"' . ((empty($selected) || in_array(-1, $selected)) ? ' selected' : '') . '>&nbsp;</option>' . "\n";
1706
                if ($show_every)
1707
                    $out .= '<option value="-2"' . ((in_array(-2, $selected)) ? ' selected' : '') . '>-- ' . $langs->trans("Everybody") . ' --</option>' . "\n";
1708
1709
                $userstatic = new User($this->db);
1710
1711
                while ($i < $num) {
1712
                    $obj = $this->db->fetch_object($resql);
1713
1714
                    $userstatic->id = $obj->rowid;
1715
                    $userstatic->lastname = $obj->lastname;
1716
                    $userstatic->firstname = $obj->firstname;
1717
1718
                    $disableline = '';
1719
                    if (is_array($enableonly) && count($enableonly) && !in_array($obj->rowid, $enableonly))
1720
                        $disableline = ($enableonlytext ? $enableonlytext : '1');
1721
1722
                    if ((is_object($selected) && $selected->id == $obj->rowid) || (!is_object($selected) && in_array($obj->rowid, $selected) )) {
1723
                        $out .= '<option value="' . $obj->rowid . '"';
1724
                        if ($disableline)
1725
                            $out .= ' disabled';
1726
                        $out .= ' selected>';
1727
                    }
1728
                    else {
1729
                        $out .= '<option value="' . $obj->rowid . '"';
1730
                        if ($disableline)
1731
                            $out .= ' disabled';
1732
                        $out .= '>';
1733
                    }
1734
1735
                    // $fullNameMode is 0=Lastname+Firstname (MAIN_FIRSTNAME_NAME_POSITION=1), 1=Firstname+Lastname (MAIN_FIRSTNAME_NAME_POSITION=0)
1736
                    $fullNameMode = 0;
1737
                    if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) {
1738
                        $fullNameMode = 1; //Firstname+lastname
1739
                    }
1740
                    $out .= $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength);
1741
1742
                    // Complete name with more info
1743
                    $moreinfo = 0;
1744
                    if (!empty($conf->global->MAIN_SHOW_LOGIN)) {
1745
                        $out .= ($moreinfo ? ' - ' : ' (') . $obj->login;
1746
                        $moreinfo++;
1747
                    }
1748
                    if ($showstatus >= 0) {
1749
                        if ($obj->statut == 1 && $showstatus == 1) {
1750
                            $out .= ($moreinfo ? ' - ' : ' (') . $langs->trans('Enabled');
1751
                            $moreinfo++;
1752
                        }
1753
                        if ($obj->statut == 0) {
1754
                            $out .= ($moreinfo ? ' - ' : ' (') . $langs->trans('Disabled');
1755
                            $moreinfo++;
1756
                        }
1757
                    }
1758
                    if (!empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && !$user->entity) {
1759
                        if (!$obj->entity) {
1760
                            $out .= ($moreinfo ? ' - ' : ' (') . $langs->trans("AllEntities");
1761
                            $moreinfo++;
1762
                        } else {
1763
                            $out .= ($moreinfo ? ' - ' : ' (') . ($obj->label ? $obj->label : $langs->trans("EntityNameNotDefined"));
1764
                            $moreinfo++;
1765
                        }
1766
                    }
1767
                    $out .= ($moreinfo ? ')' : '');
1768
                    if ($disableline && $disableline != '1') {
1769
                        $out .= ' - ' . $disableline; // This is text from $enableonlytext parameter
1770
                    }
1771
                    $out .= '</option>';
1772
                    $outarray[$userstatic->id] = $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength);
1773
1774
                    $i++;
1775
                }
1776
            } else {
1777
                $out .= '<select class="flat" id="' . $htmlname . '" name="' . $htmlname . '" disabled>';
1778
                $out .= '<option value="">' . $langs->trans("None") . '</option>';
1779
            }
1780
            $out .= '</select>';
1781
        } else {
1782
            dol_print_error($this->db);
1783
        }
1784
1785
        if ($outputmode)
1786
            return $outarray;
1787
        return $out;
1788
    }
1789
1790
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1791
    /**
1792
     * 	Return select list of users. Selected users are stored into session.
1793
     *  List of users are provided into $_SESSION['assignedtouser'].
1794
     *
1795
     *  @param  string	$action         Value for $action
1796
     *  @param  string	$htmlname       Field name in form
1797
     *  @param  int		$show_empty     0=list without the empty value, 1=add empty value
1798
     *  @param  array	$exclude        Array list of users id to exclude
1799
     * 	@param	int		$disabled		If select list must be disabled
1800
     *  @param  array	$include        Array list of users id to include or 'hierarchy' to have only supervised users
1801
     * 	@param	array	$enableonly		Array list of users id to be enabled. All other must be disabled
1802
     *  @param	int		$force_entity	'0' or Ids of environment to force
1803
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1804
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1805
     *  @param	string	$morefilter		Add more filters into sql request
1806
     *  @param	int		$showproperties		Show properties of each attendees
1807
     *  @param	array	$listofuserid		Array with properties of each user
1808
     *  @param	array	$listofcontactid	Array with properties of each contact
1809
     *  @param	array	$listofotherid		Array with properties of each other contact
1810
     * 	@return	string					HTML select string
1811
     *  @see select_dolgroups
1812
     */
1813
    function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array())
1814
    {
1815
        // phpcs:enable
1816
        global $conf, $user, $langs;
1817
1818
        $userstatic = new User($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1819
        $out = '';
1820
1821
        // Method with no ajax
1822
        //$out.='<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
1823
        if ($action == 'view') {
1824
            $out .= '';
1825
        } else {
1826
            $out .= '<input type="hidden" class="removedassignedhidden" name="removedassigned" value="">';
1827
            $out .= '<script type="text/javascript" language="javascript">jQuery(document).ready(function () {    jQuery(".removedassigned").click(function() {        jQuery(".removedassignedhidden").val(jQuery(this).val());    });})</script>';
1828
            $out .= $this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter);
1829
            $out .= ' <input type="submit" class="button valignmiddle" name="' . $action . 'assignedtouser" value="' . dol_escape_htmltag($langs->trans("Add")) . '">';
1830
            $out .= '<br>';
1831
        }
1832
        $assignedtouser = array();
1833
        if (!empty($_SESSION['assignedtouser'])) {
1834
            $assignedtouser = json_decode($_SESSION['assignedtouser'], true);
1835
        }
1836
        $nbassignetouser = count($assignedtouser);
1837
1838
        if ($nbassignetouser && $action != 'view')
1839
            $out .= '<br>';
1840
        if ($nbassignetouser)
1841
            $out .= '<ul class="attendees">';
1842
        $i = 0;
1843
        $ownerid = 0;
1844
        foreach ($assignedtouser as $key => $value) {
1845
            if ($value['id'] == $ownerid)
1846
                continue;
1847
1848
            $out .= '<li>';
1849
            $userstatic->fetch($value['id']);
1850
            $out .= $userstatic->getNomUrl(-1);
1851
            if ($i == 0) {
1852
                $ownerid = $value['id'];
1853
                $out .= ' (' . $langs->trans("Owner") . ')';
1854
            }
1855
            if ($nbassignetouser > 1 && $action != 'view') {
1856
                $out .= ' <input type="image" style="border: 0px;" src="' . img_picto($langs->trans("Remove"), 'delete', '', 0, 1) . '" value="' . $userstatic->id . '" class="removedassigned" id="removedassigned_' . $userstatic->id . '" name="removedassigned_' . $userstatic->id . '">';
1857
            }
1858
            // Show my availability
1859
            if ($showproperties) {
1860
                if ($ownerid == $value['id'] && is_array($listofuserid) && count($listofuserid) && in_array($ownerid, array_keys($listofuserid))) {
1861
                    $out .= '<div class="myavailability inline-block">';
1862
                    $out .= '&nbsp;-&nbsp;<span class="opacitymedium">' . $langs->trans("Availability") . ':</span>  <input id="transparency" class="marginleftonly marginrightonly" ' . ($action == 'view' ? 'disabled' : '') . ' type="checkbox" name="transparency"' . ($listofuserid[$ownerid]['transparency'] ? ' checked' : '') . '>' . $langs->trans("Busy");
1863
                    $out .= '</div>';
1864
                }
1865
            }
1866
            //$out.=' '.($value['mandatory']?$langs->trans("Mandatory"):$langs->trans("Optional"));
1867
            //$out.=' '.($value['transparency']?$langs->trans("Busy"):$langs->trans("NotBusy"));
1868
1869
            $out .= '</li>';
1870
            $i++;
1871
        }
1872
        if ($nbassignetouser)
1873
            $out .= '</ul>';
1874
1875
        //$out.='</form>';
1876
        return $out;
1877
    }
1878
1879
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1880
    /**
1881
     *  Return list of products for customer in Ajax if Ajax activated or go to select_produits_list
1882
     *
1883
     *  @param		int			$selected				Preselected products
1884
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
1885
     *  @param		int			$filtertype				Filter on product type (''=nofilter, 0=product, 1=service)
1886
     *  @param		int			$limit					Limit on number of returned lines
1887
     *  @param		int			$price_level			Level of price to show
1888
     *  @param		int			$status					Sell status -1=Return all products, 0=Products not on sell, 1=Products on sell
1889
     *  @param		int			$finished				2=all, 1=finished, 0=raw material
1890
     *  @param		string		$selected_input_value	Value of preselected input text (for use with ajax)
1891
     *  @param		int			$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
1892
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
1893
     *  @param      int			$socid					Thirdparty Id (to get also price dedicated to this customer)
1894
     *  @param		string		$showempty				'' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
1895
     * 	@param		int			$forcecombo				Force to use combo box
1896
     *  @param      string      $morecss                Add more css on select
1897
     *  @param      int         $hidepriceinlabel       1=Hide prices in label
1898
     *  @param      string      $warehouseStatus        warehouse status filter, following comma separated filter options can be used
1899
     * 										            'warehouseopen' = select products from open warehouses,
1900
     * 										            'warehouseclosed' = select products from closed warehouses,
1901
     * 										            'warehouseinternal' = select products from warehouses for internal correct/transfer only
1902
     *  @param 		array 		$selected_combinations 	Selected combinations. Format: array([attrid] => attrval, [...])
1903
     *  @return		void
1904
     */
1905
    function select_produits($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $status = 1, $finished = 2, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $hidepriceinlabel = 0, $warehouseStatus = '', $selected_combinations = array())
1906
    {
1907
        // phpcs:enable
1908
        global $langs, $conf;
1909
1910
        $price_level = (!empty($price_level) ? $price_level : 0);
1911
1912
        if (!empty($conf->use_javascript_ajax) && !empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
1913
            $placeholder = '';
1914
1915
            if ($selected && empty($selected_input_value)) {
1916
                require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
1917
                $producttmpselect = new Product($this->db);
0 ignored issues
show
Bug introduced by
The type Alixar\Base\Product was not found. Did you mean Product? If so, make sure to prefix the type with \.
Loading history...
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1918
                $producttmpselect->fetch($selected);
1919
                $selected_input_value = $producttmpselect->ref;
1920
                unset($producttmpselect);
1921
            }
1922
            // mode=1 means customers products
1923
            $urloption = 'htmlname=' . $htmlname . '&outjson=1&price_level=' . $price_level . '&type=' . $filtertype . '&mode=1&status=' . $status . '&finished=' . $finished . '&hidepriceinlabel=' . $hidepriceinlabel . '&warehousestatus=' . $warehouseStatus;
1924
            //Price by customer
1925
            if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1926
                $urloption .= '&socid=' . $socid;
1927
            }
1928
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
1929
1930
            if (!empty($conf->variants->enabled)) {
1931
1932
                ?>
1933
                <script>
1934
1935
                                    selected = <?php echo json_encode($selected_combinations) ?>;
1936
                                    combvalues = {};
1937
1938
                                    jQuery(document).ready(function () {
1939
1940
                                        jQuery("input[name='prod_entry_mode']").change(function () {
1941
                                            if (jQuery(this).val() == 'free') {
1942
                                                jQuery('div#attributes_box').empty();
1943
                                            }
1944
                                        });
1945
1946
                                        jQuery("input#<?php echo $htmlname ?>").change(function () {
1947
1948
                                            if (!jQuery(this).val()) {
1949
                                                jQuery('div#attributes_box').empty();
1950
                                                return;
1951
                                            }
1952
1953
                                            jQuery.getJSON("<?php echo dol_buildpath('/variants/ajax/getCombinations.php', 2) ?>", {
1954
                                                id: jQuery(this).val()
1955
                                            }, function (data) {
1956
                                                jQuery('div#attributes_box').empty();
1957
1958
                                                jQuery.each(data, function (key, val) {
1959
1960
                                                    combvalues[val.id] = val.values;
1961
1962
                                                    var span = jQuery(document.createElement('div')).css({
1963
                                                        'display': 'table-row'
1964
                                                    });
1965
1966
                                                    span.append(
1967
                                                            jQuery(document.createElement('div')).text(val.label).css({
1968
                                                        'font-weight': 'bold',
1969
                                                        'display': 'table-cell',
1970
                                                        'text-align': 'right'
1971
                                                    })
1972
                                                            );
1973
1974
                                                    var html = jQuery(document.createElement('select')).attr('name', 'combinations[' + val.id + ']').css({
1975
                                                        'margin-left': '15px',
1976
                                                        'white-space': 'pre'
1977
                                                    }).append(
1978
                                                            jQuery(document.createElement('option')).val('')
1979
                                                            );
1980
1981
                                                    jQuery.each(combvalues[val.id], function (key, val) {
1982
                                                        var tag = jQuery(document.createElement('option')).val(val.id).html(val.value);
1983
1984
                                                        if (selected[val.fk_product_attribute] == val.id) {
1985
                                                            tag.attr('selected', 'selected');
1986
                                                        }
1987
1988
                                                        html.append(tag);
1989
                                                    });
1990
1991
                                                    span.append(html);
1992
                                                    jQuery('div#attributes_box').append(span);
1993
                                                });
1994
                                            })
1995
                                        });
1996
1997
                <?php if ($selected): ?>
1998
                                jQuery("input#<?php echo $htmlname ?>").change();
1999
                <?php endif ?>
2000
                    });
2001
                                </script>
2002
                                <?php
2003
                            }
2004
                            if (empty($hidelabel))
2005
                                print $langs->trans("RefOrLabel") . ' : ';
2006
                            else if ($hidelabel > 1) {
2007
                                $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
2008
                                if ($hidelabel == 2) {
2009
                                    print img_picto($langs->trans("Search"), 'search');
2010
                                }
2011
                            }
2012
                            print '<input type="text" class="minwidth100" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' ' . (!empty($conf->global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '') . ' />';
2013
                            if ($hidelabel == 3) {
2014
                                print img_picto($langs->trans("Search"), 'search');
2015
                            }
2016
                        } else {
2017
                            print $this->select_produits_list($selected, $htmlname, $filtertype, $limit, $price_level, '', $status, $finished, 0, $socid, $showempty, $forcecombo, $morecss, $hidepriceinlabel, $warehouseStatus);
2018
                        }
2019
                    }
2020
2021
                    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2022
                    /**
2023
                     * 	Return list of products for a customer
2024
                     *
2025
                     * 	@param      int		$selected           Preselected product
2026
                     * 	@param      string	$htmlname           Name of select html
2027
                     *  @param		string	$filtertype         Filter on product type (''=nofilter, 0=product, 1=service)
2028
                     * 	@param      int		$limit              Limit on number of returned lines
2029
                     * 	@param      int		$price_level        Level of price to show
2030
                     * 	@param      string	$filterkey          Filter on product
2031
                     * 	@param		int		$status             -1=Return all products, 0=Products not on sell, 1=Products on sell
2032
                     *  @param      int		$finished           Filter on finished field: 2=No filter
2033
                     *  @param      int		$outputmode         0=HTML select string, 1=Array
2034
                     *  @param      int		$socid     		    Thirdparty Id (to get also price dedicated to this customer)
2035
                     *  @param		string	$showempty		    '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
2036
                     * 	@param		int		$forcecombo		    Force to use combo box
2037
                     *  @param      string  $morecss            Add more css on select
2038
                     *  @param      int     $hidepriceinlabel   1=Hide prices in label
2039
                     *  @param      string  $warehouseStatus    warehouse status filter, following comma separated filter options can be used
2040
                     * 										    'warehouseopen' = select products from open warehouses,
2041
                     * 										    'warehouseclosed' = select products from closed warehouses,
2042
                     * 										    'warehouseinternal' = select products from warehouses for internal correct/transfer only
2043
                     *  @return     array    				    Array of keys for json
2044
                     */
2045
                    function select_produits_list($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $filterkey = '', $status = 1, $finished = 2, $outputmode = 0, $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $hidepriceinlabel = 0, $warehouseStatus = '')
2046
    {
2047
        // phpcs:enable
2048
        global $langs, $conf, $user, $db;
2049
2050
        $out = '';
2051
        $outarray = array();
2052
2053
        $warehouseStatusArray = array();
2054
        if (!empty($warehouseStatus)) {
2055
            require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
2056
            if (preg_match('/warehouseclosed/', $warehouseStatus)) {
2057
                $warehouseStatusArray[] = Entrepot::STATUS_CLOSED;
0 ignored issues
show
Bug introduced by
The type Alixar\Base\Entrepot was not found. Did you mean Entrepot? If so, make sure to prefix the type with \.
Loading history...
2058
            }
2059
            if (preg_match('/warehouseopen/', $warehouseStatus)) {
2060
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_ALL;
2061
            }
2062
            if (preg_match('/warehouseinternal/', $warehouseStatus)) {
2063
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_INTERNAL;
2064
            }
2065
        }
2066
2067
        $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression";
2068
        (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock";
2069
2070
        $sql = "SELECT ";
2071
        $sql .= $selectFields . $selectFieldsGrouped;
2072
2073
        if (!empty($conf->global->PRODUCT_SORT_BY_CATEGORY)) {
2074
            //Product category
2075
            $sql .= ", (SELECT " . MAIN_DB_PREFIX . "categorie_product.fk_categorie
2076
						FROM " . MAIN_DB_PREFIX . "categorie_product
2077
						WHERE " . MAIN_DB_PREFIX . "categorie_product.fk_product=p.rowid
2078
						LIMIT 1
2079
				) AS categorie_product_id ";
2080
        }
2081
2082
        //Price by customer
2083
        if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
2084
            $sql .= ', pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
2085
            $sql .= ' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
2086
            $selectFields .= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx";
2087
        }
2088
2089
        // Multilang : we add translation
2090
        if (!empty($conf->global->MAIN_MULTILANGS)) {
2091
            $sql .= ", pl.label as label_translated";
2092
            $selectFields .= ", label_translated";
2093
        }
2094
        // Price by quantity
2095
        if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
2096
            $sql .= ", (SELECT pp.rowid FROM " . MAIN_DB_PREFIX . "product_price as pp WHERE pp.fk_product = p.rowid";
2097
            if ($price_level >= 1 && !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
2098
                $sql .= " AND price_level=" . $price_level;
2099
            $sql .= " ORDER BY date_price";
2100
            $sql .= " DESC LIMIT 1) as price_rowid";
2101
            $sql .= ", (SELECT pp.price_by_qty FROM " . MAIN_DB_PREFIX . "product_price as pp WHERE pp.fk_product = p.rowid"; // price_by_qty is 1 if some prices by qty exists in subtable
2102
            if ($price_level >= 1 && !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
2103
                $sql .= " AND price_level=" . $price_level;
2104
            $sql .= " ORDER BY date_price";
2105
            $sql .= " DESC LIMIT 1) as price_by_qty";
2106
            $selectFields .= ", price_rowid, price_by_qty";
2107
        }
2108
        $sql .= " FROM " . MAIN_DB_PREFIX . "product as p";
2109
        if (count($warehouseStatusArray)) {
2110
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_stock as ps on ps.fk_product = p.rowid";
2111
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entrepot as e on ps.fk_entrepot = e.rowid";
2112
        }
2113
2114
        // include search in supplier ref
2115
        if (!empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF)) {
2116
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2117
        }
2118
2119
        //Price by customer
2120
        if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
2121
            $sql .= " LEFT JOIN  " . MAIN_DB_PREFIX . "product_customer_price as pcp ON pcp.fk_soc=" . $socid . " AND pcp.fk_product=p.rowid";
2122
        }
2123
        // Multilang : we add translation
2124
        if (!empty($conf->global->MAIN_MULTILANGS)) {
2125
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='" . $langs->getDefaultLang() . "'";
2126
        }
2127
2128
        if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
2129
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination pac ON pac.fk_product_child = p.rowid";
2130
        }
2131
2132
        $sql .= ' WHERE p.entity IN (' . getEntity('product') . ')';
2133
        if (count($warehouseStatusArray)) {
2134
            $sql .= ' AND (p.fk_product_type = 1 OR e.statut IN (' . $this->db->escape(implode(',', $warehouseStatusArray)) . '))';
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2135
        }
2136
2137
        if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
2138
            $sql .= " AND pac.rowid IS NULL";
2139
        }
2140
2141
        if ($finished == 0) {
2142
            $sql .= " AND p.finished = " . $finished;
2143
        } elseif ($finished == 1) {
2144
            $sql .= " AND p.finished = " . $finished;
2145
            if ($status >= 0)
2146
                $sql .= " AND p.tosell = " . $status;
2147
        }
2148
        elseif ($status >= 0) {
2149
            $sql .= " AND p.tosell = " . $status;
2150
        }
2151
        if (strval($filtertype) != '')
2152
            $sql .= " AND p.fk_product_type=" . $filtertype;
2153
        // Add criteria on ref/label
2154
        if ($filterkey != '') {
2155
            $sql .= ' AND (';
2156
            $prefix = empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
2157
            // For natural search
2158
            $scrit = explode(' ', $filterkey);
2159
            $i = 0;
2160
            if (count($scrit) > 1)
2161
                $sql .= "(";
2162
            foreach ($scrit as $crit) {
2163
                if ($i > 0)
2164
                    $sql .= " AND ";
2165
                $sql .= "(p.ref LIKE '" . $db->escape($prefix . $crit) . "%' OR p.label LIKE '" . $db->escape($prefix . $crit) . "%'";
2166
                if (!empty($conf->global->MAIN_MULTILANGS))
2167
                    $sql .= " OR pl.label LIKE '" . $db->escape($prefix . $crit) . "%'";
2168
                if (!empty($conf->global->PRODUCT_AJAX_SEARCH_ON_DESCRIPTION)) {
2169
                    $sql .= " OR p.description LIKE '" . $db->escape($prefix . $crit) . "%'";
2170
                    if (!empty($conf->global->MAIN_MULTILANGS))
2171
                        $sql .= " OR pl.description LIKE '" . $db->escape($prefix . $crit) . "%'";
2172
                }
2173
                if (!empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF))
2174
                    $sql .= " OR pfp.ref_fourn LIKE '" . $db->escape($prefix . $crit) . "%'";
2175
                $sql .= ")";
2176
                $i++;
2177
            }
2178
            if (count($scrit) > 1)
2179
                $sql .= ")";
2180
            if (!empty($conf->barcode->enabled))
2181
                $sql .= " OR p.barcode LIKE '" . $db->escape($prefix . $filterkey) . "%'";
2182
            $sql .= ')';
2183
        }
2184
        if (count($warehouseStatusArray)) {
2185
            $sql .= ' GROUP BY' . $selectFields;
2186
        }
2187
2188
        //Sort by category
2189
        if (!empty($conf->global->PRODUCT_SORT_BY_CATEGORY)) {
2190
            $sql .= " ORDER BY categorie_product_id ";
2191
            //ASC OR DESC order
2192
            ($conf->global->PRODUCT_SORT_BY_CATEGORY == 1) ? $sql .= "ASC" : $sql .= "DESC";
2193
        } else {
2194
            $sql .= $db->order("p.ref");
2195
        }
2196
2197
        $sql .= $db->plimit($limit, 0);
2198
2199
        // Build output string
2200
        dol_syslog(get_class($this) . "::select_produits_list search product", LOG_DEBUG);
2201
        $result = $this->db->query($sql);
2202
        if ($result) {
2203
            require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
2204
            require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php';
2205
            $num = $this->db->num_rows($result);
2206
2207
            $events = null;
2208
2209
            if (!$forcecombo) {
2210
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
2211
                $out .= ajax_combobox($htmlname, $events, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT);
2212
            }
2213
2214
            $out .= '<select class="flat' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '" id="' . $htmlname . '">';
2215
2216
            $textifempty = '';
2217
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
2218
            //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
2219
            if (!empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
2220
                if ($showempty && !is_numeric($showempty))
2221
                    $textifempty = $langs->trans($showempty);
2222
                else
2223
                    $textifempty .= $langs->trans("All");
2224
            }
2225
            if ($showempty)
2226
                $out .= '<option value="0" selected>' . $textifempty . '</option>';
2227
2228
            $i = 0;
2229
            while ($num && $i < $num) {
2230
                $opt = '';
2231
                $optJson = array();
2232
                $objp = $this->db->fetch_object($result);
2233
2234
                if ((!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1) { // Price by quantity will return many prices for the same product
2235
                    $sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise, price_base_type";
2236
                    $sql .= " FROM " . MAIN_DB_PREFIX . "product_price_by_qty";
2237
                    $sql .= " WHERE fk_product_price=" . $objp->price_rowid;
2238
                    $sql .= " ORDER BY quantity ASC";
2239
2240
                    dol_syslog(get_class($this) . "::select_produits_list search price by qty", LOG_DEBUG);
2241
                    $result2 = $this->db->query($sql);
2242
                    if ($result2) {
2243
                        $nb_prices = $this->db->num_rows($result2);
2244
                        $j = 0;
2245
                        while ($nb_prices && $j < $nb_prices) {
2246
                            $objp2 = $this->db->fetch_object($result2);
2247
2248
                            $objp->price_by_qty_rowid = $objp2->rowid;
2249
                            $objp->price_by_qty_price_base_type = $objp2->price_base_type;
2250
                            $objp->price_by_qty_quantity = $objp2->quantity;
2251
                            $objp->price_by_qty_unitprice = $objp2->unitprice;
2252
                            $objp->price_by_qty_remise_percent = $objp2->remise_percent;
2253
                            // For backward compatibility
2254
                            $objp->quantity = $objp2->quantity;
2255
                            $objp->price = $objp2->price;
2256
                            $objp->unitprice = $objp2->unitprice;
2257
                            $objp->remise_percent = $objp2->remise_percent;
2258
                            $objp->remise = $objp2->remise;
2259
2260
                            $this->constructProductListOption($objp, $opt, $optJson, 0, $selected, $hidepriceinlabel);
2261
2262
                            $j++;
2263
2264
                            // Add new entry
2265
                            // "key" value of json key array is used by jQuery automatically as selected value
2266
                            // "label" value of json key array is used by jQuery automatically as text for combo box
2267
                            $out .= $opt;
2268
                            array_push($outarray, $optJson);
2269
                        }
2270
                    }
2271
                } else {
2272
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_price_expression)) {
2273
                        $price_product = new Product($this->db);
2274
                        $price_product->fetch($objp->rowid, '', '', 1);
2275
                        $priceparser = new PriceParser($this->db);
0 ignored issues
show
Bug introduced by
The type Alixar\Base\PriceParser was not found. Did you mean PriceParser? If so, make sure to prefix the type with \.
Loading history...
2276
                        $price_result = $priceparser->parseProduct($price_product);
2277
                        if ($price_result >= 0) {
2278
                            $objp->price = $price_result;
2279
                            $objp->unitprice = $price_result;
2280
                            //Calculate the VAT
2281
                            $objp->price_ttc = price2num($objp->price) * (1 + ($objp->tva_tx / 100));
2282
                            $objp->price_ttc = price2num($objp->price_ttc, 'MU');
2283
                        }
2284
                    }
2285
                    $this->constructProductListOption($objp, $opt, $optJson, $price_level, $selected, $hidepriceinlabel);
2286
                    // Add new entry
2287
                    // "key" value of json key array is used by jQuery automatically as selected value
2288
                    // "label" value of json key array is used by jQuery automatically as text for combo box
2289
                    $out .= $opt;
2290
                    array_push($outarray, $optJson);
2291
                }
2292
2293
                $i++;
2294
            }
2295
2296
            $out .= '</select>';
2297
2298
            $this->db->free($result);
2299
2300
            if (empty($outputmode))
2301
                return $out;
2302
            return $outarray;
2303
        }
2304
        else {
2305
            dol_print_error($db);
2306
        }
2307
    }
2308
2309
    /**
2310
     * constructProductListOption
2311
     *
2312
     * @param 	resultset	$objp			    Resultset of fetch
2313
     * @param 	string		$opt			    Option (var used for returned value in string option format)
2314
     * @param 	string		$optJson		    Option (var used for returned value in json format)
2315
     * @param 	int			$price_level	    Price level
2316
     * @param 	string		$selected		    Preselected value
2317
     * @param   int         $hidepriceinlabel   Hide price in label
2318
     * @return	void
2319
     */
2320
    private function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0)
2321
    {
2322
        global $langs, $conf, $user, $db;
2323
2324
        $outkey = '';
2325
        $outval = '';
2326
        $outref = '';
2327
        $outlabel = '';
2328
        $outdesc = '';
2329
        $outbarcode = '';
2330
        $outtype = '';
2331
        $outprice_ht = '';
2332
        $outprice_ttc = '';
2333
        $outpricebasetype = '';
2334
        $outtva_tx = '';
2335
        $outqty = 1;
2336
        $outdiscount = 0;
2337
2338
        $maxlengtharticle = (empty($conf->global->PRODUCT_MAX_LENGTH_COMBO) ? 48 : $conf->global->PRODUCT_MAX_LENGTH_COMBO);
2339
2340
        $label = $objp->label;
2341
        if (!empty($objp->label_translated))
2342
            $label = $objp->label_translated;
2343
        if (!empty($filterkey) && $filterkey != '')
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $filterkey seems to never exist and therefore empty should always be true.
Loading history...
2344
            $label = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $label, 1);
2345
2346
        $outkey = $objp->rowid;
2347
        $outref = $objp->ref;
2348
        $outlabel = $objp->label;
2349
        $outdesc = $objp->description;
2350
        $outbarcode = $objp->barcode;
2351
2352
        $outtype = $objp->fk_product_type;
2353
        $outdurationvalue = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : '';
2354
        $outdurationunit = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, -1) : '';
2355
2356
        $opt = '<option value="' . $objp->rowid . '"';
2357
        $opt .= ($objp->rowid == $selected) ? ' selected' : '';
2358
        if (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0) {
2359
            $opt .= ' pbq="' . $objp->price_by_qty_rowid . '" data-pbq="' . $objp->price_by_qty_rowid . '" data-pbqqty="' . $objp->price_by_qty_quantity . '" data-pbqpercent="' . $objp->price_by_qty_remise_percent . '"';
2360
        }
2361
        if (!empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock)) {
2362
            if ($objp->stock > 0)
2363
                $opt .= ' class="product_line_stock_ok"';
2364
            else if ($objp->stock <= 0)
2365
                $opt .= ' class="product_line_stock_too_low"';
2366
        }
2367
        $opt .= '>';
2368
        $opt .= $objp->ref;
2369
        if ($outbarcode)
2370
            $opt .= ' (' . $outbarcode . ')';
2371
        $opt .= ' - ' . dol_trunc($label, $maxlengtharticle);
2372
2373
        $objRef = $objp->ref;
2374
        if (!empty($filterkey) && $filterkey != '')
2375
            $objRef = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRef, 1);
2376
        $outval .= $objRef;
2377
        if ($outbarcode)
2378
            $outval .= ' (' . $outbarcode . ')';
2379
        $outval .= ' - ' . dol_trunc($label, $maxlengtharticle);
2380
2381
        $found = 0;
2382
2383
        // Multiprice
2384
        // If we need a particular price level (from 1 to 6)
2385
        if (empty($hidepriceinlabel) && $price_level >= 1 && (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))) {
2386
            $sql = "SELECT price, price_ttc, price_base_type, tva_tx";
2387
            $sql .= " FROM " . MAIN_DB_PREFIX . "product_price";
2388
            $sql .= " WHERE fk_product='" . $objp->rowid . "'";
2389
            $sql .= " AND entity IN (" . getEntity('productprice') . ")";
2390
            $sql .= " AND price_level=" . $price_level;
2391
            $sql .= " ORDER BY date_price DESC, rowid DESC"; // Warning DESC must be both on date_price and rowid.
2392
            $sql .= " LIMIT 1";
2393
2394
            dol_syslog(get_class($this) . '::constructProductListOption search price for level ' . $price_level . '', LOG_DEBUG);
2395
            $result2 = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2396
            if ($result2) {
2397
                $objp2 = $this->db->fetch_object($result2);
2398
                if ($objp2) {
2399
                    $found = 1;
2400
                    if ($objp2->price_base_type == 'HT') {
2401
                        $opt .= ' - ' . price($objp2->price, 1, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->trans("HT");
2402
                        $outval .= ' - ' . price($objp2->price, 0, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->transnoentities("HT");
2403
                    } else {
2404
                        $opt .= ' - ' . price($objp2->price_ttc, 1, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->trans("TTC");
2405
                        $outval .= ' - ' . price($objp2->price_ttc, 0, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->transnoentities("TTC");
2406
                    }
2407
                    $outprice_ht = price($objp2->price);
2408
                    $outprice_ttc = price($objp2->price_ttc);
2409
                    $outpricebasetype = $objp2->price_base_type;
2410
                    $outtva_tx = $objp2->tva_tx;
2411
                }
2412
            } else {
2413
                dol_print_error($this->db);
2414
            }
2415
        }
2416
2417
        // Price by quantity
2418
        if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1 && (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))) {
2419
            $found = 1;
2420
            $outqty = $objp->quantity;
2421
            $outdiscount = $objp->remise_percent;
2422
            if ($objp->quantity == 1) {
2423
                $opt .= ' - ' . price($objp->unitprice, 1, $langs, 0, 0, -1, $conf->currency) . "/";
2424
                $outval .= ' - ' . price($objp->unitprice, 0, $langs, 0, 0, -1, $conf->currency) . "/";
2425
                $opt .= $langs->trans("Unit"); // Do not use strtolower because it breaks utf8 encoding
2426
                $outval .= $langs->transnoentities("Unit");
2427
            } else {
2428
                $opt .= ' - ' . price($objp->price, 1, $langs, 0, 0, -1, $conf->currency) . "/" . $objp->quantity;
2429
                $outval .= ' - ' . price($objp->price, 0, $langs, 0, 0, -1, $conf->currency) . "/" . $objp->quantity;
2430
                $opt .= $langs->trans("Units"); // Do not use strtolower because it breaks utf8 encoding
2431
                $outval .= $langs->transnoentities("Units");
2432
            }
2433
2434
            $outprice_ht = price($objp->unitprice);
2435
            $outprice_ttc = price($objp->unitprice * (1 + ($objp->tva_tx / 100)));
2436
            $outpricebasetype = $objp->price_base_type;
2437
            $outtva_tx = $objp->tva_tx;
2438
        }
2439
        if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1) {
2440
            $opt .= " (" . price($objp->unitprice, 1, $langs, 0, 0, -1, $conf->currency) . "/" . $langs->trans("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2441
            $outval .= " (" . price($objp->unitprice, 0, $langs, 0, 0, -1, $conf->currency) . "/" . $langs->transnoentities("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2442
        }
2443
        if (empty($hidepriceinlabel) && !empty($objp->remise_percent) && $objp->remise_percent >= 1) {
2444
            $opt .= " - " . $langs->trans("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2445
            $outval .= " - " . $langs->transnoentities("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2446
        }
2447
2448
        // Price by customer
2449
        if (empty($hidepriceinlabel) && !empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
2450
            if (!empty($objp->idprodcustprice)) {
2451
                $found = 1;
2452
2453
                if ($objp->custprice_base_type == 'HT') {
2454
                    $opt .= ' - ' . price($objp->custprice, 1, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->trans("HT");
2455
                    $outval .= ' - ' . price($objp->custprice, 0, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->transnoentities("HT");
2456
                } else {
2457
                    $opt .= ' - ' . price($objp->custprice_ttc, 1, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->trans("TTC");
2458
                    $outval .= ' - ' . price($objp->custprice_ttc, 0, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->transnoentities("TTC");
2459
                }
2460
2461
                $outprice_ht = price($objp->custprice);
2462
                $outprice_ttc = price($objp->custprice_ttc);
2463
                $outpricebasetype = $objp->custprice_base_type;
2464
                $outtva_tx = $objp->custtva_tx;
2465
            }
2466
        }
2467
2468
        // If level no defined or multiprice not found, we used the default price
2469
        if (empty($hidepriceinlabel) && !$found) {
2470
            if ($objp->price_base_type == 'HT') {
2471
                $opt .= ' - ' . price($objp->price, 1, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->trans("HT");
2472
                $outval .= ' - ' . price($objp->price, 0, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->transnoentities("HT");
2473
            } else {
2474
                $opt .= ' - ' . price($objp->price_ttc, 1, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->trans("TTC");
2475
                $outval .= ' - ' . price($objp->price_ttc, 0, $langs, 0, 0, -1, $conf->currency) . ' ' . $langs->transnoentities("TTC");
2476
            }
2477
            $outprice_ht = price($objp->price);
2478
            $outprice_ttc = price($objp->price_ttc);
2479
            $outpricebasetype = $objp->price_base_type;
2480
            $outtva_tx = $objp->tva_tx;
2481
        }
2482
2483
        if (!empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0) {
2484
            $opt .= ' - ' . $langs->trans("Stock") . ':' . $objp->stock;
2485
2486
            if ($objp->stock > 0) {
2487
                $outval .= ' - <span class="product_line_stock_ok">' . $langs->transnoentities("Stock") . ':' . $objp->stock . '</span>';
2488
            } elseif ($objp->stock <= 0) {
2489
                $outval .= ' - <span class="product_line_stock_too_low">' . $langs->transnoentities("Stock") . ':' . $objp->stock . '</span>';
2490
            }
2491
        }
2492
2493
        if ($outdurationvalue && $outdurationunit) {
2494
            $da = array("h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year"));
2495
            if (isset($da[$outdurationunit])) {
2496
                $key = $da[$outdurationunit] . ($outdurationvalue > 1 ? 's' : '');
2497
                $opt .= ' - ' . $outdurationvalue . ' ' . $langs->trans($key);
2498
                $outval .= ' - ' . $outdurationvalue . ' ' . $langs->transnoentities($key);
2499
            }
2500
        }
2501
2502
        $opt .= "</option>\n";
2503
        $optJson = array('key' => $outkey, 'value' => $outref, 'label' => $outval, 'label2' => $outlabel, 'desc' => $outdesc, 'type' => $outtype, 'price_ht' => $outprice_ht, 'price_ttc' => $outprice_ttc, 'pricebasetype' => $outpricebasetype, 'tva_tx' => $outtva_tx, 'qty' => $outqty, 'discount' => $outdiscount, 'duration_value' => $outdurationvalue, 'duration_unit' => $outdurationunit);
2504
    }
2505
2506
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2507
    /**
2508
     * 	Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list)
2509
     *
2510
     * 	@param	int		$socid			Id third party
2511
     * 	@param  string	$selected       Preselected product
2512
     * 	@param  string	$htmlname       Name of HTML Select
2513
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2514
     * 	@param  string	$filtre			For a SQL filter
2515
     * 	@param	array	$ajaxoptions	Options for ajax_autocompleter
2516
     *  @param	int		$hidelabel		Hide label (0=no, 1=yes)
2517
     *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2518
     * 	@return	void
2519
     */
2520
    function select_produits_fournisseurs($socid, $selected = '', $htmlname = 'productid', $filtertype = '', $filtre = '', $ajaxoptions = array(), $hidelabel = 0, $alsoproductwithnosupplierprice = 0)
2521
    {
2522
        // phpcs:enable
2523
        global $langs, $conf;
2524
        global $price_level, $status, $finished;
2525
2526
        $selected_input_value = '';
2527
        if (!empty($conf->use_javascript_ajax) && !empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
2528
            if ($selected > 0) {
2529
                require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
2530
                $producttmpselect = new Product($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2531
                $producttmpselect->fetch($selected);
2532
                $selected_input_value = $producttmpselect->ref;
2533
                unset($producttmpselect);
2534
            }
2535
2536
            // mode=2 means suppliers products
2537
            $urloption = ($socid > 0 ? 'socid=' . $socid . '&' : '') . 'htmlname=' . $htmlname . '&outjson=1&price_level=' . $price_level . '&type=' . $filtertype . '&mode=2&status=' . $status . '&finished=' . $finished . '&alsoproductwithnosupplierprice=' . $alsoproductwithnosupplierprice;
2538
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
2539
            print ($hidelabel ? '' : $langs->trans("RefOrLabel") . ' : ') . '<input type="text" size="20" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $selected_input_value . '">';
2540
        } else {
2541
            print $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $filtre, '', -1, 0, 0, $alsoproductwithnosupplierprice);
2542
        }
2543
    }
2544
2545
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2546
    /**
2547
     * 	Return list of suppliers products
2548
     *
2549
     * 	@param	int		$socid   		Id societe fournisseur (0 pour aucun filtre)
2550
     * 	@param  int		$selected       Product price pre-selected (must be 'id' in product_fournisseur_price or 'idprod_IDPROD')
2551
     * 	@param  string	$htmlname       Nom de la zone select
2552
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2553
     * 	@param  string	$filtre         Pour filtre sql
2554
     * 	@param  string	$filterkey      Filtre des produits
2555
     *  @param  int		$statut         -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request)
2556
     *  @param  int		$outputmode     0=HTML select string, 1=Array
2557
     *  @param  int     $limit          Limit of line number
2558
     *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2559
     *  @return array           		Array of keys for json
2560
     */
2561
    function select_produits_fournisseurs_list($socid, $selected = '', $htmlname = 'productid', $filtertype = '', $filtre = '', $filterkey = '', $statut = -1, $outputmode = 0, $limit = 100, $alsoproductwithnosupplierprice = 0)
2562
    {
2563
        // phpcs:enable
2564
        global $langs, $conf, $db;
2565
2566
        $out = '';
2567
        $outarray = array();
2568
2569
        $langs->load('stocks');
2570
2571
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,";
2572
        $sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
2573
        $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
2574
        $sql .= " pfp.supplier_reputation";
2575
        $sql .= " FROM " . MAIN_DB_PREFIX . "product as p";
2576
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2577
        if ($socid)
2578
            $sql .= " AND pfp.fk_soc = " . $socid;
2579
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON pfp.fk_soc = s.rowid";
2580
        $sql .= " WHERE p.entity IN (" . getEntity('product') . ")";
2581
        $sql .= " AND p.tobuy = 1";
2582
        if (strval($filtertype) != '')
2583
            $sql .= " AND p.fk_product_type=" . $this->db->escape($filtertype);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2584
        if (!empty($filtre))
2585
            $sql .= " " . $filtre;
2586
        // Add criteria on ref/label
2587
        if ($filterkey != '') {
2588
            $sql .= ' AND (';
2589
            $prefix = empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
2590
            // For natural search
2591
            $scrit = explode(' ', $filterkey);
2592
            $i = 0;
2593
            if (count($scrit) > 1)
2594
                $sql .= "(";
2595
            foreach ($scrit as $crit) {
2596
                if ($i > 0)
2597
                    $sql .= " AND ";
2598
                $sql .= "(pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%' OR p.ref LIKE '" . $this->db->escape($prefix . $crit) . "%' OR p.label LIKE '" . $this->db->escape($prefix . $crit) . "%')";
2599
                $i++;
2600
            }
2601
            if (count($scrit) > 1)
2602
                $sql .= ")";
2603
            if (!empty($conf->barcode->enabled))
2604
                $sql .= " OR p.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%'";
2605
            $sql .= ')';
2606
        }
2607
        $sql .= " ORDER BY pfp.ref_fourn DESC, pfp.quantity ASC";
2608
        $sql .= $db->plimit($limit, 0);
2609
2610
        // Build output string
2611
2612
        dol_syslog(get_class($this) . "::select_produits_fournisseurs_list", LOG_DEBUG);
2613
        $result = $this->db->query($sql);
2614
        if ($result) {
2615
            require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php';
2616
2617
            $num = $this->db->num_rows($result);
2618
2619
            //$out.='<select class="flat" id="select'.$htmlname.'" name="'.$htmlname.'">';	// remove select to have id same with combo and ajax
2620
            $out .= '<select class="flat maxwidthonsmartphone" id="' . $htmlname . '" name="' . $htmlname . '">';
2621
            if (!$selected)
2622
                $out .= '<option value="0" selected>&nbsp;</option>';
2623
            else
2624
                $out .= '<option value="0">&nbsp;</option>';
2625
2626
            $i = 0;
2627
            while ($i < $num) {
2628
                $objp = $this->db->fetch_object($result);
2629
2630
                $outkey = $objp->idprodfournprice;                                                    // id in table of price
2631
                if (!$outkey && $alsoproductwithnosupplierprice)
2632
                    $outkey = 'idprod_' . $objp->rowid;   // id of product
2633
2634
                $outref = $objp->ref;
2635
                $outval = '';
2636
                $outqty = 1;
2637
                $outdiscount = 0;
2638
                $outtype = $objp->fk_product_type;
2639
                $outdurationvalue = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : '';
2640
                $outdurationunit = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, -1) : '';
2641
2642
                $opt = '<option value="' . $outkey . '"';
2643
                if ($selected && $selected == $objp->idprodfournprice)
2644
                    $opt .= ' selected';
2645
                if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice))
2646
                    $opt .= ' disabled';
2647
                if (!empty($objp->idprodfournprice) && $objp->idprodfournprice > 0) {
2648
                    $opt .= ' pbq="' . $objp->idprodfournprice . '" data-pbq="' . $objp->idprodfournprice . '" data-pbqqty="' . $objp->quantity . '" data-pbqpercent="' . $objp->remise_percent . '"';
2649
                }
2650
                $opt .= '>';
2651
2652
                $objRef = $objp->ref;
2653
                if ($filterkey && $filterkey != '')
2654
                    $objRef = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRef, 1);
2655
                $objRefFourn = $objp->ref_fourn;
2656
                if ($filterkey && $filterkey != '')
2657
                    $objRefFourn = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRefFourn, 1);
2658
                $label = $objp->label;
2659
                if ($filterkey && $filterkey != '')
2660
                    $label = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $label, 1);
2661
2662
                $opt .= $objp->ref;
2663
                if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2664
                    $opt .= ' (' . $objp->ref_fourn . ')';
2665
                $opt .= ' - ';
2666
                $outval .= $objRef;
2667
                if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2668
                    $outval .= ' (' . $objRefFourn . ')';
2669
                $outval .= ' - ';
2670
                $opt .= dol_trunc($label, 72) . ' - ';
2671
                $outval .= dol_trunc($label, 72) . ' - ';
2672
2673
                if (!empty($objp->idprodfournprice)) {
2674
                    $outqty = $objp->quantity;
2675
                    $outdiscount = $objp->remise_percent;
2676
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2677
                        $prod_supplier = new ProductFournisseur($this->db);
0 ignored issues
show
Bug introduced by
The type Alixar\Base\ProductFournisseur was not found. Did you mean ProductFournisseur? If so, make sure to prefix the type with \.
Loading history...
2678
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2679
                        $prod_supplier->id = $objp->fk_product;
2680
                        $prod_supplier->fourn_qty = $objp->quantity;
2681
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2682
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2683
                        $priceparser = new PriceParser($this->db);
2684
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2685
                        if ($price_result >= 0) {
2686
                            $objp->fprice = $price_result;
2687
                            if ($objp->quantity >= 1) {
2688
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2689
                            }
2690
                        }
2691
                    }
2692
                    if ($objp->quantity == 1) {
2693
                        $opt .= price($objp->fprice, 1, $langs, 0, 0, -1, $conf->currency) . "/";
2694
                        $outval .= price($objp->fprice, 0, $langs, 0, 0, -1, $conf->currency) . "/";
2695
                        $opt .= $langs->trans("Unit"); // Do not use strtolower because it breaks utf8 encoding
2696
                        $outval .= $langs->transnoentities("Unit");
2697
                    } else {
2698
                        $opt .= price($objp->fprice, 1, $langs, 0, 0, -1, $conf->currency) . "/" . $objp->quantity;
2699
                        $outval .= price($objp->fprice, 0, $langs, 0, 0, -1, $conf->currency) . "/" . $objp->quantity;
2700
                        $opt .= ' ' . $langs->trans("Units"); // Do not use strtolower because it breaks utf8 encoding
2701
                        $outval .= ' ' . $langs->transnoentities("Units");
2702
                    }
2703
2704
                    if ($objp->quantity >= 1) {
2705
                        $opt .= " (" . price($objp->unitprice, 1, $langs, 0, 0, -1, $conf->currency) . "/" . $langs->trans("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2706
                        $outval .= " (" . price($objp->unitprice, 0, $langs, 0, 0, -1, $conf->currency) . "/" . $langs->transnoentities("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2707
                    }
2708
                    if ($objp->remise_percent >= 1) {
2709
                        $opt .= " - " . $langs->trans("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2710
                        $outval .= " - " . $langs->transnoentities("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2711
                    }
2712
                    if ($objp->duration) {
2713
                        $opt .= " - " . $objp->duration;
2714
                        $outval .= " - " . $objp->duration;
2715
                    }
2716
                    if (!$socid) {
2717
                        $opt .= " - " . dol_trunc($objp->name, 8);
2718
                        $outval .= " - " . dol_trunc($objp->name, 8);
2719
                    }
2720
                    if ($objp->supplier_reputation) {
2721
                        //TODO dictionary
2722
                        $reputations = array('' => $langs->trans('Standard'), 'FAVORITE' => $langs->trans('Favorite'), 'NOTTHGOOD' => $langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER' => $langs->trans('DoNotOrderThisProductToThisSupplier'));
2723
2724
                        $opt .= " - " . $reputations[$objp->supplier_reputation];
2725
                        $outval .= " - " . $reputations[$objp->supplier_reputation];
2726
                    }
2727
                } else {
2728
                    if (empty($alsoproductwithnosupplierprice)) {     // No supplier price defined for couple product/supplier
2729
                        $opt .= $langs->trans("NoPriceDefinedForThisSupplier");
2730
                        $outval .= $langs->transnoentities("NoPriceDefinedForThisSupplier");
2731
                    } else {                                            // No supplier price defined for product, even on other suppliers
2732
                        $opt .= $langs->trans("NoPriceDefinedForThisSupplier");
2733
                        $outval .= $langs->transnoentities("NoPriceDefinedForThisSupplier");
2734
                    }
2735
                }
2736
                $opt .= "</option>\n";
2737
2738
2739
                // Add new entry
2740
                // "key" value of json key array is used by jQuery automatically as selected value
2741
                // "label" value of json key array is used by jQuery automatically as text for combo box
2742
                $out .= $opt;
2743
                array_push($outarray, array('key' => $outkey, 'value' => $outref, 'label' => $outval, 'qty' => $outqty, 'discount' => $outdiscount, 'type' => $outtype, 'duration_value' => $outdurationvalue, 'duration_unit' => $outdurationunit, 'disabled' => (empty($objp->idprodfournprice) ? true : false)));
2744
                // Exemple of var_dump $outarray
2745
                // array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp"
2746
                //           ["label"]=>string(76) "ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)"
2747
                //      	 ["qty"]=>string(1) "1" ["discount"]=>string(1) "0" ["disabled"]=>bool(false)
2748
                //}
2749
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2750
                //$outval=array('label'=>'ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/ Unité (20,00 Euros/unité)');
2751
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2752
2753
                $i++;
2754
            }
2755
            $out .= '</select>';
2756
2757
            $this->db->free($result);
2758
2759
            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
2760
            $out .= ajax_combobox($htmlname);
2761
2762
            if (empty($outputmode))
2763
                return $out;
2764
            return $outarray;
2765
        }
2766
        else {
2767
            dol_print_error($this->db);
2768
        }
2769
    }
2770
2771
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2772
    /**
2773
     * 	Return list of suppliers prices for a product
2774
     *
2775
     *  @param	    int		$productid       	Id of product
2776
     *  @param      string	$htmlname        	Name of HTML field
2777
     *  @param      int		$selected_supplier  Pre-selected supplier if more than 1 result
2778
     *  @return	    void
2779
     */
2780
    function select_product_fourn_price($productid, $htmlname = 'productfournpriceid', $selected_supplier = '')
2781
    {
2782
        // phpcs:enable
2783
        global $langs, $conf;
2784
2785
        $langs->load('stocks');
2786
2787
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,";
2788
        $sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice,";
2789
        $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name";
2790
        $sql .= " FROM " . MAIN_DB_PREFIX . "product as p";
2791
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2792
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON pfp.fk_soc = s.rowid";
2793
        $sql .= " WHERE pfp.entity IN (" . getEntity('productsupplierprice') . ")";
2794
        $sql .= " AND p.tobuy = 1";
2795
        $sql .= " AND s.fournisseur = 1";
2796
        $sql .= " AND p.rowid = " . $productid;
2797
        $sql .= " ORDER BY s.nom, pfp.ref_fourn DESC";
2798
2799
        dol_syslog(get_class($this) . "::select_product_fourn_price", LOG_DEBUG);
2800
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2801
2802
        if ($result) {
2803
            $num = $this->db->num_rows($result);
2804
2805
            $form = '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
2806
2807
            if (!$num) {
2808
                $form .= '<option value="0">-- ' . $langs->trans("NoSupplierPriceDefinedForThisProduct") . ' --</option>';
2809
            } else {
2810
                require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php';
2811
                $form .= '<option value="0">&nbsp;</option>';
2812
2813
                $i = 0;
2814
                while ($i < $num) {
2815
                    $objp = $this->db->fetch_object($result);
2816
2817
                    $opt = '<option value="' . $objp->idprodfournprice . '"';
2818
                    //if there is only one supplier, preselect it
2819
                    if ($num == 1 || ($selected_supplier > 0 && $objp->fk_soc == $selected_supplier)) {
2820
                        $opt .= ' selected';
2821
                    }
2822
                    $opt .= '>' . $objp->name . ' - ' . $objp->ref_fourn . ' - ';
2823
2824
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2825
                        $prod_supplier = new ProductFournisseur($this->db);
2826
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2827
                        $prod_supplier->id = $productid;
2828
                        $prod_supplier->fourn_qty = $objp->quantity;
2829
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2830
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2831
                        $priceparser = new PriceParser($this->db);
2832
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2833
                        if ($price_result >= 0) {
2834
                            $objp->fprice = $price_result;
2835
                            if ($objp->quantity >= 1) {
2836
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2837
                            }
2838
                        }
2839
                    }
2840
                    if ($objp->quantity == 1) {
2841
                        $opt .= price($objp->fprice, 1, $langs, 0, 0, -1, $conf->currency) . "/";
2842
                    }
2843
2844
                    $opt .= $objp->quantity . ' ';
2845
2846
                    if ($objp->quantity == 1) {
2847
                        $opt .= $langs->trans("Unit");
2848
                    } else {
2849
                        $opt .= $langs->trans("Units");
2850
                    }
2851
                    if ($objp->quantity > 1) {
2852
                        $opt .= " - ";
2853
                        $opt .= price($objp->unitprice, 1, $langs, 0, 0, -1, $conf->currency) . "/" . $langs->trans("Unit");
2854
                    }
2855
                    if ($objp->duration)
2856
                        $opt .= " - " . $objp->duration;
2857
                    $opt .= "</option>\n";
2858
2859
                    $form .= $opt;
2860
                    $i++;
2861
                }
2862
            }
2863
2864
            $form .= '</select>';
2865
            $this->db->free($result);
2866
            return $form;
2867
        }
2868
        else {
2869
            dol_print_error($this->db);
2870
        }
2871
    }
2872
2873
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2874
    /**
2875
     *    Return list of delivery address
2876
     *
2877
     *    @param    string	$selected          	Id contact pre-selectionn
2878
     *    @param    int		$socid				Id of company
2879
     *    @param    string	$htmlname          	Name of HTML field
2880
     *    @param    int		$showempty         	Add an empty field
2881
     *    @return	integer|null
2882
     */
2883
    function select_address($selected, $socid, $htmlname = 'address_id', $showempty = 0)
2884
    {
2885
        // phpcs:enable
2886
        // looking for users
2887
        $sql = "SELECT a.rowid, a.label";
2888
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe_address as a";
2889
        $sql .= " WHERE a.fk_soc = " . $socid;
2890
        $sql .= " ORDER BY a.label ASC";
2891
2892
        dol_syslog(get_class($this) . "::select_address", LOG_DEBUG);
2893
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2894
        if ($resql) {
2895
            print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
2896
            if ($showempty)
2897
                print '<option value="0">&nbsp;</option>';
2898
            $num = $this->db->num_rows($resql);
2899
            $i = 0;
2900
            if ($num) {
2901
                while ($i < $num) {
2902
                    $obj = $this->db->fetch_object($resql);
2903
2904
                    if ($selected && $selected == $obj->rowid) {
2905
                        print '<option value="' . $obj->rowid . '" selected>' . $obj->label . '</option>';
2906
                    } else {
2907
                        print '<option value="' . $obj->rowid . '">' . $obj->label . '</option>';
2908
                    }
2909
                    $i++;
2910
                }
2911
            }
2912
            print '</select>';
2913
            return $num;
2914
        } else {
2915
            dol_print_error($this->db);
2916
        }
2917
    }
2918
2919
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2920
    /**
2921
     *      Load into cache list of payment terms
2922
     *
2923
     *      @return     int             Nb of lines loaded, <0 if KO
2924
     */
2925
    function load_cache_conditions_paiements()
2926
    {
2927
        // phpcs:enable
2928
        global $langs;
2929
2930
        $num = count($this->cache_conditions_paiements);
2931
        if ($num > 0)
2932
            return 0;    // Cache already loaded
2933
2934
        dol_syslog(__METHOD__, LOG_DEBUG);
2935
2936
        $sql = "SELECT rowid, code, libelle as label";
2937
        $sql .= " FROM " . MAIN_DB_PREFIX . 'c_payment_term';
2938
        $sql .= " WHERE entity IN (" . getEntity('c_payment_term') . ")";
2939
        $sql .= " AND active > 0";
2940
        $sql .= " ORDER BY sortorder";
2941
2942
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2943
        if ($resql) {
2944
            $num = $this->db->num_rows($resql);
2945
            $i = 0;
2946
            while ($i < $num) {
2947
                $obj = $this->db->fetch_object($resql);
2948
2949
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2950
                $label = ($langs->trans("PaymentConditionShort" . $obj->code) != ("PaymentConditionShort" . $obj->code) ? $langs->trans("PaymentConditionShort" . $obj->code) : ($obj->label != '-' ? $obj->label : ''));
2951
                $this->cache_conditions_paiements[$obj->rowid]['code'] = $obj->code;
2952
                $this->cache_conditions_paiements[$obj->rowid]['label'] = $label;
2953
                $i++;
2954
            }
2955
2956
            //$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label', 'asc', 0, 0, 1);		// We use the field sortorder of table
2957
2958
            return $num;
2959
        } else {
2960
            dol_print_error($this->db);
2961
            return -1;
2962
        }
2963
    }
2964
2965
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2966
    /**
2967
     *      Charge dans cache la liste des délais de livraison possibles
2968
     *
2969
     *      @return     int             Nb of lines loaded, <0 if KO
2970
     */
2971
    function load_cache_availability()
2972
    {
2973
        // phpcs:enable
2974
        global $langs;
2975
2976
        $num = count($this->cache_availability);
2977
        if ($num > 0)
2978
            return 0;    // Cache already loaded
2979
2980
        dol_syslog(__METHOD__, LOG_DEBUG);
2981
2982
        $langs->load('propal');
2983
2984
        $sql = "SELECT rowid, code, label";
2985
        $sql .= " FROM " . MAIN_DB_PREFIX . 'c_availability';
2986
        $sql .= " WHERE active > 0";
2987
2988
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2989
        if ($resql) {
2990
            $num = $this->db->num_rows($resql);
2991
            $i = 0;
2992
            while ($i < $num) {
2993
                $obj = $this->db->fetch_object($resql);
2994
2995
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2996
                $label = ($langs->trans("AvailabilityType" . $obj->code) != ("AvailabilityType" . $obj->code) ? $langs->trans("AvailabilityType" . $obj->code) : ($obj->label != '-' ? $obj->label : ''));
2997
                $this->cache_availability[$obj->rowid]['code'] = $obj->code;
2998
                $this->cache_availability[$obj->rowid]['label'] = $label;
2999
                $i++;
3000
            }
3001
3002
            $this->cache_availability = dol_sort_array($this->cache_availability, 'label', 'asc', 0, 0, 1);
3003
3004
            return $num;
3005
        } else {
3006
            dol_print_error($this->db);
3007
            return -1;
3008
        }
3009
    }
3010
3011
    /**
3012
     *      Retourne la liste des types de delais de livraison possibles
3013
     *
3014
     *      @param	int		$selected        Id du type de delais pre-selectionne
3015
     *      @param  string	$htmlname        Nom de la zone select
3016
     *      @param  string	$filtertype      To add a filter
3017
     * 		@param	int		$addempty		Add empty entry
3018
     * 		@return	void
3019
     */
3020
    function selectAvailabilityDelay($selected = '', $htmlname = 'availid', $filtertype = '', $addempty = 0)
3021
    {
3022
        global $langs, $user;
3023
3024
        $this->load_cache_availability();
3025
3026
        dol_syslog(__METHOD__ . " selected=" . $selected . ", htmlname=" . $htmlname, LOG_DEBUG);
3027
3028
        print '<select id="' . $htmlname . '" class="flat" name="' . $htmlname . '">';
3029
        if ($addempty)
3030
            print '<option value="0">&nbsp;</option>';
3031
        foreach ($this->cache_availability as $id => $arrayavailability) {
3032
            if ($selected == $id) {
3033
                print '<option value="' . $id . '" selected>';
3034
            } else {
3035
                print '<option value="' . $id . '">';
3036
            }
3037
            print $arrayavailability['label'];
3038
            print '</option>';
3039
        }
3040
        print '</select>';
3041
        if ($user->admin)
3042
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3043
    }
3044
3045
    /**
3046
     *      Load into cache cache_demand_reason, array of input reasons
3047
     *
3048
     *      @return     int             Nb of lines loaded, <0 if KO
3049
     */
3050
    function loadCacheInputReason()
3051
    {
3052
        global $langs;
3053
3054
        $num = count($this->cache_demand_reason);
3055
        if ($num > 0)
3056
            return 0;    // Cache already loaded
3057
3058
        $sql = "SELECT rowid, code, label";
3059
        $sql .= " FROM " . MAIN_DB_PREFIX . 'c_input_reason';
3060
        $sql .= " WHERE active > 0";
3061
3062
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3063
        if ($resql) {
3064
            $num = $this->db->num_rows($resql);
3065
            $i = 0;
3066
            $tmparray = array();
3067
            while ($i < $num) {
3068
                $obj = $this->db->fetch_object($resql);
3069
3070
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
3071
                $label = ($obj->label != '-' ? $obj->label : '');
3072
                if ($langs->trans("DemandReasonType" . $obj->code) != ("DemandReasonType" . $obj->code))
3073
                    $label = $langs->trans("DemandReasonType" . $obj->code); // So translation key DemandReasonTypeSRC_XXX will work
3074
                if ($langs->trans($obj->code) != $obj->code)
3075
                    $label = $langs->trans($obj->code);                // So translation key SRC_XXX will work
3076
3077
                $tmparray[$obj->rowid]['id'] = $obj->rowid;
3078
                $tmparray[$obj->rowid]['code'] = $obj->code;
3079
                $tmparray[$obj->rowid]['label'] = $label;
3080
                $i++;
3081
            }
3082
3083
            $this->cache_demand_reason = dol_sort_array($tmparray, 'label', 'asc', 0, 0, 1);
3084
3085
            unset($tmparray);
3086
            return $num;
3087
        }
3088
        else {
3089
            dol_print_error($this->db);
3090
            return -1;
3091
        }
3092
    }
3093
3094
    /**
3095
     * 	Return list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
3096
     *  List found into table c_input_reason loaded by loadCacheInputReason
3097
     *
3098
     *  @param	int		$selected        Id or code of type origin to select by default
3099
     *  @param  string	$htmlname        Nom de la zone select
3100
     *  @param  string	$exclude         To exclude a code value (Example: SRC_PROP)
3101
     * 	@param	int		$addempty		 Add an empty entry
3102
     * 	@return	void
3103
     */
3104
    function selectInputReason($selected = '', $htmlname = 'demandreasonid', $exclude = '', $addempty = 0)
3105
    {
3106
        global $langs, $user;
3107
3108
        $this->loadCacheInputReason();
3109
3110
        print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
3111
        if ($addempty)
3112
            print '<option value="0"' . (empty($selected) ? ' selected' : '') . '>&nbsp;</option>';
3113
        foreach ($this->cache_demand_reason as $id => $arraydemandreason) {
3114
            if ($arraydemandreason['code'] == $exclude)
3115
                continue;
3116
3117
            if ($selected && ($selected == $arraydemandreason['id'] || $selected == $arraydemandreason['code'])) {
3118
                print '<option value="' . $arraydemandreason['id'] . '" selected>';
3119
            } else {
3120
                print '<option value="' . $arraydemandreason['id'] . '">';
3121
            }
3122
            $label = $arraydemandreason['label']; // Translation of label was already done into the ->loadCacheInputReason
3123
            print $langs->trans($label);
3124
            print '</option>';
3125
        }
3126
        print '</select>';
3127
        if ($user->admin)
3128
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3129
    }
3130
3131
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3132
    /**
3133
     *      Charge dans cache la liste des types de paiements possibles
3134
     *
3135
     *      @return     int                 Nb of lines loaded, <0 if KO
3136
     */
3137
    function load_cache_types_paiements()
3138
    {
3139
        // phpcs:enable
3140
        global $langs;
3141
3142
        $num = count($this->cache_types_paiements);
3143
        if ($num > 0)
3144
            return $num;    // Cache already loaded
3145
3146
        dol_syslog(__METHOD__, LOG_DEBUG);
3147
3148
        $this->cache_types_paiements = array();
3149
3150
        $sql = "SELECT id, code, libelle as label, type, active";
3151
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_paiement";
3152
        $sql .= " WHERE entity IN (" . getEntity('c_paiement') . ")";
3153
        //if ($active >= 0) $sql.= " AND active = ".$active;
3154
3155
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3156
        if ($resql) {
3157
            $num = $this->db->num_rows($resql);
3158
            $i = 0;
3159
            while ($i < $num) {
3160
                $obj = $this->db->fetch_object($resql);
3161
3162
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
3163
                $label = ($langs->transnoentitiesnoconv("PaymentTypeShort" . $obj->code) != ("PaymentTypeShort" . $obj->code) ? $langs->transnoentitiesnoconv("PaymentTypeShort" . $obj->code) : ($obj->label != '-' ? $obj->label : ''));
3164
                $this->cache_types_paiements[$obj->id]['id'] = $obj->id;
3165
                $this->cache_types_paiements[$obj->id]['code'] = $obj->code;
3166
                $this->cache_types_paiements[$obj->id]['label'] = $label;
3167
                $this->cache_types_paiements[$obj->id]['type'] = $obj->type;
3168
                $this->cache_types_paiements[$obj->id]['active'] = $obj->active;
3169
                $i++;
3170
            }
3171
3172
            $this->cache_types_paiements = dol_sort_array($this->cache_types_paiements, 'label', 'asc', 0, 0, 1);
3173
3174
            return $num;
3175
        } else {
3176
            dol_print_error($this->db);
3177
            return -1;
3178
        }
3179
    }
3180
3181
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3182
    /**
3183
     *      Return list of payment modes.
3184
     *      Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want.
3185
     *      See instead to force the default value by the caller.
3186
     *
3187
     *      @param	int		$selected		Id of payment term to preselect by default
3188
     *      @param	string	$htmlname		Nom de la zone select
3189
     *      @param	int		$filtertype		Not used
3190
     * 		@param	int		$addempty		Add an empty entry
3191
     * 		@param	int		$noinfoadmin		0=Add admin info, 1=Disable admin info
3192
     * 		@param	string	$morecss			Add more CSS on select tag
3193
     * 		@return	void
3194
     */
3195
    function select_conditions_paiements($selected = 0, $htmlname = 'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss = '')
3196
    {
3197
        // phpcs:enable
3198
        global $langs, $user, $conf;
3199
3200
        dol_syslog(__METHOD__ . " selected=" . $selected . ", htmlname=" . $htmlname, LOG_DEBUG);
3201
3202
        $this->load_cache_conditions_paiements();
3203
3204
        // Set default value if not already set by caller
3205
        if (empty($selected) && !empty($conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID))
3206
            $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID;
3207
3208
        print '<select id="' . $htmlname . '" class="flat selectpaymentterms' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '">';
3209
        if ($addempty)
3210
            print '<option value="0">&nbsp;</option>';
3211
        foreach ($this->cache_conditions_paiements as $id => $arrayconditions) {
3212
            if ($selected == $id) {
3213
                print '<option value="' . $id . '" selected>';
3214
            } else {
3215
                print '<option value="' . $id . '">';
3216
            }
3217
            print $arrayconditions['label'];
3218
            print '</option>';
3219
        }
3220
        print '</select>';
3221
        if ($user->admin && empty($noinfoadmin))
3222
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3223
    }
3224
3225
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3226
    /**
3227
     *      Return list of payment methods
3228
     *
3229
     *      @param	string	$selected       Id du mode de paiement pre-selectionne
3230
     *      @param  string	$htmlname       Nom de la zone select
3231
     *      @param  string	$filtertype     To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz))
3232
     *      @param  int		$format         0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code
3233
     *      @param  int		$empty			1=peut etre vide, 0 sinon
3234
     * 		@param	int		$noadmininfo	0=Add admin info, 1=Disable admin info
3235
     *      @param  int		$maxlength      Max length of label
3236
     *      @param  int     $active         Active or not, -1 = all
3237
     *      @param  string  $morecss        Add more CSS on select tag
3238
     * 		@return	void
3239
     */
3240
    function select_types_paiements($selected = '', $htmlname = 'paiementtype', $filtertype = '', $format = 0, $empty = 1, $noadmininfo = 0, $maxlength = 0, $active = 1, $morecss = '')
3241
    {
3242
        // phpcs:enable
3243
        global $langs, $user;
3244
3245
        dol_syslog(__METHOD__ . " " . $selected . ", " . $htmlname . ", " . $filtertype . ", " . $format, LOG_DEBUG);
3246
3247
        $filterarray = array();
3248
        if ($filtertype == 'CRDT')
3249
            $filterarray = array(0, 2, 3);
3250
        elseif ($filtertype == 'DBIT')
3251
            $filterarray = array(1, 2, 3);
3252
        elseif ($filtertype != '' && $filtertype != '-1')
3253
            $filterarray = explode(',', $filtertype);
3254
3255
        $this->load_cache_types_paiements();
3256
3257
        print '<select id="select' . $htmlname . '" class="flat selectpaymenttypes' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '">';
3258
        if ($empty)
3259
            print '<option value="">&nbsp;</option>';
3260
        foreach ($this->cache_types_paiements as $id => $arraytypes) {
3261
            // If not good status
3262
            if ($active >= 0 && $arraytypes['active'] != $active)
3263
                continue;
3264
3265
            // On passe si on a demande de filtrer sur des modes de paiments particuliers
3266
            if (count($filterarray) && !in_array($arraytypes['type'], $filterarray))
3267
                continue;
3268
3269
            // We discard empty line if showempty is on because an empty line has already been output.
3270
            if ($empty && empty($arraytypes['code']))
3271
                continue;
3272
3273
            if ($format == 0)
3274
                print '<option value="' . $id . '"';
3275
            elseif ($format == 1)
3276
                print '<option value="' . $arraytypes['code'] . '"';
3277
            elseif ($format == 2)
3278
                print '<option value="' . $arraytypes['code'] . '"';
3279
            elseif ($format == 3)
3280
                print '<option value="' . $id . '"';
3281
            // Si selected est text, on compare avec code, sinon avec id
3282
            if (preg_match('/[a-z]/i', $selected) && $selected == $arraytypes['code'])
3283
                print ' selected';
3284
            elseif ($selected == $id)
3285
                print ' selected';
3286
            print '>';
3287
            if ($format == 0)
3288
                $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
3289
            elseif ($format == 1)
3290
                $value = $arraytypes['code'];
3291
            elseif ($format == 2)
3292
                $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
3293
            elseif ($format == 3)
3294
                $value = $arraytypes['code'];
3295
            print $value ? $value : '&nbsp;';
3296
            print '</option>';
3297
        }
3298
        print '</select>';
3299
        if ($user->admin && !$noadmininfo)
3300
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3301
    }
3302
3303
    /**
3304
     *  Selection HT or TTC
3305
     *
3306
     *  @param	string	$selected       Id pre-selectionne
3307
     *  @param  string	$htmlname       Nom de la zone select
3308
     * 	@return	string					Code of HTML select to chose tax or not
3309
     */
3310
    function selectPriceBaseType($selected = '', $htmlname = 'price_base_type')
3311
    {
3312
        global $langs;
3313
3314
        $return = '';
3315
3316
        $return .= '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
3317
        $options = array(
3318
            'HT' => $langs->trans("HT"),
3319
            'TTC' => $langs->trans("TTC")
3320
        );
3321
        foreach ($options as $id => $value) {
3322
            if ($selected == $id) {
3323
                $return .= '<option value="' . $id . '" selected>' . $value;
3324
            } else {
3325
                $return .= '<option value="' . $id . '">' . $value;
3326
            }
3327
            $return .= '</option>';
3328
        }
3329
        $return .= '</select>';
3330
3331
        return $return;
3332
    }
3333
3334
    /**
3335
     *  Return a HTML select list of shipping mode
3336
     *
3337
     *  @param	string	$selected          Id shipping mode pre-selected
3338
     *  @param  string	$htmlname          Name of select zone
3339
     *  @param  string	$filtre            To filter list
3340
     *  @param  int		$useempty          1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3341
     *  @param  string	$moreattrib        To add more attribute on select
3342
     * 	@return	void
3343
     */
3344
    function selectShippingMethod($selected = '', $htmlname = 'shipping_method_id', $filtre = '', $useempty = 0, $moreattrib = '')
3345
    {
3346
        global $langs, $conf, $user;
3347
3348
        $langs->load("admin");
3349
        $langs->load("deliveries");
3350
3351
        $sql = "SELECT rowid, code, libelle as label";
3352
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_shipment_mode";
3353
        $sql .= " WHERE active > 0";
3354
        if ($filtre)
3355
            $sql .= " AND " . $filtre;
3356
        $sql .= " ORDER BY libelle ASC";
3357
3358
        dol_syslog(get_class($this) . "::selectShippingMode", LOG_DEBUG);
3359
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3360
        if ($result) {
3361
            $num = $this->db->num_rows($result);
3362
            $i = 0;
3363
            if ($num) {
3364
                print '<select id="select' . $htmlname . '" class="flat selectshippingmethod" name="' . $htmlname . '"' . ($moreattrib ? ' ' . $moreattrib : '') . '>';
3365
                if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
3366
                    print '<option value="-1">&nbsp;</option>';
3367
                }
3368
                while ($i < $num) {
3369
                    $obj = $this->db->fetch_object($result);
3370
                    if ($selected == $obj->rowid) {
3371
                        print '<option value="' . $obj->rowid . '" selected>';
3372
                    } else {
3373
                        print '<option value="' . $obj->rowid . '">';
3374
                    }
3375
                    print ($langs->trans("SendingMethod" . strtoupper($obj->code)) != "SendingMethod" . strtoupper($obj->code)) ? $langs->trans("SendingMethod" . strtoupper($obj->code)) : $obj->label;
3376
                    print '</option>';
3377
                    $i++;
3378
                }
3379
                print "</select>";
3380
                if ($user->admin)
3381
                    print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3382
            } else {
3383
                print $langs->trans("NoShippingMethodDefined");
3384
            }
3385
        } else {
3386
            dol_print_error($this->db);
3387
        }
3388
    }
3389
3390
    /**
3391
     *    Display form to select shipping mode
3392
     *
3393
     *    @param	string	$page        Page
3394
     *    @param    int		$selected    Id of shipping mode
3395
     *    @param    string	$htmlname    Name of select html field
3396
     *    @param    int		$addempty    1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3397
     *    @return	void
3398
     */
3399
    function formSelectShippingMethod($page, $selected = '', $htmlname = 'shipping_method_id', $addempty = 0)
3400
    {
3401
        global $langs, $db;
3402
3403
        $langs->load("deliveries");
3404
3405
        if ($htmlname != "none") {
3406
            print '<form method="POST" action="' . $page . '">';
3407
            print '<input type="hidden" name="action" value="setshippingmethod">';
3408
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
3409
            $this->selectShippingMethod($selected, $htmlname, '', $addempty);
3410
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
3411
            print '</form>';
3412
        } else {
3413
            if ($selected) {
3414
                $code = $langs->getLabelFromKey($db, $selected, 'c_shipment_mode', 'rowid', 'code');
3415
                print $langs->trans("SendingMethod" . strtoupper($code));
3416
            } else {
3417
                print "&nbsp;";
3418
            }
3419
        }
3420
    }
3421
3422
    /**
3423
     * Creates HTML last in cycle situation invoices selector
3424
     *
3425
     * @param     string  $selected   		Preselected ID
3426
     * @param     int     $socid      		Company ID
3427
     *
3428
     * @return    string                     HTML select
3429
     */
3430
    function selectSituationInvoices($selected = '', $socid = 0)
3431
    {
3432
        global $langs;
3433
3434
        $langs->load('bills');
3435
3436
        $opt = '<option value ="" selected></option>';
3437
        $sql = 'SELECT rowid, ref, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1';
3438
        $sql .= ' ORDER by situation_cycle_ref, situation_counter desc';
3439
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3440
        if ($resql && $this->db->num_rows($resql) > 0) {
3441
            // Last seen cycle
3442
            $ref = 0;
3443
            while ($obj = $this->db->fetch_object($resql)) {
3444
                //Same company ?
3445
                if ($socid == $obj->fk_soc) {
3446
                    //Same cycle ?
3447
                    if ($obj->situation_cycle_ref != $ref) {
3448
                        // Just seen this cycle
3449
                        $ref = $obj->situation_cycle_ref;
3450
                        //not final ?
3451
                        if ($obj->situation_final != 1) {
3452
                            //Not prov?
3453
                            if (substr($obj->ref, 1, 4) != 'PROV') {
3454
                                if ($selected == $obj->rowid) {
3455
                                    $opt .= '<option value="' . $obj->rowid . '" selected>' . $obj->ref . '</option>';
3456
                                } else {
3457
                                    $opt .= '<option value="' . $obj->rowid . '">' . $obj->ref . '</option>';
3458
                                }
3459
                            }
3460
                        }
3461
                    }
3462
                }
3463
            }
3464
        } else {
3465
            dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR);
3466
        }
3467
        if ($opt == '<option value ="" selected></option>') {
3468
            $opt = '<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>';
3469
        }
3470
        return $opt;
3471
    }
3472
3473
    /**
3474
     *      Creates HTML units selector (code => label)
3475
     *
3476
     *      @param	string	$selected       Preselected Unit ID
3477
     *      @param  string	$htmlname       Select name
3478
     *      @param	int		$showempty		Add a nempty line
3479
     * 		@return	string                  HTML select
3480
     */
3481
    function selectUnits($selected = '', $htmlname = 'units', $showempty = 0)
3482
    {
3483
        global $langs;
3484
3485
        $langs->load('products');
3486
3487
        $return = '<select class="flat" id="' . $htmlname . '" name="' . $htmlname . '">';
3488
3489
        $sql = 'SELECT rowid, label, code from ' . MAIN_DB_PREFIX . 'c_units';
3490
        $sql .= ' WHERE active > 0';
3491
3492
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3493
        if ($resql && $this->db->num_rows($resql) > 0) {
3494
            if ($showempty)
3495
                $return .= '<option value="none"></option>';
3496
3497
            while ($res = $this->db->fetch_object($resql)) {
3498
                $unitLabel = $res->label;
3499
                if (!empty($langs->tab_translate['unit' . $res->code])) { // check if Translation is available before
3500
                    $unitLabel = $langs->trans('unit' . $res->code) != $res->label ? $langs->trans('unit' . $res->code) : $res->label;
3501
                }
3502
3503
                if ($selected == $res->rowid) {
3504
                    $return .= '<option value="' . $res->rowid . '" selected>' . $unitLabel . '</option>';
3505
                } else {
3506
                    $return .= '<option value="' . $res->rowid . '">' . $unitLabel . '</option>';
3507
                }
3508
            }
3509
            $return .= '</select>';
3510
        }
3511
        return $return;
3512
    }
3513
3514
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3515
    /**
3516
     *  Return a HTML select list of bank accounts
3517
     *
3518
     *  @param	string	$selected           Id account pre-selected
3519
     *  @param  string	$htmlname           Name of select zone
3520
     *  @param  int		$statut             Status of searched accounts (0=open, 1=closed, 2=both)
3521
     *  @param  string	$filtre             To filter list
3522
     *  @param  int		$useempty           1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3523
     *  @param  string	$moreattrib         To add more attribute on select
3524
     *  @param	int		$showcurrency		Show currency in label
3525
     * 	@return	int							<0 if error, Num of bank account found if OK (0, 1, 2, ...)
3526
     */
3527
    function select_comptes($selected = '', $htmlname = 'accountid', $statut = 0, $filtre = '', $useempty = 0, $moreattrib = '', $showcurrency = 0)
3528
    {
3529
        // phpcs:enable
3530
        global $langs, $conf;
3531
3532
        $langs->load("admin");
3533
        $num = 0;
3534
3535
        $sql = "SELECT rowid, label, bank, clos as status, currency_code";
3536
        $sql .= " FROM " . MAIN_DB_PREFIX . "bank_account";
3537
        $sql .= " WHERE entity IN (" . getEntity('bank_account') . ")";
3538
        if ($statut != 2)
3539
            $sql .= " AND clos = '" . $statut . "'";
3540
        if ($filtre)
3541
            $sql .= " AND " . $filtre;
3542
        $sql .= " ORDER BY label";
3543
3544
        dol_syslog(get_class($this) . "::select_comptes", LOG_DEBUG);
3545
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3546
        if ($result) {
3547
            $num = $this->db->num_rows($result);
3548
            $i = 0;
3549
            if ($num) {
3550
                print '<select id="select' . $htmlname . '" class="flat selectbankaccount" name="' . $htmlname . '"' . ($moreattrib ? ' ' . $moreattrib : '') . '>';
3551
                if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
3552
                    print '<option value="-1">&nbsp;</option>';
3553
                }
3554
3555
                while ($i < $num) {
3556
                    $obj = $this->db->fetch_object($result);
3557
                    if ($selected == $obj->rowid) {
3558
                        print '<option value="' . $obj->rowid . '" selected>';
3559
                    } else {
3560
                        print '<option value="' . $obj->rowid . '">';
3561
                    }
3562
                    print trim($obj->label);
3563
                    if ($showcurrency)
3564
                        print ' (' . $obj->currency_code . ')';
3565
                    if ($statut == 2 && $obj->status == 1)
3566
                        print ' (' . $langs->trans("Closed") . ')';
3567
                    print '</option>';
3568
                    $i++;
3569
                }
3570
                print "</select>";
3571
            }
3572
            else {
3573
                if ($statut == 0)
3574
                    print '<span class="opacitymedium">' . $langs->trans("NoActiveBankAccountDefined") . '</span>';
3575
                else
3576
                    print '<span class="opacitymedium">' . $langs->trans("NoBankAccountFound") . '</span>';
3577
            }
3578
        }
3579
        else {
3580
            dol_print_error($this->db);
3581
        }
3582
3583
        return $num;
3584
    }
3585
3586
    /**
3587
     *    Display form to select bank account
3588
     *
3589
     *    @param	string	$page        Page
3590
     *    @param    int		$selected    Id of bank account
3591
     *    @param    string	$htmlname    Name of select html field
3592
     *    @param    int		$addempty    1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3593
     *    @return	void
3594
     */
3595
    function formSelectAccount($page, $selected = '', $htmlname = 'fk_account', $addempty = 0)
3596
    {
3597
        global $langs;
3598
        if ($htmlname != "none") {
3599
            print '<form method="POST" action="' . $page . '">';
3600
            print '<input type="hidden" name="action" value="setbankaccount">';
3601
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
3602
            $nbaccountfound = $this->select_comptes($selected, $htmlname, 0, '', $addempty);
3603
            if ($nbaccountfound > 0)
3604
                print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
3605
            print '</form>';
3606
        } else {
3607
3608
            $langs->load('banks');
3609
3610
            if ($selected) {
3611
                require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php';
3612
                $bankstatic = new Account($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
Bug introduced by
The type Alixar\Base\Account was not found. Did you mean Account? If so, make sure to prefix the type with \.
Loading history...
3613
                $result = $bankstatic->fetch($selected);
3614
                if ($result)
3615
                    print $bankstatic->getNomUrl(1);
3616
            } else {
3617
                print "&nbsp;";
3618
            }
3619
        }
3620
    }
3621
3622
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3623
    /**
3624
     *    Return list of categories having choosed type
3625
     *
3626
     *    @param	string|int	$type				Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated.
3627
     *    @param    string		$selected    		Id of category preselected or 'auto' (autoselect category if there is only one element)
3628
     *    @param    string		$htmlname			HTML field name
3629
     *    @param    int			$maxlength      	Maximum length for labels
3630
     *    @param    int			$excludeafterid 	Exclude all categories after this leaf in category tree.
3631
     *    @param	int			$outputmode			0=HTML select string, 1=Array
3632
     *    @return	string
3633
     *    @see select_categories
3634
     */
3635
    function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $excludeafterid = 0, $outputmode = 0)
3636
    {
3637
        // phpcs:enable
3638
        global $conf, $langs;
3639
        $langs->load("categories");
3640
3641
        include_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
3642
3643
        // For backward compatibility
3644
        if (is_numeric($type)) {
3645
            dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING);
3646
        }
3647
3648
        if ($type === Categorie::TYPE_BANK_LINE) {
3649
            // TODO Move this into common category feature
3650
            $categids = array();
3651
            $sql = "SELECT c.label, c.rowid";
3652
            $sql .= " FROM " . MAIN_DB_PREFIX . "bank_categ as c";
3653
            $sql .= " WHERE entity = " . $conf->entity;
3654
            $sql .= " ORDER BY c.label";
3655
            $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3656
            if ($result) {
3657
                $num = $this->db->num_rows($result);
3658
                $i = 0;
3659
                while ($i < $num) {
3660
                    $objp = $this->db->fetch_object($result);
3661
                    if ($objp)
3662
                        $cate_arbo[$objp->rowid] = array('id' => $objp->rowid, 'fulllabel' => $objp->label);
3663
                    $i++;
3664
                }
3665
                $this->db->free($result);
3666
            } else
3667
                dol_print_error($this->db);
3668
        }
3669
        else {
3670
            $cat = new Categorie($this->db);
3671
            $cate_arbo = $cat->get_full_arbo($type, $excludeafterid);
3672
        }
3673
3674
        $output = '<select class="flat" name="' . $htmlname . '" id="' . $htmlname . '">';
3675
        $outarray = array();
3676
        if (is_array($cate_arbo)) {
3677
            if (!count($cate_arbo))
3678
                $output .= '<option value="-1" disabled>' . $langs->trans("NoCategoriesDefined") . '</option>';
3679
            else {
3680
                $output .= '<option value="-1">&nbsp;</option>';
3681
                foreach ($cate_arbo as $key => $value) {
3682
                    if ($cate_arbo[$key]['id'] == $selected || ($selected == 'auto' && count($cate_arbo) == 1)) {
3683
                        $add = 'selected ';
3684
                    } else {
3685
                        $add = '';
3686
                    }
3687
                    $output .= '<option ' . $add . 'value="' . $cate_arbo[$key]['id'] . '">' . dol_trunc($cate_arbo[$key]['fulllabel'], $maxlength, 'middle') . '</option>';
3688
3689
                    $outarray[$cate_arbo[$key]['id']] = $cate_arbo[$key]['fulllabel'];
3690
                }
3691
            }
3692
        }
3693
        $output .= '</select>';
3694
        $output .= "\n";
3695
3696
        if ($outputmode)
3697
            return $outarray;
3698
        return $output;
3699
    }
3700
3701
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3702
    /**
3703
     *     Show a confirmation HTML form or AJAX popup
3704
     *
3705
     *     @param	string		$page        	   	Url of page to call if confirmation is OK
3706
     *     @param	string		$title       	   	Title
3707
     *     @param	string		$question    	   	Question
3708
     *     @param 	string		$action      	   	Action
3709
     * 	   @param	array		$formquestion	   	An array with forms complementary inputs
3710
     * 	   @param	string		$selectedchoice		"" or "no" or "yes"
3711
     * 	   @param	int			$useajax		   	0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=preoutput confirm box with div id=dialog-confirm-xxx
3712
     *     @param	int			$height          	Force height of box
3713
     *     @param	int			$width				Force width of box
3714
     *     @return 	void
3715
     *     @deprecated
3716
     *     @see formconfirm()
3717
     */
3718
    function form_confirm($page, $title, $question, $action, $formquestion = '', $selectedchoice = "", $useajax = 0, $height = 170, $width = 500)
3719
    {
3720
        // phpcs:enable
3721
        dol_syslog(__METHOD__ . ': using form_confirm is deprecated. Use formconfim instead.', LOG_WARNING);
3722
        print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width);
3723
    }
3724
3725
    /**
3726
     *     Show a confirmation HTML form or AJAX popup.
3727
     *     Easiest way to use this is with useajax=1.
3728
     *     If you use useajax='xxx', you must also add jquery code to trigger opening of box (with correct parameters)
3729
     *     just after calling this method. For example:
3730
     *       print '<script type="text/javascript">'."\n";
3731
     *       print 'jQuery(document).ready(function() {'."\n";
3732
     *       print 'jQuery(".xxxlink").click(function(e) { jQuery("#aparamid").val(jQuery(this).attr("rel")); jQuery("#dialog-confirm-xxx").dialog("open"); return false; });'."\n";
3733
     *       print '});'."\n";
3734
     *       print '</script>'."\n";
3735
     *
3736
     *     @param  	string		$page        	   	Url of page to call if confirmation is OK. Can contains paramaters (param 'action' and 'confirm' will be reformated)
3737
     *     @param	string		$title       	   	Title
3738
     *     @param	string		$question    	   	Question
3739
     *     @param 	string		$action      	   	Action
3740
     * 	   @param  	array		$formquestion	   	An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , ))
3741
     * 												type can be 'hidden', 'text', 'password', 'checkbox', 'radio', 'date', 'morecss', ...
3742
     * 	   @param  	string		$selectedchoice  	'' or 'no', or 'yes' or '1' or '0'
3743
     * 	   @param  	int			$useajax		   	0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx
3744
     *     @param  	int			$height          	Force height of box
3745
     *     @param	int			$width				Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones.
3746
     *     @param	int			$disableformtag		1=Disable form tag. Can be used if we are already inside a <form> section.
3747
     *     @return 	string      	    			HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form
3748
     */
3749
    function formconfirm($page, $title, $question, $action, $formquestion = '', $selectedchoice = '', $useajax = 0, $height = 210, $width = 500, $disableformtag = 0)
3750
    {
3751
        global $langs, $conf;
3752
        global $useglobalvars;
3753
3754
        $more = '';
3755
        $formconfirm = '';
3756
        $inputok = array();
3757
        $inputko = array();
3758
3759
        // Clean parameters
3760
        $newselectedchoice = empty($selectedchoice) ? "no" : $selectedchoice;
3761
        if ($conf->browser->layout == 'phone')
3762
            $width = '95%';
3763
3764
        if (is_array($formquestion) && !empty($formquestion)) {
3765
            // First add hidden fields and value
3766
            foreach ($formquestion as $key => $input) {
3767
                if (is_array($input) && !empty($input)) {
3768
                    if ($input['type'] == 'hidden') {
3769
                        $more .= '<input type="hidden" id="' . $input['name'] . '" name="' . $input['name'] . '" value="' . dol_escape_htmltag($input['value']) . '">' . "\n";
3770
                    }
3771
                }
3772
            }
3773
3774
            // Now add questions
3775
            $more .= '<table class="paddingtopbottomonly" width="100%">' . "\n";
3776
            if (!empty($formquestion['text']))
3777
                $more .= '<tr><td colspan="2">' . $formquestion['text'] . '</td></tr>' . "\n";
3778
            foreach ($formquestion as $key => $input) {
3779
                if (is_array($input) && !empty($input)) {
3780
                    $size = (!empty($input['size']) ? ' size="' . $input['size'] . '"' : '');
3781
                    $moreattr = (!empty($input['moreattr']) ? ' ' . $input['moreattr'] : '');
3782
                    $morecss = (!empty($input['morecss']) ? ' ' . $input['morecss'] : '');
3783
3784
                    if ($input['type'] == 'text') {
3785
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td><td align="left"><input type="text" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '"' . $size . ' value="' . $input['value'] . '"' . $moreattr . ' /></td></tr>' . "\n";
3786
                    } elseif ($input['type'] == 'password') {
3787
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td><td align="left"><input type="password" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '"' . $size . ' value="' . $input['value'] . '"' . $moreattr . ' /></td></tr>' . "\n";
3788
                    } elseif ($input['type'] == 'select') {
3789
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>';
3790
                        if (!empty($input['label']))
3791
                            $more .= $input['label'] . '</td><td class="tdtop" align="left">';
3792
                        $more .= $this->selectarray($input['name'], $input['values'], $input['default'], 1, 0, 0, $moreattr, 0, 0, 0, '', $morecss);
3793
                        $more .= '</td></tr>' . "\n";
3794
                    }
3795
                    elseif ($input['type'] == 'checkbox') {
3796
                        $more .= '<tr>';
3797
                        $more .= '<td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . ' </td><td align="left">';
3798
                        $more .= '<input type="checkbox" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '"' . $moreattr;
3799
                        if (!is_bool($input['value']) && $input['value'] != 'false' && $input['value'] != '0')
3800
                            $more .= ' checked';
3801
                        if (is_bool($input['value']) && $input['value'])
3802
                            $more .= ' checked';
3803
                        if (isset($input['disabled']))
3804
                            $more .= ' disabled';
3805
                        $more .= ' /></td>';
3806
                        $more .= '</tr>' . "\n";
3807
                    }
3808
                    elseif ($input['type'] == 'radio') {
3809
                        $i = 0;
3810
                        foreach ($input['values'] as $selkey => $selval) {
3811
                            $more .= '<tr>';
3812
                            if ($i == 0)
3813
                                $more .= '<td' . (empty($input['tdclass']) ? ' class="tdtop"' : (' class="tdtop ' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td>';
3814
                            else
3815
                                $more .= '<td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>&nbsp;</td>';
3816
                            $more .= '<td><input type="radio" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '" value="' . $selkey . '"' . $moreattr;
3817
                            if ($input['disabled'])
3818
                                $more .= ' disabled';
3819
                            $more .= ' /> ';
3820
                            $more .= $selval;
3821
                            $more .= '</td></tr>' . "\n";
3822
                            $i++;
3823
                        }
3824
                    }
3825
                    elseif ($input['type'] == 'date') {
3826
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td>';
3827
                        $more .= '<td align="left">';
3828
                        $more .= $this->selectDate($input['value'], $input['name'], 0, 0, 0, '', 1, 0);
3829
                        $more .= '</td></tr>' . "\n";
3830
                        $formquestion[] = array('name' => $input['name'] . 'day');
3831
                        $formquestion[] = array('name' => $input['name'] . 'month');
3832
                        $formquestion[] = array('name' => $input['name'] . 'year');
3833
                        $formquestion[] = array('name' => $input['name'] . 'hour');
3834
                        $formquestion[] = array('name' => $input['name'] . 'min');
3835
                    } elseif ($input['type'] == 'other') {
3836
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>';
3837
                        if (!empty($input['label']))
3838
                            $more .= $input['label'] . '</td><td align="left">';
3839
                        $more .= $input['value'];
3840
                        $more .= '</td></tr>' . "\n";
3841
                    }
3842
3843
                    elseif ($input['type'] == 'onecolumn') {
3844
                        $more .= '<tr><td colspan="2" align="left">';
3845
                        $more .= $input['value'];
3846
                        $more .= '</td></tr>' . "\n";
3847
                    }
3848
                }
3849
            }
3850
            $more .= '</table>' . "\n";
3851
        }
3852
3853
        // JQUI method dialog is broken with jmobile, we use standard HTML.
3854
        // Note: When using dol_use_jmobile or no js, you must also check code for button use a GET url with action=xxx and check that you also output the confirm code when action=xxx
3855
        // See page product/card.php for example
3856
        if (!empty($conf->dol_use_jmobile))
3857
            $useajax = 0;
3858
        if (empty($conf->use_javascript_ajax))
3859
            $useajax = 0;
3860
3861
        if ($useajax) {
3862
            $autoOpen = true;
3863
            $dialogconfirm = 'dialog-confirm';
3864
            $button = '';
3865
            if (!is_numeric($useajax)) {
3866
                $button = $useajax;
3867
                $useajax = 1;
3868
                $autoOpen = false;
3869
                $dialogconfirm .= '-' . $button;
3870
            }
3871
            $pageyes = $page . (preg_match('/\?/', $page) ? '&' : '?') . 'action=' . $action . '&confirm=yes';
3872
            $pageno = ($useajax == 2 ? $page . (preg_match('/\?/', $page) ? '&' : '?') . 'confirm=no' : '');
3873
            // Add input fields into list of fields to read during submit (inputok and inputko)
3874
            if (is_array($formquestion)) {
3875
                foreach ($formquestion as $key => $input) {
3876
                    //print "xx ".$key." rr ".is_array($input)."<br>\n";
3877
                    if (is_array($input) && isset($input['name']))
3878
                        array_push($inputok, $input['name']);
3879
                    if (isset($input['inputko']) && $input['inputko'] == 1)
3880
                        array_push($inputko, $input['name']);
3881
                }
3882
            }
3883
            // Show JQuery confirm box. Note that global var $useglobalvars is used inside this template
3884
            $formconfirm .= '<div id="' . $dialogconfirm . '" title="' . dol_escape_htmltag($title) . '" style="display: none;">';
3885
            if (!empty($more)) {
3886
                $formconfirm .= '<div class="confirmquestions">' . $more . '</div>';
3887
            }
3888
            $formconfirm .= ($question ? '<div class="confirmmessage">' . img_help('', '') . ' ' . $question . '</div>' : '');
3889
            $formconfirm .= '</div>' . "\n";
3890
3891
            $formconfirm .= "\n<!-- begin ajax formconfirm page=" . $page . " -->\n";
3892
            $formconfirm .= '<script type="text/javascript">' . "\n";
3893
            $formconfirm .= 'jQuery(document).ready(function() {
3894
            $(function() {
3895
            	$( "#' . $dialogconfirm . '" ).dialog(
3896
            	{
3897
                    autoOpen: ' . ($autoOpen ? "true" : "false") . ',';
3898
            if ($newselectedchoice == 'no') {
3899
                $formconfirm .= '
3900
						open: function() {
3901
            				$(this).parent().find("button.ui-button:eq(2)").focus();
3902
						},';
3903
            }
3904
            $formconfirm .= '
3905
                    resizable: false,
3906
                    height: "' . $height . '",
3907
                    width: "' . $width . '",
3908
                    modal: true,
3909
                    closeOnEscape: false,
3910
                    buttons: {
3911
                        "' . dol_escape_js($langs->transnoentities("Yes")) . '": function() {
3912
                        	var options="";
3913
                        	var inputok = ' . json_encode($inputok) . ';
3914
                         	var pageyes = "' . dol_escape_js(!empty($pageyes) ? $pageyes : '') . '";
3915
                         	if (inputok.length>0) {
3916
                         		$.each(inputok, function(i, inputname) {
3917
                         			var more = "";
3918
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3919
                         		    if ($("#" + inputname).attr("type") == "radio") { more = ":checked"; }
3920
                         			var inputvalue = $("#" + inputname + more).val();
3921
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3922
                         			options += "&" + inputname + "=" + encodeURIComponent(inputvalue);
3923
                         		});
3924
                         	}
3925
                         	var urljump = pageyes + (pageyes.indexOf("?") < 0 ? "?" : "") + options;
3926
                         	//alert(urljump);
3927
            				if (pageyes.length > 0) { location.href = urljump; }
3928
                            $(this).dialog("close");
3929
                        },
3930
                        "' . dol_escape_js($langs->transnoentities("No")) . '": function() {
3931
                        	var options = "";
3932
                         	var inputko = ' . json_encode($inputko) . ';
3933
                         	var pageno="' . dol_escape_js(!empty($pageno) ? $pageno : '') . '";
3934
                         	if (inputko.length>0) {
3935
                         		$.each(inputko, function(i, inputname) {
3936
                         			var more = "";
3937
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3938
                         			var inputvalue = $("#" + inputname + more).val();
3939
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3940
                         			options += "&" + inputname + "=" + encodeURIComponent(inputvalue);
3941
                         		});
3942
                         	}
3943
                         	var urljump=pageno + (pageno.indexOf("?") < 0 ? "?" : "") + options;
3944
                         	//alert(urljump);
3945
            				if (pageno.length > 0) { location.href = urljump; }
3946
                            $(this).dialog("close");
3947
                        }
3948
                    }
3949
                }
3950
                );
3951
3952
            	var button = "' . $button . '";
3953
            	if (button.length > 0) {
3954
                	$( "#" + button ).click(function() {
3955
                		$("#' . $dialogconfirm . '").dialog("open");
3956
        			});
3957
                }
3958
            });
3959
            });
3960
            </script>';
3961
            $formconfirm .= "<!-- end ajax formconfirm -->\n";
3962
        } else {
3963
            $formconfirm .= "\n<!-- begin formconfirm page=" . $page . " -->\n";
3964
3965
            if (empty($disableformtag))
3966
                $formconfirm .= '<form method="POST" action="' . $page . '" class="notoptoleftroright">' . "\n";
3967
3968
            $formconfirm .= '<input type="hidden" name="action" value="' . $action . '">' . "\n";
3969
            if (empty($disableformtag))
3970
                $formconfirm .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">' . "\n";
3971
3972
            $formconfirm .= '<table width="100%" class="valid">' . "\n";
3973
3974
            // Line title
3975
            $formconfirm .= '<tr class="validtitre"><td class="validtitre" colspan="3">' . img_picto('', 'recent') . ' ' . $title . '</td></tr>' . "\n";
3976
3977
            // Line form fields
3978
            if ($more) {
3979
                $formconfirm .= '<tr class="valid"><td class="valid" colspan="3">' . "\n";
3980
                $formconfirm .= $more;
3981
                $formconfirm .= '</td></tr>' . "\n";
3982
            }
3983
3984
            // Line with question
3985
            $formconfirm .= '<tr class="valid">';
3986
            $formconfirm .= '<td class="valid">' . $question . '</td>';
3987
            $formconfirm .= '<td class="valid">';
3988
            $formconfirm .= $this->selectyesno("confirm", $newselectedchoice);
3989
            $formconfirm .= '</td>';
3990
            $formconfirm .= '<td class="valid" align="center"><input class="button valignmiddle" type="submit" value="' . $langs->trans("Validate") . '"></td>';
3991
            $formconfirm .= '</tr>' . "\n";
3992
3993
            $formconfirm .= '</table>' . "\n";
3994
3995
            if (empty($disableformtag))
3996
                $formconfirm .= "</form>\n";
3997
            $formconfirm .= '<br>';
3998
3999
            $formconfirm .= "<!-- end formconfirm -->\n";
4000
        }
4001
4002
        return $formconfirm;
4003
    }
4004
4005
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4006
    /**
4007
     *    Show a form to select a project
4008
     *
4009
     *    @param	int		$page        		Page
4010
     *    @param	int		$socid       		Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id)
4011
     *    @param    int		$selected    		Id pre-selected project
4012
     *    @param    string	$htmlname    		Name of select field
4013
     *    @param	int		$discard_closed		Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable)
4014
     *    @param	int		$maxlength			Max length
4015
     *    @param	int		$forcefocus			Force focus on field (works with javascript only)
4016
     *    @param    int     $nooutput           No print is done. String is returned.
4017
     *    @return	string                      Return html content
4018
     */
4019
    function form_project($page, $socid, $selected = '', $htmlname = 'projectid', $discard_closed = 0, $maxlength = 20, $forcefocus = 0, $nooutput = 0)
4020
    {
4021
        // phpcs:enable
4022
        global $langs;
4023
4024
        require_once DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php';
4025
        require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
4026
4027
        $out = '';
4028
4029
        $formproject = new FormProjets($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
Bug introduced by
The type Alixar\Base\FormProjets was not found. Did you mean FormProjets? If so, make sure to prefix the type with \.
Loading history...
4030
4031
        $langs->load("project");
4032
        if ($htmlname != "none") {
4033
            $out .= "\n";
4034
            $out .= '<form method="post" action="' . $page . '">';
4035
            $out .= '<input type="hidden" name="action" value="classin">';
4036
            $out .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4037
            $out .= $formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0, '', 1);
4038
            $out .= '<input type="submit" class="button" value="' . $langs->trans("Modify") . '">';
4039
            $out .= '</form>';
4040
        } else {
4041
            if ($selected) {
4042
                $projet = new Project($this->db);
0 ignored issues
show
Bug introduced by
The type Alixar\Base\Project was not found. Did you mean Project? If so, make sure to prefix the type with \.
Loading history...
4043
                $projet->fetch($selected);
4044
                //print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>';
4045
                $out .= $projet->getNomUrl(0, '', 1);
4046
            } else {
4047
                $out .= "&nbsp;";
4048
            }
4049
        }
4050
4051
        if (empty($nooutput)) {
4052
            print $out;
4053
            return '';
4054
        }
4055
        return $out;
4056
    }
4057
4058
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4059
    /**
4060
     * 	Show a form to select payment conditions
4061
     *
4062
     *  @param	int		$page        	Page
4063
     *  @param  string	$selected    	Id condition pre-selectionne
4064
     *  @param  string	$htmlname    	Name of select html field
4065
     * 	@param	int		$addempty		Add empty entry
4066
     *  @return	void
4067
     */
4068
    function form_conditions_reglement($page, $selected = '', $htmlname = 'cond_reglement_id', $addempty = 0)
4069
    {
4070
        // phpcs:enable
4071
        global $langs;
4072
        if ($htmlname != "none") {
4073
            print '<form method="post" action="' . $page . '">';
4074
            print '<input type="hidden" name="action" value="setconditions">';
4075
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4076
            $this->select_conditions_paiements($selected, $htmlname, -1, $addempty);
4077
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4078
            print '</form>';
4079
        } else {
4080
            if ($selected) {
4081
                $this->load_cache_conditions_paiements();
4082
                print $this->cache_conditions_paiements[$selected]['label'];
4083
            } else {
4084
                print "&nbsp;";
4085
            }
4086
        }
4087
    }
4088
4089
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4090
    /**
4091
     *  Show a form to select a delivery delay
4092
     *
4093
     *  @param  int		$page        	Page
4094
     *  @param  string	$selected    	Id condition pre-selectionne
4095
     *  @param  string	$htmlname    	Name of select html field
4096
     * 	@param	int		$addempty		Ajoute entree vide
4097
     *  @return	void
4098
     */
4099
    function form_availability($page, $selected = '', $htmlname = 'availability', $addempty = 0)
4100
    {
4101
        // phpcs:enable
4102
        global $langs;
4103
        if ($htmlname != "none") {
4104
            print '<form method="post" action="' . $page . '">';
4105
            print '<input type="hidden" name="action" value="setavailability">';
4106
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4107
            $this->selectAvailabilityDelay($selected, $htmlname, -1, $addempty);
4108
            print '<input type="submit" class="button" value="' . $langs->trans("Modify") . '">';
4109
            print '</form>';
4110
        } else {
4111
            if ($selected) {
4112
                $this->load_cache_availability();
4113
                print $this->cache_availability[$selected]['label'];
4114
            } else {
4115
                print "&nbsp;";
4116
            }
4117
        }
4118
    }
4119
4120
    /**
4121
     * 	Output HTML form to select list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
4122
     *  List found into table c_input_reason loaded by loadCacheInputReason
4123
     *
4124
     *  @param  string	$page        	Page
4125
     *  @param  string	$selected    	Id condition pre-selectionne
4126
     *  @param  string	$htmlname    	Name of select html field
4127
     * 	@param	int		$addempty		Add empty entry
4128
     *  @return	void
4129
     */
4130
    function formInputReason($page, $selected = '', $htmlname = 'demandreason', $addempty = 0)
4131
    {
4132
        global $langs;
4133
        if ($htmlname != "none") {
4134
            print '<form method="post" action="' . $page . '">';
4135
            print '<input type="hidden" name="action" value="setdemandreason">';
4136
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4137
            $this->selectInputReason($selected, $htmlname, -1, $addempty);
4138
            print '<input type="submit" class="button" value="' . $langs->trans("Modify") . '">';
4139
            print '</form>';
4140
        } else {
4141
            if ($selected) {
4142
                $this->loadCacheInputReason();
4143
                foreach ($this->cache_demand_reason as $key => $val) {
4144
                    if ($val['id'] == $selected) {
4145
                        print $val['label'];
4146
                        break;
4147
                    }
4148
                }
4149
            } else {
4150
                print "&nbsp;";
4151
            }
4152
        }
4153
    }
4154
4155
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4156
    /**
4157
     *    Show a form + html select a date
4158
     *
4159
     *    @param	string		$page        	Page
4160
     *    @param	string		$selected    	Date preselected
4161
     *    @param    string		$htmlname    	Html name of date input fields or 'none'
4162
     *    @param    int			$displayhour 	Display hour selector
4163
     *    @param    int			$displaymin		Display minutes selector
4164
     *    @param	int			$nooutput		1=No print output, return string
4165
     *    @return	string
4166
     *    @see		selectDate
4167
     */
4168
    function form_date($page, $selected, $htmlname, $displayhour = 0, $displaymin = 0, $nooutput = 0)
4169
    {
4170
        // phpcs:enable
4171
        global $langs;
4172
4173
        $ret = '';
4174
4175
        if ($htmlname != "none") {
4176
            $ret .= '<form method="post" action="' . $page . '" name="form' . $htmlname . '">';
4177
            $ret .= '<input type="hidden" name="action" value="set' . $htmlname . '">';
4178
            $ret .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4179
            $ret .= '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
4180
            $ret .= '<tr><td>';
4181
            $ret .= $this->selectDate($selected, $htmlname, $displayhour, $displaymin, 1, 'form' . $htmlname, 1, 0);
4182
            $ret .= '</td>';
4183
            $ret .= '<td align="left"><input type="submit" class="button" value="' . $langs->trans("Modify") . '"></td>';
4184
            $ret .= '</tr></table></form>';
4185
        } else {
4186
            if ($displayhour)
4187
                $ret .= dol_print_date($selected, 'dayhour');
4188
            else
4189
                $ret .= dol_print_date($selected, 'day');
4190
        }
4191
4192
        if (empty($nooutput))
4193
            print $ret;
4194
        return $ret;
4195
    }
4196
4197
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4198
    /**
4199
     *  Show a select form to choose a user
4200
     *
4201
     *  @param	string	$page        	Page
4202
     *  @param  string	$selected    	Id of user preselected
4203
     *  @param  string	$htmlname    	Name of input html field. If 'none', we just output the user link.
4204
     *  @param  array	$exclude		List of users id to exclude
4205
     *  @param  array	$include        List of users id to include
4206
     *  @return	void
4207
     */
4208
    function form_users($page, $selected = '', $htmlname = 'userid', $exclude = '', $include = '')
4209
    {
4210
        // phpcs:enable
4211
        global $langs;
4212
4213
        if ($htmlname != "none") {
4214
            print '<form method="POST" action="' . $page . '" name="form' . $htmlname . '">';
4215
            print '<input type="hidden" name="action" value="set' . $htmlname . '">';
4216
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4217
            print $this->select_dolusers($selected, $htmlname, 1, $exclude, 0, $include);
4218
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4219
            print '</form>';
4220
        } else {
4221
            if ($selected) {
4222
                require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
4223
                $theuser = new User($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4224
                $theuser->fetch($selected);
4225
                print $theuser->getNomUrl(1);
4226
            } else {
4227
                print "&nbsp;";
4228
            }
4229
        }
4230
    }
4231
4232
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4233
    /**
4234
     *    Show form with payment mode
4235
     *
4236
     *    @param	string	$page        	Page
4237
     *    @param    int		$selected    	Id mode pre-selectionne
4238
     *    @param    string	$htmlname    	Name of select html field
4239
     *    @param  	string	$filtertype		To filter on field type in llx_c_paiement (array('code'=>xx,'label'=>zz))
4240
     *    @param    int     $active         Active or not, -1 = all
4241
     *    @return	void
4242
     */
4243
    function form_modes_reglement($page, $selected = '', $htmlname = 'mode_reglement_id', $filtertype = '', $active = 1)
4244
    {
4245
        // phpcs:enable
4246
        global $langs;
4247
        if ($htmlname != "none") {
4248
            print '<form method="POST" action="' . $page . '">';
4249
            print '<input type="hidden" name="action" value="setmode">';
4250
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4251
            $this->select_types_paiements($selected, $htmlname, $filtertype, 0, 0, 0, 0, $active);
4252
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4253
            print '</form>';
4254
        } else {
4255
            if ($selected) {
4256
                $this->load_cache_types_paiements();
4257
                print $this->cache_types_paiements[$selected]['label'];
4258
            } else {
4259
                print "&nbsp;";
4260
            }
4261
        }
4262
    }
4263
4264
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4265
    /**
4266
     *    Show form with multicurrency code
4267
     *
4268
     *    @param	string	$page        	Page
4269
     *    @param    string	$selected    	code pre-selectionne
4270
     *    @param    string	$htmlname    	Name of select html field
4271
     *    @return	void
4272
     */
4273
    function form_multicurrency_code($page, $selected = '', $htmlname = 'multicurrency_code')
4274
    {
4275
        // phpcs:enable
4276
        global $langs;
4277
        if ($htmlname != "none") {
4278
            print '<form method="POST" action="' . $page . '">';
4279
            print '<input type="hidden" name="action" value="setmulticurrencycode">';
4280
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4281
            print $this->selectMultiCurrency($selected, $htmlname, 0);
4282
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4283
            print '</form>';
4284
        } else {
4285
            dol_include_once('/core/lib/company.lib.php');
4286
            print !empty($selected) ? currency_name($selected, 1) : '&nbsp;';
4287
        }
4288
    }
4289
4290
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4291
    /**
4292
     *    Show form with multicurrency rate
4293
     *
4294
     *    @param	string	$page        	Page
4295
     *    @param    double	$rate	    	Current rate
4296
     *    @param    string	$htmlname    	Name of select html field
4297
     *    @param    string  $currency       Currency code to explain the rate
4298
     *    @return	void
4299
     */
4300
    function form_multicurrency_rate($page, $rate = '', $htmlname = 'multicurrency_tx', $currency = '')
4301
    {
4302
        // phpcs:enable
4303
        global $langs, $mysoc, $conf;
4304
4305
        if ($htmlname != "none") {
4306
            print '<form method="POST" action="' . $page . '">';
4307
            print '<input type="hidden" name="action" value="setmulticurrencyrate">';
4308
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4309
            print '<input type="text" name="' . $htmlname . '" value="' . (!empty($rate) ? price($rate) : 1) . '" size="10" /> ';
4310
            print '<select name="calculation_mode">';
4311
            print '<option value="1">' . $currency . ' > ' . $conf->currency . '</option>';
4312
            print '<option value="2">' . $conf->currency . ' > ' . $currency . '</option>';
4313
            print '</select> ';
4314
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4315
            print '</form>';
4316
        } else {
4317
            if (!empty($rate)) {
4318
                print price($rate, 1, $langs, 1, 0);
4319
                if ($currency && $rate != 1)
4320
                    print ' &nbsp; (' . price($rate, 1, $langs, 1, 0) . ' ' . $currency . ' = 1 ' . $conf->currency . ')';
4321
            }
4322
            else {
4323
                print 1;
4324
            }
4325
        }
4326
    }
4327
4328
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4329
    /**
4330
     * 	Show a select box with available absolute discounts
4331
     *
4332
     *  @param  string	$page        	Page URL where form is shown
4333
     *  @param  int		$selected    	Value pre-selected
4334
     * 	@param  string	$htmlname    	Name of SELECT component. If 'none', not changeable. Example 'remise_id'.
4335
     * 	@param	int		$socid			Third party id
4336
     * 	@param	float	$amount			Total amount available
4337
     * 	@param	string	$filter			SQL filter on discounts
4338
     * 	@param	int		$maxvalue		Max value for lines that can be selected
4339
     *  @param  string	$more           More string to add
4340
     *  @param  int     $hidelist       1=Hide list
4341
     *  @param	int		$discount_type	0 => customer discount, 1 => supplier discount
4342
     *  @return	void
4343
     */
4344
    function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter = '', $maxvalue = 0, $more = '', $hidelist = 0, $discount_type = 0)
4345
    {
4346
        // phpcs:enable
4347
        global $conf, $langs;
4348
        if ($htmlname != "none") {
4349
            print '<form method="post" action="' . $page . '">';
4350
            print '<input type="hidden" name="action" value="setabsolutediscount">';
4351
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4352
            print '<div class="inline-block">';
4353
            if (!empty($discount_type)) {
4354
                if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
4355
                    if (!$filter || $filter == "fk_invoice_supplier_source IS NULL")
4356
                        $translationKey = 'HasAbsoluteDiscountFromSupplier';    // If we want deposit to be substracted to payments only and not to total of final invoice
4357
                    else
4358
                        $translationKey = 'HasCreditNoteFromSupplier';
4359
                }
4360
                else {
4361
                    if (!$filter || $filter == "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')")
4362
                        $translationKey = 'HasAbsoluteDiscountFromSupplier';
4363
                    else
4364
                        $translationKey = 'HasCreditNoteFromSupplier';
4365
                }
4366
            } else {
4367
                if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
4368
                    if (!$filter || $filter == "fk_facture_source IS NULL")
4369
                        $translationKey = 'CompanyHasAbsoluteDiscount';    // If we want deposit to be substracted to payments only and not to total of final invoice
4370
                    else
4371
                        $translationKey = 'CompanyHasCreditNote';
4372
                }
4373
                else {
4374
                    if (!$filter || $filter == "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')")
4375
                        $translationKey = 'CompanyHasAbsoluteDiscount';
4376
                    else
4377
                        $translationKey = 'CompanyHasCreditNote';
4378
                }
4379
            }
4380
            print $langs->trans($translationKey, price($amount, 0, $langs, 0, 0, -1, $conf->currency));
4381
            if (empty($hidelist))
4382
                print ': ';
4383
            print '</div>';
4384
            if (empty($hidelist)) {
4385
                print '<div class="inline-block" style="padding-right: 10px">';
4386
                $newfilter = 'discount_type=' . intval($discount_type);
4387
                if (!empty($discount_type)) {
4388
                    $newfilter .= ' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Supplier discounts available
4389
                } else {
4390
                    $newfilter .= ' AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Customer discounts available
4391
                }
4392
                if ($filter)
4393
                    $newfilter .= ' AND (' . $filter . ')';
4394
                $nbqualifiedlines = $this->select_remises($selected, $htmlname, $newfilter, $socid, $maxvalue);
4395
                if ($nbqualifiedlines > 0) {
4396
                    print ' &nbsp; <input type="submit" class="button" value="' . dol_escape_htmltag($langs->trans("UseLine")) . '"';
4397
                    if (!empty($discount_type) && $filter && $filter != "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')")
4398
                        print ' title="' . $langs->trans("UseCreditNoteInInvoicePayment") . '"';
4399
                    if (empty($discount_type) && $filter && $filter != "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')")
4400
                        print ' title="' . $langs->trans("UseCreditNoteInInvoicePayment") . '"';
4401
4402
                    print '>';
4403
                }
4404
                print '</div>';
4405
            }
4406
            if ($more) {
4407
                print '<div class="inline-block">';
4408
                print $more;
4409
                print '</div>';
4410
            }
4411
            print '</form>';
4412
        } else {
4413
            if ($selected) {
4414
                print $selected;
4415
            } else {
4416
                print "0";
4417
            }
4418
        }
4419
    }
4420
4421
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4422
    /**
4423
     *    Show forms to select a contact
4424
     *
4425
     *    @param	string		$page        	Page
4426
     *    @param	Societe		$societe		Filter on third party
4427
     *    @param    int			$selected    	Id contact pre-selectionne
4428
     *    @param    string		$htmlname    	Name of HTML select. If 'none', we just show contact link.
4429
     *    @return	void
4430
     */
4431
    function form_contacts($page, $societe, $selected = '', $htmlname = 'contactid')
4432
    {
4433
        // phpcs:enable
4434
        global $langs, $conf;
4435
4436
        if ($htmlname != "none") {
4437
            print '<form method="post" action="' . $page . '">';
4438
            print '<input type="hidden" name="action" value="set_contact">';
4439
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4440
            print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
4441
            print '<tr><td>';
4442
            $num = $this->select_contacts($societe->id, $selected, $htmlname);
4443
            if ($num == 0) {
4444
                $addcontact = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress"));
4445
                print '<a href="' . DOL_URL_ROOT . '/contact/card.php?socid=' . $societe->id . '&amp;action=create&amp;backtoreferer=1">' . $addcontact . '</a>';
4446
            }
4447
            print '</td>';
4448
            print '<td align="left"><input type="submit" class="button" value="' . $langs->trans("Modify") . '"></td>';
4449
            print '</tr></table></form>';
4450
        } else {
4451
            if ($selected) {
4452
                require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
4453
                $contact = new Contact($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4454
                $contact->fetch($selected);
4455
                print $contact->getFullName($langs);
4456
            } else {
4457
                print "&nbsp;";
4458
            }
4459
        }
4460
    }
4461
4462
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4463
    /**
4464
     *  Output html select to select thirdparty
4465
     *
4466
     *  @param	string	$page       	Page
4467
     *  @param  string	$selected   	Id preselected
4468
     *  @param  string	$htmlname		Name of HTML select
4469
     *  @param  string	$filter         optional filters criteras
4470
     * 	@param	int		$showempty		Add an empty field
4471
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
4472
     * 	@param	int		$forcecombo		Force to use combo box
4473
     *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
4474
     *  @param  int     $nooutput       No print output. Return it only.
4475
     *  @return	void
4476
     */
4477
    function form_thirdparty($page, $selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0)
4478
    {
4479
        // phpcs:enable
4480
        global $langs;
4481
4482
        $out = '';
4483
        if ($htmlname != "none") {
4484
            $out .= '<form method="post" action="' . $page . '">';
4485
            $out .= '<input type="hidden" name="action" value="set_thirdparty">';
4486
            $out .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4487
            $out .= $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events);
4488
            $out .= '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4489
            $out .= '</form>';
4490
        } else {
4491
            if ($selected) {
4492
                require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
4493
                $soc = new Societe($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4494
                $soc->fetch($selected);
4495
                $out .= $soc->getNomUrl($langs);
4496
            } else {
4497
                $out .= "&nbsp;";
4498
            }
4499
        }
4500
4501
        if ($nooutput)
4502
            return $out;
4503
        else
4504
            print $out;
4505
    }
4506
4507
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4508
    /**
4509
     *    Retourne la liste des devises, dans la langue de l'utilisateur
4510
     *
4511
     *    @param	string	$selected    preselected currency code
4512
     *    @param    string	$htmlname    name of HTML select list
4513
     *    @deprecated
4514
     *    @return	void
4515
     */
4516
    function select_currency($selected = '', $htmlname = 'currency_id')
4517
    {
4518
        // phpcs:enable
4519
        print $this->selectCurrency($selected, $htmlname);
4520
    }
4521
4522
    /**
4523
     *  Retourne la liste des devises, dans la langue de l'utilisateur
4524
     *
4525
     *  @param	string	$selected    preselected currency code
4526
     *  @param  string	$htmlname    name of HTML select list
4527
     * 	@return	string
4528
     */
4529
    function selectCurrency($selected = '', $htmlname = 'currency_id')
4530
    {
4531
        global $conf, $langs, $user;
4532
4533
        $langs->loadCacheCurrencies('');
4534
4535
        $out = '';
4536
4537
        if ($selected == 'euro' || $selected == 'euros')
4538
            $selected = 'EUR';   // Pour compatibilite
4539
4540
        $out .= '<select class="flat maxwidth200onsmartphone minwidth300" name="' . $htmlname . '" id="' . $htmlname . '">';
4541
        foreach ($langs->cache_currencies as $code_iso => $currency) {
4542
            if ($selected && $selected == $code_iso) {
4543
                $out .= '<option value="' . $code_iso . '" selected>';
4544
            } else {
4545
                $out .= '<option value="' . $code_iso . '">';
4546
            }
4547
            $out .= $currency['label'];
4548
            $out .= ' (' . $langs->getCurrencySymbol($code_iso) . ')';
4549
            $out .= '</option>';
4550
        }
4551
        $out .= '</select>';
4552
        if ($user->admin)
4553
            $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
4554
4555
        // Make select dynamic
4556
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4557
        $out .= ajax_combobox($htmlname);
4558
4559
        return $out;
4560
    }
4561
4562
    /**
4563
     * 	Return array of currencies in user language
4564
     *
4565
     *  @param	string	$selected    preselected currency code
4566
     *  @param  string	$htmlname    name of HTML select list
4567
     *  @param  integer	$useempty    1=Add empty line
4568
     * 	@return	string
4569
     */
4570
    function selectMultiCurrency($selected = '', $htmlname = 'multicurrency_code', $useempty = 0)
4571
    {
4572
        global $db, $conf, $langs, $user;
4573
4574
        $langs->loadCacheCurrencies('');        // Load ->cache_currencies
4575
4576
        $TCurrency = array();
4577
4578
        $sql = 'SELECT code FROM ' . MAIN_DB_PREFIX . 'multicurrency';
4579
        $sql .= " WHERE entity IN ('" . getEntity('mutlicurrency') . "')";
4580
        $resql = $db->query($sql);
4581
        if ($resql) {
4582
            while ($obj = $db->fetch_object($resql))
4583
                $TCurrency[$obj->code] = $obj->code;
4584
        }
4585
4586
        $out = '';
4587
        $out .= '<select class="flat" name="' . $htmlname . '" id="' . $htmlname . '">';
4588
        if ($useempty)
4589
            $out .= '<option value=""></option>';
4590
        // If company current currency not in table, we add it into list. Should always be available.
4591
        if (!in_array($conf->currency, $TCurrency)) {
4592
            $TCurrency[$conf->currency] = $conf->currency;
4593
        }
4594
        if (count($TCurrency) > 0) {
4595
            foreach ($langs->cache_currencies as $code_iso => $currency) {
4596
                if (isset($TCurrency[$code_iso])) {
4597
                    if (!empty($selected) && $selected == $code_iso)
4598
                        $out .= '<option value="' . $code_iso . '" selected="selected">';
4599
                    else
4600
                        $out .= '<option value="' . $code_iso . '">';
4601
4602
                    $out .= $currency['label'];
4603
                    $out .= ' (' . $langs->getCurrencySymbol($code_iso) . ')';
4604
                    $out .= '</option>';
4605
                }
4606
            }
4607
        }
4608
4609
        $out .= '</select>';
4610
        // Make select dynamic
4611
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4612
        $out .= ajax_combobox($htmlname);
4613
4614
        return $out;
4615
    }
4616
4617
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4618
    /**
4619
     * 	Load into the cache vat rates of a country
4620
     *
4621
     * 	@param	string	$country_code		Country code with quotes ("'CA'", or "'CA,IN,...'")
4622
     * 	@return	int							Nb of loaded lines, 0 if already loaded, <0 if KO
4623
     */
4624
    function load_cache_vatrates($country_code)
4625
    {
4626
        // phpcs:enable
4627
        global $langs;
4628
4629
        $num = count($this->cache_vatrates);
4630
        if ($num > 0)
4631
            return $num;    // Cache already loaded
4632
4633
        dol_syslog(__METHOD__, LOG_DEBUG);
4634
4635
        $sql = "SELECT DISTINCT t.rowid, t.code, t.taux, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.recuperableonly";
4636
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
4637
        $sql .= " WHERE t.fk_pays = c.rowid";
4638
        $sql .= " AND t.active > 0";
4639
        $sql .= " AND c.code IN (" . $country_code . ")";
4640
        $sql .= " ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC";
4641
4642
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4643
        if ($resql) {
4644
            $num = $this->db->num_rows($resql);
4645
            if ($num) {
4646
                for ($i = 0; $i < $num; $i++) {
4647
                    $obj = $this->db->fetch_object($resql);
4648
                    $this->cache_vatrates[$i]['rowid'] = $obj->rowid;
4649
                    $this->cache_vatrates[$i]['code'] = $obj->code;
4650
                    $this->cache_vatrates[$i]['txtva'] = $obj->taux;
4651
                    $this->cache_vatrates[$i]['nprtva'] = $obj->recuperableonly;
4652
                    $this->cache_vatrates[$i]['localtax1'] = $obj->localtax1;
4653
                    $this->cache_vatrates[$i]['localtax1_type'] = $obj->localtax1_type;
4654
                    $this->cache_vatrates[$i]['localtax2'] = $obj->localtax2;
4655
                    $this->cache_vatrates[$i]['localtax2_type'] = $obj->localtax1_type;
4656
4657
                    $this->cache_vatrates[$i]['label'] = $obj->taux . '%' . ($obj->code ? ' (' . $obj->code . ')' : '');   // Label must contains only 0-9 , . % or *
4658
                    $this->cache_vatrates[$i]['labelallrates'] = $obj->taux . '/' . ($obj->localtax1 ? $obj->localtax1 : '0') . '/' . ($obj->localtax2 ? $obj->localtax2 : '0') . ($obj->code ? ' (' . $obj->code . ')' : ''); // Must never be used as key, only label
4659
                    $positiverates = '';
4660
                    if ($obj->taux)
4661
                        $positiverates .= ($positiverates ? '/' : '') . $obj->taux;
4662
                    if ($obj->localtax1)
4663
                        $positiverates .= ($positiverates ? '/' : '') . $obj->localtax1;
4664
                    if ($obj->localtax2)
4665
                        $positiverates .= ($positiverates ? '/' : '') . $obj->localtax2;
4666
                    if (empty($positiverates))
4667
                        $positiverates = '0';
4668
                    $this->cache_vatrates[$i]['labelpositiverates'] = $positiverates . ($obj->code ? ' (' . $obj->code . ')' : ''); // Must never be used as key, only label
4669
                }
4670
4671
                return $num;
4672
            }
4673
            else {
4674
                $this->error = '<font class="error">' . $langs->trans("ErrorNoVATRateDefinedForSellerCountry", $country_code) . '</font>';
4675
                return -1;
4676
            }
4677
        } else {
4678
            $this->error = '<font class="error">' . $this->db->error() . '</font>';
4679
            return -2;
4680
        }
4681
    }
4682
4683
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4684
    /**
4685
     *  Output an HTML select vat rate.
4686
     *  The name of this function should be selectVat. We keep bad name for compatibility purpose.
4687
     *
4688
     *  @param	string	      $htmlname           Name of HTML select field
4689
     *  @param  float|string  $selectedrate       Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing.
4690
     *  @param  Societe	      $societe_vendeuse   Thirdparty seller
4691
     *  @param  Societe	      $societe_acheteuse  Thirdparty buyer
4692
     *  @param  int		      $idprod             Id product. O if unknown of NA.
4693
     *  @param  int		      $info_bits          Miscellaneous information on line (1 for NPR)
4694
     *  @param  int|string    $type               ''=Unknown, 0=Product, 1=Service (Used if idprod not defined)
4695
     *                  		                  Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle.
4696
     *                  					      Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle.
4697
     *                  					      Si (vendeur et acheteur dans Communaute europeenne) et bien vendu = moyen de transports neuf (auto, bateau, avion), TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle.
4698
     *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle.
4699
     *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle.
4700
     *                  					      Sinon la TVA proposee par defaut=0. Fin de regle.
4701
     *  @param	bool	     $options_only		  Return HTML options lines only (for ajax treatment)
4702
     *  @param  int          $mode                0=Use vat rate as key in combo list, 1=Add VAT code after vat rate into key, -1=Use id of vat line as key
4703
     *  @return	string
4704
     */
4705
    function load_tva($htmlname = 'tauxtva', $selectedrate = '', $societe_vendeuse = '', $societe_acheteuse = '', $idprod = 0, $info_bits = 0, $type = '', $options_only = false, $mode = 0)
4706
    {
4707
        // phpcs:enable
4708
        global $langs, $conf, $mysoc;
4709
4710
        $langs->load('errors');
4711
4712
        $return = '';
4713
4714
        // Define defaultnpr, defaultttx and defaultcode
4715
        $defaultnpr = ($info_bits & 0x01);
4716
        $defaultnpr = (preg_match('/\*/', $selectedrate) ? 1 : $defaultnpr);
4717
        $defaulttx = str_replace('*', '', $selectedrate);
4718
        $defaultcode = '';
4719
        if (preg_match('/\((.*)\)/', $defaulttx, $reg)) {
4720
            $defaultcode = $reg[1];
4721
            $defaulttx = preg_replace('/\s*\(.*\)/', '', $defaulttx);
4722
        }
4723
        //var_dump($selectedrate.'-'.$defaulttx.'-'.$defaultnpr.'-'.$defaultcode);
4724
        // Check parameters
4725
        if (is_object($societe_vendeuse) && !$societe_vendeuse->country_code) {
4726
            if ($societe_vendeuse->id == $mysoc->id) {
4727
                $return .= '<font class="error">' . $langs->trans("ErrorYourCountryIsNotDefined") . '</div>';
4728
            } else {
4729
                $return .= '<font class="error">' . $langs->trans("ErrorSupplierCountryIsNotDefined") . '</div>';
4730
            }
4731
            return $return;
4732
        }
4733
4734
        //var_dump($societe_acheteuse);
4735
        //print "name=$name, selectedrate=$selectedrate, seller=".$societe_vendeuse->country_code." buyer=".$societe_acheteuse->country_code." buyer is company=".$societe_acheteuse->isACompany()." idprod=$idprod, info_bits=$info_bits type=$type";
4736
        //exit;
4737
        // Define list of countries to use to search VAT rates to show
4738
        // First we defined code_country to use to find list
4739
        if (is_object($societe_vendeuse)) {
4740
            $code_country = "'" . $societe_vendeuse->country_code . "'";
4741
        } else {
4742
            $code_country = "'" . $mysoc->country_code . "'";   // Pour compatibilite ascendente
4743
        }
4744
        if (!empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) {    // If option to have vat for end customer for services is on
4745
            require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
4746
            if (!isInEEC($societe_vendeuse) && (!is_object($societe_acheteuse) || (isInEEC($societe_acheteuse) && !$societe_acheteuse->isACompany()))) {
4747
                // We also add the buyer
4748
                if (is_numeric($type)) {
4749
                    if ($type == 1) { // We know product is a service
4750
                        $code_country .= ",'" . $societe_acheteuse->country_code . "'";
0 ignored issues
show
Bug introduced by
The property country_code does not exist on string.
Loading history...
4751
                    }
4752
                } else if (!$idprod) {  // We don't know type of product
4753
                    $code_country .= ",'" . $societe_acheteuse->country_code . "'";
4754
                } else {
4755
                    $prodstatic = new Product($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4756
                    $prodstatic->fetch($idprod);
4757
                    if ($prodstatic->type == Product::TYPE_SERVICE) {   // We know product is a service
4758
                        $code_country .= ",'" . $societe_acheteuse->country_code . "'";
4759
                    }
4760
                }
4761
            }
4762
        }
4763
4764
        // Now we get list
4765
        $num = $this->load_cache_vatrates($code_country);   // If no vat defined, return -1 with message into this->error
4766
4767
        if ($num > 0) {
4768
            // Definition du taux a pre-selectionner (si defaulttx non force et donc vaut -1 ou '')
4769
            if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) {
4770
                $tmpthirdparty = new Societe($this->db);
4771
                $defaulttx = get_default_tva($societe_vendeuse, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
4772
                $defaultnpr = get_default_npr($societe_vendeuse, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
4773
                if (preg_match('/\((.*)\)/', $defaulttx, $reg)) {
4774
                    $defaultcode = $reg[1];
4775
                    $defaulttx = preg_replace('/\s*\(.*\)/', '', $defaulttx);
4776
                }
4777
                if (empty($defaulttx)) {
4778
                    $defaultnpr = 0;
4779
                }
4780
            }
4781
4782
            // Si taux par defaut n'a pu etre determine, on prend dernier de la liste.
4783
            // Comme ils sont tries par ordre croissant, dernier = plus eleve = taux courant
4784
            if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) {
4785
                if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) {
4786
                    $defaulttx = $this->cache_vatrates[$num - 1]['txtva'];
4787
                } else {
4788
                    $defaulttx = ($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS == 'none' ? '' : $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS);
4789
                }
4790
            }
4791
4792
            // Disabled if seller is not subject to VAT
4793
            $disabled = false;
4794
            $title = '';
4795
            if (is_object($societe_vendeuse) && $societe_vendeuse->id == $mysoc->id && $societe_vendeuse->tva_assuj == "0") {
4796
                // Override/enable VAT for expense report regardless of global setting - needed if expense report used for business expenses
4797
                if (empty($conf->global->OVERRIDE_VAT_FOR_EXPENSE_REPORT)) {
4798
                    $title = ' title="' . $langs->trans('VATIsNotUsed') . '"';
4799
                    $disabled = true;
4800
                }
4801
            }
4802
4803
            if (!$options_only) {
4804
                $return .= '<select class="flat minwidth75imp" id="' . $htmlname . '" name="' . $htmlname . '"' . ($disabled ? ' disabled' : '') . $title . '>';
4805
            }
4806
4807
            $selectedfound = false;
4808
            foreach ($this->cache_vatrates as $rate) {
4809
                // Keep only 0 if seller is not subject to VAT
4810
                if ($disabled && $rate['txtva'] != 0)
4811
                    continue;
4812
4813
                // Define key to use into select list
4814
                $key = $rate['txtva'];
4815
                $key .= $rate['nprtva'] ? '*' : '';
4816
                if ($mode > 0 && $rate['code'])
4817
                    $key .= ' (' . $rate['code'] . ')';
4818
                if ($mode < 0)
4819
                    $key = $rate['rowid'];
4820
4821
                $return .= '<option value="' . $key . '"';
4822
                if (!$selectedfound) {
4823
                    if ($defaultcode) { // If defaultcode is defined, we used it in priority to select combo option instead of using rate+npr flag
4824
                        if ($defaultcode == $rate['code']) {
4825
                            $return .= ' selected';
4826
                            $selectedfound = true;
4827
                        }
4828
                    } elseif ($rate['txtva'] == $defaulttx && $rate['nprtva'] == $defaultnpr) {
4829
                        $return .= ' selected';
4830
                        $selectedfound = true;
4831
                    }
4832
                }
4833
                $return .= '>';
4834
                //if (! empty($conf->global->MAIN_VAT_SHOW_POSITIVE_RATES))
4835
                if ($mysoc->country_code == 'IN' || !empty($conf->global->MAIN_VAT_LABEL_IS_POSITIVE_RATES)) {
4836
                    $return .= $rate['labelpositiverates'];
4837
                } else {
4838
                    $return .= vatrate($rate['label']);
4839
                }
4840
                //$return.=($rate['code']?' '.$rate['code']:'');
4841
                $return .= (empty($rate['code']) && $rate['nprtva']) ? ' *' : '';         // We show the *  (old behaviour only if new vat code is not used)
4842
4843
                $return .= '</option>';
4844
            }
4845
4846
            if (!$options_only)
4847
                $return .= '</select>';
4848
        }
4849
        else {
4850
            $return .= $this->error;
4851
        }
4852
4853
        $this->num = $num;
4854
        return $return;
4855
    }
4856
4857
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4858
    /**
4859
     *  Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
4860
     *  Fields are preselected with :
4861
     *            	- set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
4862
     *            	- local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
4863
     *            	- Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
4864
     *
4865
     * 	@param	timestamp	$set_time 		Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
4866
     * 	@param	string		$prefix			Prefix for fields name
4867
     * 	@param	int			$h				1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty
4868
     * 	@param	int			$m				1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty
4869
     * 	@param	int			$empty			0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
4870
     * 	@param	string		$form_name 		Not used
4871
     * 	@param	int			$d				1=Show days, month, years
4872
     * 	@param	int			$addnowlink		Add a link "Now"
4873
     * 	@param	int			$nooutput		Do not output html string but return it
4874
     * 	@param 	int			$disabled		Disable input fields
4875
     *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
4876
     *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another select_date field.
4877
     *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
0 ignored issues
show
Bug introduced by
The type Alixar\Base\datetime was not found. Did you mean datetime? If so, make sure to prefix the type with \.
Loading history...
4878
     *  @return	string|void					Nothing or string if nooutput is 1
4879
     *  @deprecated
4880
     *  @see    form_date, select_month, select_year, select_dayofweek
4881
     */
4882
    function select_date($set_time = '', $prefix = 're', $h = 0, $m = 0, $empty = 0, $form_name = "", $d = 1, $addnowlink = 0, $nooutput = 0, $disabled = 0, $fullday = '', $addplusone = '', $adddateof = '')
4883
    {
4884
        // phpcs:enable
4885
        $retstring = $this->selectDate($set_time, $prefix, $h, $m, $empty, $form_name, $d, $addnowlink, $disabled, $fullday, $addplusone, $adddateof);
4886
        if (!empty($nooutput)) {
4887
            return $retstring;
4888
        }
4889
        print $retstring;
4890
        return;
4891
    }
4892
4893
    /**
4894
     *  Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
4895
     *  Fields are preselected with :
4896
     *              - set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
4897
     *              - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
4898
     *              - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
4899
     *
4900
     *  @param  timestamp   $set_time       Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
4901
     *  @param	string		$prefix			Prefix for fields name
4902
     *  @param	int			$h				1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty
4903
     * 	@param	int			$m				1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty
4904
     * 	@param	int			$empty			0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
4905
     * 	@param	string		$form_name 		Not used
4906
     * 	@param	int			$d				1=Show days, month, years
4907
     * 	@param	int			$addnowlink		Add a link "Now"
4908
     * 	@param 	int			$disabled		Disable input fields
4909
     *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
4910
     *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another selectDate field.
4911
     *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
4912
     * 	@return string                      Html for selectDate
4913
     *  @see    form_date, select_month, select_year, select_dayofweek
4914
     */
4915
    function selectDate($set_time = '', $prefix = 're', $h = 0, $m = 0, $empty = 0, $form_name = "", $d = 1, $addnowlink = 0, $disabled = 0, $fullday = '', $addplusone = '', $adddateof = '')
4916
    {
4917
        global $conf, $langs;
4918
4919
        $retstring = '';
4920
4921
        if ($prefix == '')
4922
            $prefix = 're';
4923
        if ($h == '')
4924
            $h = 0;
4925
        if ($m == '')
4926
            $m = 0;
4927
        $emptydate = 0;
4928
        $emptyhours = 0;
4929
        if ($empty == 1) {
4930
            $emptydate = 1;
4931
            $emptyhours = 1;
4932
        }
4933
        if ($empty == 2) {
4934
            $emptydate = 0;
4935
            $emptyhours = 1;
4936
        }
4937
        $orig_set_time = $set_time;
4938
4939
        if ($set_time === '' && $emptydate == 0) {
4940
            include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
4941
            $set_time = dol_now('tzuser') - (getServerTimeZoneInt('now') * 3600); // set_time must be relative to PHP server timezone
4942
        }
4943
4944
        // Analysis of the pre-selection date
4945
        if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/', $set_time, $reg)) { // deprecated usage
4946
            // Date format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'
4947
            $syear = (!empty($reg[1]) ? $reg[1] : '');
4948
            $smonth = (!empty($reg[2]) ? $reg[2] : '');
4949
            $sday = (!empty($reg[3]) ? $reg[3] : '');
4950
            $shour = (!empty($reg[4]) ? $reg[4] : '');
4951
            $smin = (!empty($reg[5]) ? $reg[5] : '');
4952
        } elseif (strval($set_time) != '' && $set_time != -1) {
4953
            // set_time est un timestamps (0 possible)
4954
            $syear = dol_print_date($set_time, "%Y");
4955
            $smonth = dol_print_date($set_time, "%m");
4956
            $sday = dol_print_date($set_time, "%d");
4957
            if ($orig_set_time != '') {
4958
                $shour = dol_print_date($set_time, "%H");
4959
                $smin = dol_print_date($set_time, "%M");
4960
                $ssec = dol_print_date($set_time, "%S");
4961
            } else {
4962
                $shour = '';
4963
                $smin = '';
4964
                $ssec = '';
4965
            }
4966
        } else {
4967
            // Date est '' ou vaut -1
4968
            $syear = '';
4969
            $smonth = '';
4970
            $sday = '';
4971
            $shour = !isset($conf->global->MAIN_DEFAULT_DATE_HOUR) ? ($h == -1 ? '23' : '') : $conf->global->MAIN_DEFAULT_DATE_HOUR;
4972
            $smin = !isset($conf->global->MAIN_DEFAULT_DATE_MIN) ? ($h == -1 ? '59' : '') : $conf->global->MAIN_DEFAULT_DATE_MIN;
4973
            $ssec = !isset($conf->global->MAIN_DEFAULT_DATE_SEC) ? ($h == -1 ? '59' : '') : $conf->global->MAIN_DEFAULT_DATE_SEC;
4974
        }
4975
        if ($h == 3)
4976
            $shour = '';
4977
        if ($m == 3)
4978
            $smin = '';
4979
4980
        // You can set MAIN_POPUP_CALENDAR to 'eldy' or 'jquery'
4981
        $usecalendar = 'combo';
4982
        if (!empty($conf->use_javascript_ajax) && (empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR != "none")) {
4983
            $usecalendar = ((empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR == 'eldy') ? 'jquery' : $conf->global->MAIN_POPUP_CALENDAR);
4984
        }
4985
4986
        if ($d) {
4987
            // Show date with popup
4988
            if ($usecalendar != 'combo') {
4989
                $formated_date = '';
4990
                //print "e".$set_time." t ".$conf->format_date_short;
4991
                if (strval($set_time) != '' && $set_time != -1) {
4992
                    //$formated_date=dol_print_date($set_time,$conf->format_date_short);
4993
                    $formated_date = dol_print_date($set_time, $langs->trans("FormatDateShortInput"));  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
4994
                }
4995
4996
                // Calendrier popup version eldy
4997
                if ($usecalendar == "eldy") {
4998
                    // Zone de saisie manuelle de la date
4999
                    $retstring .= '<input id="' . $prefix . '" name="' . $prefix . '" type="text" class="maxwidth75" maxlength="11" value="' . $formated_date . '"';
5000
                    $retstring .= ($disabled ? ' disabled' : '');
5001
                    $retstring .= ' onChange="dpChangeDay(\'' . $prefix . '\',\'' . $langs->trans("FormatDateShortJavaInput") . '\'); "';  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
5002
                    $retstring .= '>';
5003
5004
                    // Icone calendrier
5005
                    if (!$disabled) {
5006
                        $retstring .= '<button id="' . $prefix . 'Button" type="button" class="dpInvisibleButtons"';
5007
                        $base = DOL_URL_ROOT . '/core/';
5008
                        $retstring .= ' onClick="showDP(\'' . $base . '\',\'' . $prefix . '\',\'' . $langs->trans("FormatDateShortJavaInput") . '\',\'' . $langs->defaultlang . '\');"';
5009
                        $retstring .= '>' . img_object($langs->trans("SelectDate"), 'calendarday', 'class="datecallink"') . '</button>';
5010
                    } else
5011
                        $retstring .= '<button id="' . $prefix . 'Button" type="button" class="dpInvisibleButtons">' . img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"') . '</button>';
5012
5013
                    $retstring .= '<input type="hidden" id="' . $prefix . 'day"   name="' . $prefix . 'day"   value="' . $sday . '">' . "\n";
5014
                    $retstring .= '<input type="hidden" id="' . $prefix . 'month" name="' . $prefix . 'month" value="' . $smonth . '">' . "\n";
5015
                    $retstring .= '<input type="hidden" id="' . $prefix . 'year"  name="' . $prefix . 'year"  value="' . $syear . '">' . "\n";
5016
                }
5017
                elseif ($usecalendar == 'jquery') {
5018
                    if (!$disabled) {
5019
                        // Output javascript for datepicker
5020
                        $retstring .= "<script type='text/javascript'>";
5021
                        $retstring .= "$(function(){ $('#" . $prefix . "').datepicker({
5022
							dateFormat: '" . $langs->trans("FormatDateShortJQueryInput") . "',
5023
							autoclose: true,
5024
							todayHighlight: true,";
5025
                        if (!empty($conf->dol_use_jmobile)) {
5026
                            $retstring .= "
5027
								beforeShow: function (input, datePicker) {
5028
									input.disabled = true;
5029
								},
5030
								onClose: function (dateText, datePicker) {
5031
									this.disabled = false;
5032
								},
5033
								";
5034
                        }
5035
                        // Note: We don't need monthNames, monthNamesShort, dayNames, dayNamesShort, dayNamesMin, they are set globally on datepicker component in lib_head.js.php
5036
                        if (empty($conf->global->MAIN_POPUP_CALENDAR_ON_FOCUS)) {
5037
                            /*
5038
                              $retstring .= "
5039
                              showOn: 'button',
5040
                              buttonImage: '" . DOL_URL_ROOT . "/theme/" . $conf->theme . "/img/object_calendarday.png',
5041
                              buttonImageOnly: true";
5042
                             */
5043
                            $retstring .= "
5044
								showOn: 'button',
5045
								buttonImage: '" . DOL_BASE_URI . "/theme/" . $conf->theme . "/img/object_calendarday.png',
5046
								buttonImageOnly: true";
5047
                        }
5048
                        $retstring .= "
5049
							}) });";
5050
                        $retstring .= "</script>";
5051
                    }
5052
5053
                    // Zone de saisie manuelle de la date
5054
                    $retstring .= '<div class="nowrap inline-block">';
5055
                    $retstring .= '<input id="' . $prefix . '" name="' . $prefix . '" type="text" class="maxwidth75" maxlength="11" value="' . $formated_date . '"';
5056
                    $retstring .= ($disabled ? ' disabled' : '');
5057
                    $retstring .= ' onChange="dpChangeDay(\'' . $prefix . '\',\'' . $langs->trans("FormatDateShortJavaInput") . '\'); "';  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
5058
                    $retstring .= '>';
5059
5060
                    // Icone calendrier
5061
                    if (!$disabled) {
5062
                        /* Not required. Managed by option buttonImage of jquery
5063
                          $retstring.=img_object($langs->trans("SelectDate"),'calendarday','id="'.$prefix.'id" class="datecallink"');
5064
                          $retstring.="<script type='text/javascript'>";
5065
                          $retstring.="jQuery(document).ready(function() {";
5066
                          $retstring.='	jQuery("#'.$prefix.'id").click(function() {';
5067
                          $retstring.="    	jQuery('#".$prefix."').focus();";
5068
                          $retstring.='    });';
5069
                          $retstring.='});';
5070
                          $retstring.="</script>"; */
5071
                    } else {
5072
                        $retstring .= '<button id="' . $prefix . 'Button" type="button" class="dpInvisibleButtons">' . img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"') . '</button>';
5073
                    }
5074
5075
                    $retstring .= '</div>';
5076
                    $retstring .= '<input type="hidden" id="' . $prefix . 'day"   name="' . $prefix . 'day"   value="' . $sday . '">' . "\n";
5077
                    $retstring .= '<input type="hidden" id="' . $prefix . 'month" name="' . $prefix . 'month" value="' . $smonth . '">' . "\n";
5078
                    $retstring .= '<input type="hidden" id="' . $prefix . 'year"  name="' . $prefix . 'year"  value="' . $syear . '">' . "\n";
5079
                } else {
5080
                    $retstring .= "Bad value of MAIN_POPUP_CALENDAR";
5081
                }
5082
            }
5083
            // Show date with combo selects
5084
            else {
5085
                //$retstring.='<div class="inline-block">';
5086
                // Day
5087
                $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50imp" id="' . $prefix . 'day" name="' . $prefix . 'day">';
5088
5089
                if ($emptydate || $set_time == -1) {
5090
                    $retstring .= '<option value="0" selected>&nbsp;</option>';
5091
                }
5092
5093
                for ($day = 1; $day <= 31; $day++) {
5094
                    $retstring .= '<option value="' . $day . '"' . ($day == $sday ? ' selected' : '') . '>' . $day . '</option>';
5095
                }
5096
5097
                $retstring .= "</select>";
5098
5099
                $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75imp" id="' . $prefix . 'month" name="' . $prefix . 'month">';
5100
                if ($emptydate || $set_time == -1) {
5101
                    $retstring .= '<option value="0" selected>&nbsp;</option>';
5102
                }
5103
5104
                // Month
5105
                for ($month = 1; $month <= 12; $month++) {
5106
                    $retstring .= '<option value="' . $month . '"' . ($month == $smonth ? ' selected' : '') . '>';
5107
                    $retstring .= dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b");
5108
                    $retstring .= "</option>";
5109
                }
5110
                $retstring .= "</select>";
5111
5112
                // Year
5113
                if ($emptydate || $set_time == -1) {
5114
                    $retstring .= '<input' . ($disabled ? ' disabled' : '') . ' placeholder="' . dol_escape_htmltag($langs->trans("Year")) . '" class="flat maxwidth50imp valignmiddle" type="number" min="0" max="3000" maxlength="4" id="' . $prefix . 'year" name="' . $prefix . 'year" value="' . $syear . '">';
5115
                } else {
5116
                    $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75imp" id="' . $prefix . 'year" name="' . $prefix . 'year">';
5117
5118
                    for ($year = $syear - 10; $year < $syear + 10; $year++) {
5119
                        $retstring .= '<option value="' . $year . '"' . ($year == $syear ? ' selected' : '') . '>' . $year . '</option>';
5120
                    }
5121
                    $retstring .= "</select>\n";
5122
                }
5123
                //$retstring.='</div>';
5124
            }
5125
        }
5126
5127
        if ($d && $h)
5128
            $retstring .= ($h == 2 ? '<br>' : ' ');
5129
5130
        if ($h) {
5131
            // Show hour
5132
            $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50 ' . ($fullday ? $fullday . 'hour' : '') . '" id="' . $prefix . 'hour" name="' . $prefix . 'hour">';
5133
            if ($emptyhours)
5134
                $retstring .= '<option value="-1">&nbsp;</option>';
5135
            for ($hour = 0; $hour < 24; $hour++) {
5136
                if (strlen($hour) < 2)
5137
                    $hour = "0" . $hour;
5138
                $retstring .= '<option value="' . $hour . '"' . (($hour == $shour) ? ' selected' : '') . '>' . $hour . (empty($conf->dol_optimize_smallscreen) ? '' : 'H') . '</option>';
5139
            }
5140
            $retstring .= '</select>';
5141
            if ($m && empty($conf->dol_optimize_smallscreen))
5142
                $retstring .= ":";
5143
        }
5144
5145
        if ($m) {
5146
            // Show minutes
5147
            $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50 ' . ($fullday ? $fullday . 'min' : '') . '" id="' . $prefix . 'min" name="' . $prefix . 'min">';
5148
            if ($emptyhours)
5149
                $retstring .= '<option value="-1">&nbsp;</option>';
5150
            for ($min = 0; $min < 60; $min++) {
5151
                if (strlen($min) < 2)
5152
                    $min = "0" . $min;
5153
                $retstring .= '<option value="' . $min . '"' . (($min == $smin) ? ' selected' : '') . '>' . $min . (empty($conf->dol_optimize_smallscreen) ? '' : '') . '</option>';
5154
            }
5155
            $retstring .= '</select>';
5156
5157
            $retstring .= '<input type="hidden" name="' . $prefix . 'sec" value="' . $ssec . '">';
5158
        }
5159
5160
        // Add a "Now" link
5161
        if ($conf->use_javascript_ajax && $addnowlink) {
5162
            // Script which will be inserted in the onClick of the "Now" link
5163
            $reset_scripts = "";
5164
5165
            // Generate the date part, depending on the use or not of the javascript calendar
5166
            $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date(dol_now(), 'day') . '\');';
5167
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date(dol_now(), '%d') . '\');';
5168
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date(dol_now(), '%m') . '\');';
5169
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date(dol_now(), '%Y') . '\');';
5170
            /* if ($usecalendar == "eldy")
5171
              {
5172
              $base=DOL_URL_ROOT.'/core/';
5173
              $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');';
5174
              }
5175
              else
5176
              {
5177
              $reset_scripts .= 'this.form.elements[\''.$prefix.'day\'].value=formatDate(new Date(), \'d\'); ';
5178
              $reset_scripts .= 'this.form.elements[\''.$prefix.'month\'].value=formatDate(new Date(), \'M\'); ';
5179
              $reset_scripts .= 'this.form.elements[\''.$prefix.'year\'].value=formatDate(new Date(), \'yyyy\'); ';
5180
              } */
5181
            // Update the hour part
5182
            if ($h) {
5183
                if ($fullday)
5184
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5185
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); ';
5186
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . dol_print_date(dol_now(), '%H') . '\');';
5187
                if ($fullday)
5188
                    $reset_scripts .= ' } ';
5189
            }
5190
            // Update the minute part
5191
            if ($m) {
5192
                if ($fullday)
5193
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5194
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); ';
5195
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . dol_print_date(dol_now(), '%M') . '\');';
5196
                if ($fullday)
5197
                    $reset_scripts .= ' } ';
5198
            }
5199
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
5200
            if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) {
5201
                $retstring .= ' <button class="dpInvisibleButtons datenowlink" id="' . $prefix . 'ButtonNow" type="button" name="_useless" value="now" onClick="' . $reset_scripts . '">';
5202
                $retstring .= $langs->trans("Now");
5203
                $retstring .= '</button> ';
5204
            }
5205
        }
5206
5207
        // Add a "Plus one hour" link
5208
        if ($conf->use_javascript_ajax && $addplusone) {
5209
            // Script which will be inserted in the onClick of the "Add plusone" link
5210
            $reset_scripts = "";
5211
5212
            // Generate the date part, depending on the use or not of the javascript calendar
5213
            $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date(dol_now(), 'day') . '\');';
5214
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date(dol_now(), '%d') . '\');';
5215
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date(dol_now(), '%m') . '\');';
5216
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date(dol_now(), '%Y') . '\');';
5217
            // Update the hour part
5218
            if ($h) {
5219
                if ($fullday)
5220
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5221
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . dol_print_date(dol_now(), '%H') . '\');';
5222
                if ($fullday)
5223
                    $reset_scripts .= ' } ';
5224
            }
5225
            // Update the minute part
5226
            if ($m) {
5227
                if ($fullday)
5228
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5229
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . dol_print_date(dol_now(), '%M') . '\');';
5230
                if ($fullday)
5231
                    $reset_scripts .= ' } ';
5232
            }
5233
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
5234
            if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) {
5235
                $retstring .= ' <button class="dpInvisibleButtons datenowlink" id="' . $prefix . 'ButtonPlusOne" type="button" name="_useless2" value="plusone" onClick="' . $reset_scripts . '">';
5236
                $retstring .= $langs->trans("DateStartPlusOne");
5237
                $retstring .= '</button> ';
5238
            }
5239
        }
5240
5241
        // Add a "Plus one hour" link
5242
        if ($conf->use_javascript_ajax && $adddateof) {
5243
            $tmparray = dol_getdate($adddateof);
5244
            $retstring .= ' - <button class="dpInvisibleButtons datenowlink" id="dateofinvoice" type="button" name="_dateofinvoice" value="now" onclick="jQuery(\'#re\').val(\'' . dol_print_date($adddateof, 'day') . '\');jQuery(\'#reday\').val(\'' . $tmparray['mday'] . '\');jQuery(\'#remonth\').val(\'' . $tmparray['mon'] . '\');jQuery(\'#reyear\').val(\'' . $tmparray['year'] . '\');">' . $langs->trans("DateInvoice") . '</a>';
5245
        }
5246
5247
        return $retstring;
5248
    }
5249
5250
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
5251
    /**
5252
     * 	Function to show a form to select a duration on a page
5253
     *
5254
     * 	@param	string	$prefix   		Prefix for input fields
5255
     * 	@param  int	$iSecond  		    Default preselected duration (number of seconds or '')
5256
     * 	@param	int	$disabled           Disable the combo box
5257
     * 	@param	string	$typehour		If 'select' then input hour and input min is a combo,
5258
     * 						            if 'text' input hour is in text and input min is a text,
5259
     * 						            if 'textselect' input hour is in text and input min is a combo
5260
     *  @param	integer	$minunderhours	If 1, show minutes selection under the hours
5261
     * 	@param	int	$nooutput		    Do not output html string but return it
5262
     *  @return	string|void
5263
     */
5264
    function select_duration($prefix, $iSecond = '', $disabled = 0, $typehour = 'select', $minunderhours = 0, $nooutput = 0)
5265
    {
5266
        // phpcs:enable
5267
        global $langs;
5268
5269
        $retstring = '';
5270
5271
        $hourSelected = 0;
5272
        $minSelected = 0;
5273
5274
        // Hours
5275
        if ($iSecond != '') {
5276
            require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
5277
5278
            $hourSelected = convertSecondToTime($iSecond, 'allhour');
5279
            $minSelected = convertSecondToTime($iSecond, 'min');
5280
        }
5281
5282
        if ($typehour == 'select') {
5283
            $retstring .= '<select class="flat" id="select_' . $prefix . 'hour" name="' . $prefix . 'hour"' . ($disabled ? ' disabled' : '') . '>';
5284
            for ($hour = 0; $hour < 25; $hour++) { // For a duration, we allow 24 hours
5285
                $retstring .= '<option value="' . $hour . '"';
5286
                if ($hourSelected == $hour) {
5287
                    $retstring .= " selected";
5288
                }
5289
                $retstring .= ">" . $hour . "</option>";
5290
            }
5291
            $retstring .= "</select>";
5292
        } elseif ($typehour == 'text' || $typehour == 'textselect') {
5293
            $retstring .= '<input placeholder="' . $langs->trans('HourShort') . '" type="number" min="0" size="1" name="' . $prefix . 'hour"' . ($disabled ? ' disabled' : '') . ' class="flat maxwidth50 inputhour" value="' . (($hourSelected != '') ? ((int) $hourSelected) : '') . '">';
5294
        } else
5295
            return 'BadValueForParameterTypeHour';
5296
5297
        if ($typehour != 'text')
5298
            $retstring .= ' ' . $langs->trans('HourShort');
5299
        else
5300
            $retstring .= '<span class="hideonsmartphone">:</span>';
5301
5302
        // Minutes
5303
        if ($minunderhours)
5304
            $retstring .= '<br>';
5305
        else
5306
            $retstring .= '<span class="hideonsmartphone">&nbsp;</span>';
5307
5308
        if ($typehour == 'select' || $typehour == 'textselect') {
5309
            $retstring .= '<select class="flat" id="select_' . $prefix . 'min" name="' . $prefix . 'min"' . ($disabled ? ' disabled' : '') . '>';
5310
            for ($min = 0; $min <= 55; $min = $min + 5) {
5311
                $retstring .= '<option value="' . $min . '"';
5312
                if ($minSelected == $min)
5313
                    $retstring .= ' selected';
5314
                $retstring .= '>' . $min . '</option>';
5315
            }
5316
            $retstring .= "</select>";
5317
        }
5318
        elseif ($typehour == 'text') {
5319
            $retstring .= '<input placeholder="' . $langs->trans('MinuteShort') . '" type="number" min="0" size="1" name="' . $prefix . 'min"' . ($disabled ? ' disabled' : '') . ' class="flat maxwidth50 inputminute" value="' . (($minSelected != '') ? ((int) $minSelected) : '') . '">';
5320
        }
5321
5322
        if ($typehour != 'text')
5323
            $retstring .= ' ' . $langs->trans('MinuteShort');
5324
5325
        //$retstring.="&nbsp;";
5326
5327
        if (!empty($nooutput))
5328
            return $retstring;
5329
5330
        print $retstring;
5331
        return;
5332
    }
5333
5334
    /**
5335
     * Generic method to select a component from a combo list.
5336
     * This is the generic method that will replace all specific existing methods.
5337
     *
5338
     * @param 	string			$objectdesc			Objectclassname:Objectclasspath
5339
     * @param	string			$htmlname			Name of HTML select component
5340
     * @param	int				$preselectedvalue	Preselected value (ID of element)
5341
     * @param	string			$showempty			''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
5342
     * @param	string			$searchkey			Search criteria
5343
     * @param	string			$placeholder		Place holder
5344
     * @param	string			$morecss			More CSS
5345
     * @param	string			$moreparams			More params provided to ajax call
5346
     * @param	int				$forcecombo			Force to load all values and output a standard combobox (with no beautification)
5347
     * @return	string								Return HTML string
5348
     * @see selectForFormsList select_thirdparty
5349
     */
5350
    function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0)
5351
    {
5352
        global $conf, $user;
5353
5354
        $objecttmp = null;
5355
5356
        $InfoFieldList = explode(":", $objectdesc);
5357
        $classname = $InfoFieldList[0];
5358
        $classpath = $InfoFieldList[1];
5359
        if (!empty($classpath)) {
5360
            dol_include_once($classpath);
5361
            if ($classname && class_exists($classname)) {
5362
                $objecttmp = new $classname($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
5363
            }
5364
        }
5365
        if (!is_object($objecttmp)) {
5366
            dol_syslog('Error bad setup of type for field ' . $InfoFieldList, LOG_WARNING);
5367
            return 'Error bad setup of type for field ' . join(',', $InfoFieldList);
5368
        }
5369
5370
        $prefixforautocompletemode = $objecttmp->element;
5371
        if ($prefixforautocompletemode == 'societe')
5372
            $prefixforautocompletemode = 'company';
5373
        $confkeyforautocompletemode = strtoupper($prefixforautocompletemode) . '_USE_SEARCH_TO_SELECT'; // For example COMPANY_USE_SEARCH_TO_SELECT
5374
5375
        dol_syslog(get_class($this) . "::selectForForms", LOG_DEBUG);
5376
5377
        $out = '';
5378
        if (!empty($conf->use_javascript_ajax) && !empty($conf->global->$confkeyforautocompletemode) && !$forcecombo) {
5379
            $objectdesc = $classname . ':' . $classpath;
5380
            $urlforajaxcall = DOL_URL_ROOT . '/core/ajax/selectobject.php';
5381
            //if ($objecttmp->element == 'societe') $urlforajaxcall = DOL_URL_ROOT.'/societe/ajax/company.php';
5382
            // No immediate load of all database
5383
            $urloption = 'htmlname=' . $htmlname . '&outjson=1&objectdesc=' . $objectdesc . ($moreparams ? $moreparams : '');
5384
            // Activate the auto complete using ajax call.
5385
            $out .= ajax_autocompleter($preselectedvalue, $htmlname, $urlforajaxcall, $urloption, $conf->global->$confkeyforautocompletemode, 0, array());
5386
            $out .= '<style type="text/css">.ui-autocomplete { z-index: 250; }</style>';
5387
            if ($placeholder)
5388
                $placeholder = ' placeholder="' . $placeholder . '"';
5389
            $out .= '<input type="text" class="' . $morecss . '" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $preselectedvalue . '"' . $placeholder . ' />';
5390
        }
5391
        else {
5392
            // Immediate load of all database
5393
            $out .= $this->selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo);
5394
        }
5395
5396
        return $out;
5397
    }
5398
5399
    /**
5400
     * Output html form to select an object.
5401
     * Note, this function is called by selectForForms or by ajax selectobject.php
5402
     *
5403
     * @param 	Object			$objecttmp			Object
5404
     * @param	string			$htmlname			Name of HTML select component
5405
     * @param	int				$preselectedvalue	Preselected value (ID of element)
5406
     * @param	string			$showempty			''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
5407
     * @param	string			$searchkey			Search value
5408
     * @param	string			$placeholder		Place holder
5409
     * @param	string			$morecss			More CSS
5410
     * @param	string			$moreparams			More params provided to ajax call
5411
     * @param	int				$forcecombo			Force to load all values and output a standard combobox (with no beautification)
5412
     * @param	int				$outputmode			0=HTML select string, 1=Array
5413
     * @return	string								Return HTML string
5414
     * @see selectForForms
5415
     */
5416
    function selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $outputmode = 0)
5417
    {
5418
        global $conf, $langs, $user;
5419
5420
        $prefixforautocompletemode = $objecttmp->element;
5421
        if ($prefixforautocompletemode == 'societe')
5422
            $prefixforautocompletemode = 'company';
5423
        $confkeyforautocompletemode = strtoupper($prefixforautocompletemode) . '_USE_SEARCH_TO_SELECT'; // For example COMPANY_USE_SEARCH_TO_SELECT
5424
5425
        $fieldstoshow = 't.ref';
5426
        if (!empty($objecttmp->fields)) { // For object that declare it, it is better to use declared fields ( like societe, contact, ...)
5427
            $tmpfieldstoshow = '';
5428
            foreach ($objecttmp->fields as $key => $val) {
5429
                if ($val['showoncombobox'])
5430
                    $tmpfieldstoshow .= ($tmpfieldstoshow ? ',' : '') . 't.' . $key;
5431
            }
5432
            if ($tmpfieldstoshow)
5433
                $fieldstoshow = $tmpfieldstoshow;
5434
        }
5435
5436
        $out = '';
5437
        $outarray = array();
5438
5439
        $num = 0;
5440
5441
        // Search data
5442
        $sql = "SELECT t.rowid, " . $fieldstoshow . " FROM " . MAIN_DB_PREFIX . $objecttmp->table_element . " as t";
5443
        if ($objecttmp->ismultientitymanaged == 2)
5444
            if (!$user->rights->societe->client->voir && !$user->societe_id)
5445
                $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
5446
        $sql .= " WHERE 1=1";
5447
        if (!empty($objecttmp->ismultientitymanaged))
5448
            $sql .= " AND t.entity IN (" . getEntity($objecttmp->table_element) . ")";
5449
        if ($objecttmp->ismultientitymanaged == 1 && !empty($user->societe_id)) {
5450
            if ($objecttmp->element == 'societe')
5451
                $sql .= " AND t.rowid = " . $user->societe_id;
5452
            else
5453
                $sql .= " AND t.fk_soc = " . $user->societe_id;
5454
        }
5455
        if ($searchkey != '')
5456
            $sql .= natural_search(explode(',', $fieldstoshow), $searchkey);
5457
        if ($objecttmp->ismultientitymanaged == 2)
5458
            if (!$user->rights->societe->client->voir && !$user->societe_id)
5459
                $sql .= " AND t.rowid = sc.fk_soc AND sc.fk_user = " . $user->id;
5460
        $sql .= $this->db->order($fieldstoshow, "ASC");
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
5461
        //$sql.=$this->db->plimit($limit, 0);
5462
        // Build output string
5463
        $resql = $this->db->query($sql);
5464
        if ($resql) {
5465
            if (!$forcecombo) {
5466
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
5467
                $out .= ajax_combobox($htmlname, null, $conf->global->$confkeyforautocompletemode);
5468
            }
5469
5470
            // Construct $out and $outarray
5471
            $out .= '<select id="' . $htmlname . '" class="flat' . ($morecss ? ' ' . $morecss : '') . '"' . ($moreparams ? ' ' . $moreparams : '') . ' name="' . $htmlname . '">' . "\n";
5472
5473
            // Warning: Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'. Seems it is no more true with selec2 v4
5474
            $textifempty = '&nbsp;';
5475
5476
            //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
5477
            if (!empty($conf->global->$confkeyforautocompletemode)) {
5478
                if ($showempty && !is_numeric($showempty))
5479
                    $textifempty = $langs->trans($showempty);
5480
                else
5481
                    $textifempty .= $langs->trans("All");
5482
            }
5483
            if ($showempty)
5484
                $out .= '<option value="-1">' . $textifempty . '</option>' . "\n";
5485
5486
            $num = $this->db->num_rows($resql);
5487
            $i = 0;
5488
            if ($num) {
5489
                while ($i < $num) {
5490
                    $obj = $this->db->fetch_object($resql);
5491
                    $label = '';
5492
                    $tmparray = explode(',', $fieldstoshow);
5493
                    foreach ($tmparray as $key => $val) {
5494
                        $val = preg_replace('/t\./', '', $val);
5495
                        $label .= (($label && $obj->$val) ? ' - ' : '') . $obj->$val;
5496
                    }
5497
                    if (empty($outputmode)) {
5498
                        if ($preselectedvalue > 0 && $preselectedvalue == $obj->rowid) {
5499
                            $out .= '<option value="' . $obj->rowid . '" selected>' . $label . '</option>';
5500
                        } else {
5501
                            $out .= '<option value="' . $obj->rowid . '">' . $label . '</option>';
5502
                        }
5503
                    } else {
5504
                        array_push($outarray, array('key' => $obj->rowid, 'value' => $label, 'label' => $label));
5505
                    }
5506
5507
                    $i++;
5508
                    if (($i % 10) == 0)
5509
                        $out .= "\n";
5510
                }
5511
            }
5512
5513
            $out .= '</select>' . "\n";
5514
        }
5515
        else {
5516
            dol_print_error($this->db);
5517
        }
5518
5519
        $this->result = array('nbofelement' => $num);
5520
5521
        if ($outputmode)
5522
            return $outarray;
5523
        return $out;
5524
    }
5525
5526
    /**
5527
     * 	Return a HTML select string, built from an array of key+value.
5528
     *  Note: Do not apply langs->trans function on returned content, content may be entity encoded twice.
5529
     *
5530
     * 	@param	string			$htmlname			Name of html select area. Must start with "multi" if this is a multiselect
5531
     * 	@param	array			$array				Array (key => value)
5532
     * 	@param	string|string[]	$id					Preselected key or preselected keys for multiselect
5533
     * 	@param	int|string		$show_empty			0 no empty value allowed, 1 or string to add an empty value into list (key is -1 and value is '' or '&nbsp;' if 1, key is -1 and value is text if string), <0 to add an empty value with key that is this value.
5534
     * 	@param	int				$key_in_label		1 to show key into label with format "[key] value"
5535
     * 	@param	int				$value_as_key		1 to use value as key
5536
     * 	@param  string			$moreparam			Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
5537
     * 	@param  int				$translate			1=Translate and encode value
5538
     * 	@param	int				$maxlen				Length maximum for labels
5539
     * 	@param	int				$disabled			Html select box is disabled
5540
     *  @param	string			$sort				'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order
5541
     *  @param	string			$morecss			Add more class to css styles
5542
     *  @param	int				$addjscombo			Add js combo
5543
     *  @param  string          $moreparamonempty	Add more param on the empty option line. Not used if show_empty not set
5544
     *  @param  int             $disablebademail	Check if an email is found into value and if not disable and colorize entry
5545
     *  @param  int             $nohtmlescape		No html escaping.
5546
     * 	@return	string								HTML select string.
5547
     *  @see multiselectarray
5548
     */
5549
    static function selectarray($htmlname, $array, $id = '', $show_empty = 0, $key_in_label = 0, $value_as_key = 0, $moreparam = '', $translate = 0, $maxlen = 0, $disabled = 0, $sort = '', $morecss = '', $addjscombo = 0, $moreparamonempty = '', $disablebademail = 0, $nohtmlescape = 0)
5550
    {
5551
        global $conf, $langs;
5552
5553
        // Do we want a multiselect ?
5554
        //$jsbeautify = 0;
5555
        //if (preg_match('/^multi/',$htmlname)) $jsbeautify = 1;
5556
        $jsbeautify = 1;
5557
5558
        if ($value_as_key)
5559
            $array = array_combine($array, $array);
5560
5561
        $out = '';
5562
5563
        // Add code for jquery to use multiselect
5564
        if ($addjscombo && $jsbeautify) {
5565
            $minLengthToAutocomplete = 0;
5566
            $tmpplugin = empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) ? (constant('REQUIRE_JQUERY_MULTISELECT') ? constant('REQUIRE_JQUERY_MULTISELECT') : 'select2') : $conf->global->MAIN_USE_JQUERY_MULTISELECT;
5567
5568
            // Enhance with select2
5569
            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
5570
            $out .= ajax_combobox($htmlname);
5571
        }
5572
5573
        $out .= '<select id="' . preg_replace('/^\./', '', $htmlname) . '" ' . ($disabled ? 'disabled ' : '') . 'class="flat ' . (preg_replace('/^\./', '', $htmlname)) . ($morecss ? ' ' . $morecss : '') . '"';
5574
        $out .= ' name="' . preg_replace('/^\./', '', $htmlname) . '" ' . ($moreparam ? $moreparam : '');
5575
        $out .= '>';
5576
5577
        if ($show_empty) {
5578
            $textforempty = ' ';
5579
            if (!empty($conf->use_javascript_ajax))
5580
                $textforempty = '&nbsp;'; // If we use ajaxcombo, we need &nbsp; here to avoid to have an empty element that is too small.
5581
            if (!is_numeric($show_empty))
5582
                $textforempty = $show_empty;
5583
            $out .= '<option class="optiongrey" ' . ($moreparamonempty ? $moreparamonempty . ' ' : '') . 'value="' . ($show_empty < 0 ? $show_empty : -1) . '"' . ($id == $show_empty ? ' selected' : '') . '>' . $textforempty . '</option>' . "\n";
5584
        }
5585
5586
        if (is_array($array)) {
5587
            // Translate
5588
            if ($translate) {
5589
                foreach ($array as $key => $value) {
5590
                    $array[$key] = $langs->trans($value);
5591
                }
5592
            }
5593
5594
            // Sort
5595
            if ($sort == 'ASC')
5596
                asort($array);
5597
            elseif ($sort == 'DESC')
5598
                arsort($array);
5599
5600
            foreach ($array as $key => $value) {
5601
                $disabled = '';
5602
                $style = '';
5603
                if (!empty($disablebademail)) {
5604
                    if (!preg_match('/&lt;.+@.+&gt;/', $value)) {
5605
                        //$value=preg_replace('/'.preg_quote($a,'/').'/', $b, $value);
5606
                        $disabled = ' disabled';
5607
                        $style = ' class="warning"';
5608
                    }
5609
                }
5610
5611
                if ($key_in_label) {
5612
                    if (empty($nohtmlescape))
5613
                        $selectOptionValue = dol_escape_htmltag($key . ' - ' . ($maxlen ? dol_trunc($value, $maxlen) : $value));
5614
                    else
5615
                        $selectOptionValue = $key . ' - ' . ($maxlen ? dol_trunc($value, $maxlen) : $value);
5616
                }
5617
                else {
5618
                    if (empty($nohtmlescape))
5619
                        $selectOptionValue = dol_escape_htmltag($maxlen ? dol_trunc($value, $maxlen) : $value);
5620
                    else
5621
                        $selectOptionValue = $maxlen ? dol_trunc($value, $maxlen) : $value;
5622
                    if ($value == '' || $value == '-')
5623
                        $selectOptionValue = '&nbsp;';
5624
                }
5625
5626
                $out .= '<option value="' . $key . '"';
5627
                $out .= $style . $disabled;
5628
                if ($id != '' && $id == $key && !$disabled)
5629
                    $out .= ' selected';  // To preselect a value
5630
                if ($nohtmlescape)
5631
                    $out .= ' data-html="' . dol_escape_htmltag($selectOptionValue) . '"';
5632
                $out .= '>';
5633
                //var_dump($selectOptionValue);
5634
                $out .= $selectOptionValue;
5635
                $out .= "</option>\n";
5636
            }
5637
        }
5638
5639
        $out .= "</select>";
5640
        return $out;
5641
    }
5642
5643
    /**
5644
     * 	Return a HTML select string, built from an array of key+value, but content returned into select come from an Ajax call of an URL.
5645
     *  Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice.
5646
     *
5647
     * 	@param	string	$htmlname       		Name of html select area
5648
     * 	@param	string	$url					Url. Must return a json_encode of array(key=>array('text'=>'A text', 'url'=>'An url'), ...)
5649
     * 	@param	string	$id             		Preselected key
5650
     * 	@param  string	$moreparam      		Add more parameters onto the select tag
5651
     * 	@param  string	$moreparamtourl 		Add more parameters onto the Ajax called URL
5652
     * 	@param	int		$disabled				Html select box is disabled
5653
     *  @param	int		$minimumInputLength		Minimum Input Length
5654
     *  @param	string	$morecss				Add more class to css styles
5655
     *  @param  int     $callurlonselect        If set to 1, some code is added so an url return by the ajax is called when value is selected.
5656
     *  @param  string  $placeholder            String to use as placeholder
5657
     *  @param  integer $acceptdelayedhtml      1 = caller is requesting to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect)
5658
     * 	@return	string   						HTML select string
5659
     *  @see selectArrayFilter, ajax_combobox in ajax.lib.php
5660
     */
5661
    static function selectArrayAjax($htmlname, $url, $id = '', $moreparam = '', $moreparamtourl = '', $disabled = 0, $minimumInputLength = 1, $morecss = '', $callurlonselect = 0, $placeholder = '', $acceptdelayedhtml = 0)
5662
    {
5663
        global $conf, $langs;
5664
        global $delayedhtmlcontent;
5665
5666
        // TODO Use an internal dolibarr component instead of select2
5667
        if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined('REQUIRE_JQUERY_MULTISELECT'))
5668
            return '';
5669
5670
        $out = '<select type="text" class="' . $htmlname . ($morecss ? ' ' . $morecss : '') . '" ' . ($moreparam ? $moreparam . ' ' : '') . 'name="' . $htmlname . '"></select>';
5671
5672
        $tmpplugin = 'select2';
5673
        $outdelayed = "\n" . '<!-- JS CODE TO ENABLE ' . $tmpplugin . ' for id ' . $htmlname . ' -->
5674
	    	<script type="text/javascript">
5675
	    	$(document).ready(function () {
5676
5677
    	        ' . ($callurlonselect ? 'var saveRemoteData = [];' : '') . '
5678
5679
                $(".' . $htmlname . '").select2({
5680
			    	ajax: {
5681
				    	dir: "ltr",
5682
				    	url: "' . $url . '",
5683
				    	dataType: \'json\',
5684
				    	delay: 250,
5685
				    	data: function (params) {
5686
				    		return {
5687
						    	q: params.term, 	// search term
5688
				    			page: params.page
5689
				    		};
5690
			    		},
5691
			    		processResults: function (data) {
5692
			    			// parse the results into the format expected by Select2.
5693
			    			// since we are using custom formatting functions we do not need to alter the remote JSON data
5694
			    			//console.log(data);
5695
							saveRemoteData = data;
5696
				    	    /* format json result for select2 */
5697
				    	    result = []
5698
				    	    $.each( data, function( key, value ) {
5699
				    	       result.push({id: key, text: value.text});
5700
                            });
5701
			    			//return {results:[{id:\'none\', text:\'aa\'}, {id:\'rrr\', text:\'Red\'},{id:\'bbb\', text:\'Search a into projects\'}], more:false}
5702
			    			//console.log(result);
5703
			    			return {results: result, more: false}
5704
			    		},
5705
			    		cache: true
5706
			    	},
5707
	 				language: select2arrayoflanguage,
5708
					containerCssClass: \':all:\',					/* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
5709
				    placeholder: "' . dol_escape_js($placeholder) . '",
5710
			    	escapeMarkup: function (markup) { return markup; }, 	// let our custom formatter work
5711
			    	minimumInputLength: ' . $minimumInputLength . ',
5712
			        formatResult: function(result, container, query, escapeMarkup) {
5713
                        return escapeMarkup(result.text);
5714
                    },
5715
			    });
5716
5717
                ' . ($callurlonselect ? '
5718
                /* Code to execute a GET when we select a value */
5719
                $(".' . $htmlname . '").change(function() {
5720
			    	var selected = $(".' . $htmlname . '").val();
5721
                	console.log("We select in selectArrayAjax the entry "+selected)
5722
			        $(".' . $htmlname . '").val("");  /* reset visible combo value */
5723
    			    $.each( saveRemoteData, function( key, value ) {
5724
    				        if (key == selected)
5725
    			            {
5726
    			                 console.log("selectArrayAjax - Do a redirect to "+value.url)
5727
    			                 location.assign(value.url);
5728
    			            }
5729
                    });
5730
    			});' : '' ) . '
5731
5732
    	   });
5733
	       </script>';
5734
5735
        if ($acceptdelayedhtml) {
5736
            $delayedhtmlcontent .= $outdelayed;
5737
        } else {
5738
            $out .= $outdelayed;
5739
        }
5740
        return $out;
5741
    }
5742
5743
    /**
5744
     * 	Return a HTML select string, built from an array of key+value, but content returned into select is defined into $array parameter.
5745
     *  Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice.
5746
     *
5747
     * 	@param	string	$htmlname       		Name of html select area
5748
     * 	@param	string	$array					Array (key=>array('text'=>'A text', 'url'=>'An url'), ...)
5749
     * 	@param	string	$id             		Preselected key
5750
     * 	@param  string	$moreparam      		Add more parameters onto the select tag
5751
     * 	@param	int		$disableFiltering		If set to 1, results are not filtered with searched string
5752
     * 	@param	int		$disabled				Html select box is disabled
5753
     *  @param	int		$minimumInputLength		Minimum Input Length
5754
     *  @param	string	$morecss				Add more class to css styles
5755
     *  @param  int     $callurlonselect        If set to 1, some code is added so an url return by the ajax is called when value is selected.
5756
     *  @param  string  $placeholder            String to use as placeholder
5757
     *  @param  integer $acceptdelayedhtml      1 = caller is requesting to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect)
5758
     * 	@return	string   						HTML select string
5759
     *  @see selectArrayAjax, ajax_combobox in ajax.lib.php
5760
     */
5761
    static function selectArrayFilter($htmlname, $array, $id = '', $moreparam = '', $disableFiltering = 0, $disabled = 0, $minimumInputLength = 1, $morecss = '', $callurlonselect = 0, $placeholder = '', $acceptdelayedhtml = 0)
5762
    {
5763
        global $conf, $langs;
5764
        global $delayedhtmlcontent;
5765
5766
        // TODO Use an internal dolibarr component instead of select2
5767
        if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined('REQUIRE_JQUERY_MULTISELECT'))
5768
            return '';
5769
5770
        $out = '<select type="text" class="' . $htmlname . ($morecss ? ' ' . $morecss : '') . '" ' . ($moreparam ? $moreparam . ' ' : '') . 'name="' . $htmlname . '"><option></option></select>';
5771
5772
        $formattedarrayresult = array();
5773
5774
        foreach ($array as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $array of type string is not traversable.
Loading history...
5775
            $o = new stdClass();
0 ignored issues
show
Bug introduced by
The type Alixar\Base\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
5776
            $o->id = $key;
5777
            $o->text = $value['text'];
5778
            $o->url = $value['url'];
5779
            $formattedarrayresult[] = $o;
5780
        }
5781
5782
        $tmpplugin = 'select2';
5783
        $outdelayed = "\n" . '<!-- JS CODE TO ENABLE ' . $tmpplugin . ' for id ' . $htmlname . ' -->
5784
			<script type="text/javascript">
5785
			$(document).ready(function () {
5786
				var data = ' . json_encode($formattedarrayresult) . ';
5787
5788
				' . ($callurlonselect ? 'var saveRemoteData = ' . json_encode($array) . ';' : '') . '
5789
5790
				$(".' . $htmlname . '").select2({
5791
					data: data,
5792
					language: select2arrayoflanguage,
5793
					containerCssClass: \':all:\',					/* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
5794
					placeholder: "' . dol_escape_js($placeholder) . '",
5795
					escapeMarkup: function (markup) { return markup; }, 	// let our custom formatter work
5796
					minimumInputLength: ' . $minimumInputLength . ',
5797
					formatResult: function(result, container, query, escapeMarkup) {
5798
						return escapeMarkup(result.text);
5799
					},
5800
					matcher: function (params, data) {
5801
5802
						if(! data.id) return null;';
5803
5804
        if ($callurlonselect) {
5805
            $outdelayed .= '
5806
5807
						var urlBase = data.url;
5808
						var separ = urlBase.indexOf("?") >= 0 ? "&" : "?";
5809
						/* console.log("params.term="+params.term); */
5810
						/* console.log("params.term encoded="+encodeURIComponent(params.term)); */
5811
						saveRemoteData[data.id].url = urlBase + separ + "sall=" + encodeURIComponent(params.term);';
5812
        }
5813
5814
        if (!$disableFiltering) {
5815
            $outdelayed .= '
5816
5817
						if(data.text.match(new RegExp(params.term))) {
5818
							return data;
5819
						}
5820
5821
						return null;';
5822
        } else {
5823
            $outdelayed .= '
5824
5825
						return data;';
5826
        }
5827
5828
        $outdelayed .= '
5829
					}
5830
				});
5831
5832
				' . ($callurlonselect ? '
5833
				/* Code to execute a GET when we select a value */
5834
				$(".' . $htmlname . '").change(function() {
5835
					var selected = $(".' . $htmlname . '").val();
5836
					console.log("We select "+selected)
5837
5838
					$(".' . $htmlname . '").val("");  /* reset visible combo value */
5839
					$.each( saveRemoteData, function( key, value ) {
5840
						if (key == selected)
5841
						{
5842
							console.log("selectArrayAjax - Do a redirect to "+value.url)
5843
							location.assign(value.url);
5844
						}
5845
					});
5846
				});' : '' ) . '
5847
5848
			});
5849
			</script>';
5850
5851
        if ($acceptdelayedhtml) {
5852
            $delayedhtmlcontent .= $outdelayed;
5853
        } else {
5854
            $out .= $outdelayed;
5855
        }
5856
        return $out;
5857
    }
5858
5859
    /**
5860
     * 	Show a multiselect form from an array.
5861
     *
5862
     * 	@param	string	$htmlname		Name of select
5863
     * 	@param	array	$array			Array with key+value
5864
     * 	@param	array	$selected		Array with key+value preselected
5865
     * 	@param	int		$key_in_label   1 pour afficher la key dans la valeur "[key] value"
5866
     * 	@param	int		$value_as_key   1 to use value as key
5867
     * 	@param  string	$morecss        Add more css style
5868
     * 	@param  int		$translate		Translate and encode value
5869
     *  @param	int		$width			Force width of select box. May be used only when using jquery couch. Example: 250, 95%
5870
     *  @param	string	$moreattrib		Add more options on select component. Example: 'disabled'
5871
     *  @param	string	$elemtype		Type of element we show ('category', ...)
5872
     *  @param	string	$placeholder	String to use as placeholder
5873
     *  @param	int		$addjscombo		Add js combo
5874
     * 	@return	string					HTML multiselect string
5875
     *  @see selectarray
5876
     */
5877
    static function multiselectarray($htmlname, $array, $selected = array(), $key_in_label = 0, $value_as_key = 0, $morecss = '', $translate = 0, $width = 0, $moreattrib = '', $elemtype = '', $placeholder = '', $addjscombo = 1)
5878
    {
5879
        global $conf, $langs;
5880
5881
        $out = '';
5882
5883
5884
        // Add code for jquery to use multiselect
5885
        if (!empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT')) {
5886
            $out .= "\n" . '<!-- JS CODE TO ENABLE ' . $tmpplugin . ' for id ' . $htmlname . ' -->
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tmpplugin seems to be never defined.
Loading history...
5887
						<script type="text/javascript">' . "\n";
5888
            if ($addjscombo == 1) {
5889
                $tmpplugin = empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) ? constant('REQUIRE_JQUERY_MULTISELECT') : $conf->global->MAIN_USE_JQUERY_MULTISELECT;
5890
                $out .= 'function formatResult(record) {' . "\n";
5891
                if ($elemtype == 'category') {
5892
                    $out .= '	//return \'<span><img src="' . DOL_URL_ROOT . '/theme/eldy/img/object_category.png' . '"> <a href="' . DOL_URL_ROOT . '/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
5893
									  	return \'<span><img src="' . DOL_URL_ROOT . '/theme/eldy/img/object_category.png' . '"> \'+record.text+\'</span>\';';
5894
                } else {
5895
                    $out .= 'return record.text;';
5896
                }
5897
                $out .= '};' . "\n";
5898
                $out .= 'function formatSelection(record) {' . "\n";
5899
                if ($elemtype == 'category') {
5900
                    $out .= '	//return \'<span><img src="' . DOL_URL_ROOT . '/theme/eldy/img/object_category.png' . '"> <a href="' . DOL_URL_ROOT . '/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
5901
									  	return \'<span><img src="' . DOL_URL_ROOT . '/theme/eldy/img/object_category.png' . '"> \'+record.text+\'</span>\';';
5902
                } else {
5903
                    $out .= 'return record.text;';
5904
                }
5905
                $out .= '};' . "\n";
5906
                $out .= '$(document).ready(function () {
5907
							$(\'#' . $htmlname . '\').' . $tmpplugin . '({
5908
								dir: \'ltr\',
5909
								// Specify format function for dropdown item
5910
								formatResult: formatResult,
5911
							 	templateResult: formatResult,		/* For 4.0 */
5912
								// Specify format function for selected item
5913
								formatSelection: formatSelection,
5914
							 	templateResult: formatSelection		/* For 4.0 */
5915
							});
5916
						});' . "\n";
5917
            } elseif ($addjscombo == 2) {
5918
                // Add other js lib
5919
                // ...
5920
                $out .= '$(document).ready(function () {
5921
							$(\'#' . $htmlname . '\').multiSelect({
5922
								containerHTML: \'<div class="multi-select-container">\',
5923
								menuHTML: \'<div class="multi-select-menu">\',
5924
								buttonHTML: \'<span class="multi-select-button ' . $morecss . '">\',
5925
								menuItemHTML: \'<label class="multi-select-menuitem">\',
5926
								activeClass: \'multi-select-container--open\',
5927
								noneText: \'' . $placeholder . '\'
5928
							});
5929
						})';
5930
            }
5931
            $out .= '</script>';
5932
        }
5933
5934
        // Try also magic suggest
5935
5936
        $out .= '<select id="' . $htmlname . '" class="multiselect' . ($morecss ? ' ' . $morecss : '') . '" multiple name="' . $htmlname . '[]"' . ($moreattrib ? ' ' . $moreattrib : '') . ($width ? ' style="width: ' . (preg_match('/%/', $width) ? $width : $width . 'px') . '"' : '') . '>' . "\n";
5937
        if (is_array($array) && !empty($array)) {
5938
            if ($value_as_key)
5939
                $array = array_combine($array, $array);
5940
5941
            if (!empty($array)) {
5942
                foreach ($array as $key => $value) {
5943
                    $out .= '<option value="' . $key . '"';
5944
                    if (is_array($selected) && !empty($selected) && in_array($key, $selected) && !empty($key)) {
5945
                        $out .= ' selected';
5946
                    }
5947
                    $out .= '>';
5948
5949
                    $newval = ($translate ? $langs->trans($value) : $value);
5950
                    $newval = ($key_in_label ? $key . ' - ' . $newval : $newval);
5951
                    $out .= dol_htmlentitiesbr($newval);
5952
                    $out .= '</option>' . "\n";
5953
                }
5954
            }
5955
        }
5956
        $out .= '</select>' . "\n";
5957
5958
        return $out;
5959
    }
5960
5961
    /**
5962
     * 	Show a multiselect dropbox from an array.
5963
     *
5964
     * 	@param	string	$htmlname		Name of HTML field
5965
     * 	@param	array	$array			Array with array of fields we could show. This array may be modified according to setup of user.
5966
     *  @param  string  $varpage        Id of context for page. Can be set by caller with $varpage=(empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage);
5967
     * 	@return	string					HTML multiselect string
5968
     *  @see selectarray
5969
     */
5970
    static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage)
5971
    {
5972
        global $conf, $langs, $user;
5973
5974
        if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
5975
            return '';
5976
5977
        $tmpvar = "MAIN_SELECTEDFIELDS_" . $varpage;
5978
        if (!empty($user->conf->$tmpvar)) {
5979
            $tmparray = explode(',', $user->conf->$tmpvar);
5980
            foreach ($array as $key => $val) {
5981
                //var_dump($key);
5982
                //var_dump($tmparray);
5983
                if (in_array($key, $tmparray))
5984
                    $array[$key]['checked'] = 1;
5985
                else
5986
                    $array[$key]['checked'] = 0;
5987
            }
5988
        }
5989
        //var_dump($array);
5990
5991
        $lis = '';
5992
        $listcheckedstring = '';
5993
5994
        foreach ($array as $key => $val) {
5995
            /* var_dump($val);
5996
              var_dump(array_key_exists('enabled', $val));
5997
              var_dump(!$val['enabled']); */
5998
            if (array_key_exists('enabled', $val) && isset($val['enabled']) && !$val['enabled']) {
5999
                unset($array[$key]);     // We don't want this field
6000
                continue;
6001
            }
6002
            if ($val['label']) {
6003
                $lis .= '<li><input type="checkbox" id="checkbox' . $key . '" value="' . $key . '"' . (empty($val['checked']) ? '' : ' checked="checked"') . '/><label for="checkbox' . $key . '">' . dol_escape_htmltag($langs->trans($val['label'])) . '</label></li>';
6004
                $listcheckedstring .= (empty($val['checked']) ? '' : $key . ',');
6005
            }
6006
        }
6007
6008
        $out = '<!-- Component multiSelectArrayWithCheckbox ' . $htmlname . ' -->
6009
6010
        <dl class="dropdown">
6011
            <dt>
6012
            <a href="#">
6013
              ' . img_picto('', 'list') . '
6014
            </a>
6015
            <input type="hidden" class="' . $htmlname . '" name="' . $htmlname . '" value="' . $listcheckedstring . '">
6016
            </dt>
6017
            <dd class="dropdowndd">
6018
                <div class="multiselectcheckbox' . $htmlname . '">
6019
                    <ul class="ul' . $htmlname . '">
6020
                    ' . $lis . '
6021
                    </ul>
6022
                </div>
6023
            </dd>
6024
        </dl>
6025
6026
        <script type="text/javascript">
6027
          jQuery(document).ready(function () {
6028
              $(\'.multiselectcheckbox' . $htmlname . ' input[type="checkbox"]\').on(\'click\', function () {
6029
                  console.log("A new field was added/removed")
6030
                  $("input:hidden[name=formfilteraction]").val(\'listafterchangingselectedfields\')
6031
                  var title = $(this).val() + ",";
6032
                  if ($(this).is(\':checked\')) {
6033
                      $(\'.' . $htmlname . '\').val(title + $(\'.' . $htmlname . '\').val());
6034
                  }
6035
                  else {
6036
                      $(\'.' . $htmlname . '\').val( $(\'.' . $htmlname . '\').val().replace(title, \'\') )
6037
                  }
6038
                  // Now, we submit page
6039
                  $(this).parents(\'form:first\').submit();
6040
              });
6041
           });
6042
        </script>
6043
6044
        ';
6045
        return $out;
6046
    }
6047
6048
    /**
6049
     * 	Render list of categories linked to object with id $id and type $type
6050
     *
6051
     * 	@param		int		$id				Id of object
6052
     * 	@param		string	$type			Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated.
6053
     *  @param		int		$rendermode		0=Default, use multiselect. 1=Emulate multiselect (recommended)
6054
     * 	@return		string					String with categories
6055
     */
6056
    function showCategories($id, $type, $rendermode = 0)
6057
    {
6058
        global $db;
6059
6060
        include_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
6061
6062
        $cat = new Categorie($db);
6063
        $categories = $cat->containing($id, $type);
6064
6065
        if ($rendermode == 1) {
6066
            $toprint = array();
6067
            foreach ($categories as $c) {
6068
                $ways = $c->print_all_ways();       // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text
6069
                foreach ($ways as $way) {
6070
                    $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"' . ($c->color ? ' style="background: #' . $c->color . ';"' : ' style="background: #aaa"') . '>' . img_object('', 'category') . ' ' . $way . '</li>';
6071
                }
6072
            }
6073
            return '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">' . implode(' ', $toprint) . '</ul></div>';
6074
        }
6075
6076
        if ($rendermode == 0) {
6077
            $cate_arbo = $this->select_all_categories($type, '', 'parent', 64, 0, 1);
6078
            foreach ($categories as $c) {
6079
                $arrayselected[] = $c->id;
6080
            }
6081
6082
            return $this->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%', 'disabled', 'category');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $arrayselected seems to be defined by a foreach iteration on line 6078. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
6083
        }
6084
6085
        return 'ErrorBadValueForParameterRenderMode'; // Should not happened
6086
    }
6087
6088
    /**
6089
     *  Show linked object block.
6090
     *
6091
     *  @param	CommonObject	$object		      Object we want to show links to
6092
     *  @param  string          $morehtmlright    More html to show on right of title
6093
     *  @param  array           $compatibleImportElementsList  Array of compatibles elements object for "import from" action
6094
     *  @return	int							      <0 if KO, >=0 if OK
6095
     */
6096
    function showLinkedObjectBlock($object, $morehtmlright = '', $compatibleImportElementsList = false)
6097
    {
6098
        global $conf, $langs, $hookmanager;
6099
        global $bc;
6100
6101
        $object->fetchObjectLinked();
6102
6103
        // Bypass the default method
6104
        $hookmanager->initHooks(array('commonobject'));
6105
        $parameters = array(
6106
            'morehtmlright' => $morehtmlright,
6107
            'compatibleImportElementsList' => & $compatibleImportElementsList,
6108
        );
6109
        $reshook = $hookmanager->executeHooks('showLinkedObjectBlock', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $action seems to be never defined.
Loading history...
6110
6111
        if (empty($reshook)) {
6112
            $nbofdifferenttypes = count($object->linkedObjects);
6113
6114
            print '<!-- showLinkedObjectBlock -->';
6115
            print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '', 0, 0, 'showlinkedobjectblock');
6116
6117
6118
            print '<div class="div-table-responsive-no-min">';
6119
            print '<table class="noborder allwidth" data-block="showLinkedObject" data-element="' . $object->element . '"  data-elementid="' . $object->id . '"   >';
6120
6121
            print '<tr class="liste_titre">';
6122
            print '<td>' . $langs->trans("Type") . '</td>';
6123
            print '<td>' . $langs->trans("Ref") . '</td>';
6124
            print '<td align="center"></td>';
6125
            print '<td align="center">' . $langs->trans("Date") . '</td>';
6126
            print '<td align="right">' . $langs->trans("AmountHTShort") . '</td>';
6127
            print '<td align="right">' . $langs->trans("Status") . '</td>';
6128
            print '<td></td>';
6129
            print '</tr>';
6130
6131
            $nboftypesoutput = 0;
6132
6133
            foreach ($object->linkedObjects as $objecttype => $objects) {
6134
                $tplpath = $element = $subelement = $objecttype;
6135
6136
                // to display inport button on tpl
6137
                $showImportButton = false;
6138
                if (!empty($compatibleImportElementsList) && in_array($element, $compatibleImportElementsList)) {
6139
                    $showImportButton = true;
6140
                }
6141
6142
                if ($objecttype != 'supplier_proposal' && preg_match('/^([^_]+)_([^_]+)/i', $objecttype, $regs)) {
6143
                    $element = $regs[1];
6144
                    $subelement = $regs[2];
6145
                    $tplpath = $element . '/' . $subelement;
6146
                }
6147
                $tplname = 'linkedobjectblock';
6148
6149
                // To work with non standard path
6150
                if ($objecttype == 'facture') {
6151
                    $tplpath = 'compta/' . $element;
6152
                    if (empty($conf->facture->enabled))
6153
                        continue; // Do not show if module disabled
6154
                }
6155
                else if ($objecttype == 'facturerec') {
6156
                    $tplpath = 'compta/facture';
6157
                    $tplname = 'linkedobjectblockForRec';
6158
                    if (empty($conf->facture->enabled))
6159
                        continue; // Do not show if module disabled
6160
                }
6161
                else if ($objecttype == 'propal') {
6162
                    $tplpath = 'comm/' . $element;
6163
                    if (empty($conf->propal->enabled))
6164
                        continue; // Do not show if module disabled
6165
                }
6166
                else if ($objecttype == 'supplier_proposal') {
6167
                    if (empty($conf->supplier_proposal->enabled))
6168
                        continue; // Do not show if module disabled
6169
                }
6170
                else if ($objecttype == 'shipping' || $objecttype == 'shipment') {
6171
                    $tplpath = 'expedition';
6172
                    if (empty($conf->expedition->enabled))
6173
                        continue; // Do not show if module disabled
6174
                }
6175
                else if ($objecttype == 'reception') {
6176
                    $tplpath = 'reception';
6177
                    if (empty($conf->reception->enabled))
6178
                        continue; // Do not show if module disabled
6179
                }
6180
                else if ($objecttype == 'delivery') {
6181
                    $tplpath = 'livraison';
6182
                    if (empty($conf->expedition->enabled))
6183
                        continue; // Do not show if module disabled
6184
                }
6185
                else if ($objecttype == 'invoice_supplier') {
6186
                    $tplpath = 'fourn/facture';
6187
                } else if ($objecttype == 'order_supplier') {
6188
                    $tplpath = 'fourn/commande';
6189
                } else if ($objecttype == 'expensereport') {
6190
                    $tplpath = 'expensereport';
6191
                } else if ($objecttype == 'subscription') {
6192
                    $tplpath = 'adherents';
6193
                }
6194
6195
                global $linkedObjectBlock;
6196
                $linkedObjectBlock = $objects;
6197
6198
6199
                // Output template part (modules that overwrite templates must declare this into descriptor)
6200
                $dirtpls = array_merge($conf->modules_parts['tpl'], array('/' . $tplpath . '/tpl'));
6201
                foreach ($dirtpls as $reldir) {
6202
                    if ($nboftypesoutput == ($nbofdifferenttypes - 1)) {    // No more type to show after
6203
                        global $noMoreLinkedObjectBlockAfter;
6204
                        $noMoreLinkedObjectBlockAfter = 1;
6205
                    }
6206
6207
                    $res = @include dol_buildpath($reldir . '/' . $tplname . '.tpl.php');
6208
                    if ($res) {
6209
                        $nboftypesoutput++;
6210
                        break;
6211
                    }
6212
                }
6213
            }
6214
6215
            if (!$nboftypesoutput) {
6216
                print '<tr><td class="impair opacitymedium" colspan="7">' . $langs->trans("None") . '</td></tr>';
6217
            }
6218
6219
            print '</table>';
6220
6221
            if (!empty($compatibleImportElementsList)) {
6222
                $res = @include dol_buildpath('core/tpl/ajax/objectlinked_lineimport.tpl.php');
6223
            }
6224
6225
6226
            print '</div>';
6227
6228
            return $nbofdifferenttypes;
6229
        }
6230
    }
6231
6232
    /**
6233
     *  Show block with links to link to other objects.
6234
     *
6235
     *  @param	CommonObject	$object				Object we want to show links to
6236
     *  @param	array			$restrictlinksto	Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction.
6237
     *  @param	array			$excludelinksto		Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion.
6238
     *  @return	string								<0 if KO, >0 if OK
6239
     */
6240
    function showLinkToObjectBlock($object, $restrictlinksto = array(), $excludelinksto = array())
6241
    {
6242
        global $conf, $langs, $hookmanager;
6243
        global $bc;
6244
6245
        $linktoelem = '';
6246
        $linktoelemlist = '';
6247
        $listofidcompanytoscan = '';
6248
6249
        if (!is_object($object->thirdparty))
6250
            $object->fetch_thirdparty();
6251
6252
        $possiblelinks = array();
6253
        if (is_object($object->thirdparty) && !empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
6254
            $listofidcompanytoscan = $object->thirdparty->id;
6255
            if (($object->thirdparty->parent > 0) && !empty($conf->global->THIRDPARTY_INCLUDE_PARENT_IN_LINKTO))
6256
                $listofidcompanytoscan .= ',' . $object->thirdparty->parent;
6257
            if (($object->fk_project > 0) && !empty($conf->global->THIRDPARTY_INCLUDE_PROJECT_THIRDPARY_IN_LINKTO)) {
6258
                include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
6259
                $tmpproject = new Project($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
6260
                $tmpproject->fetch($object->fk_project);
6261
                if ($tmpproject->socid > 0 && ($tmpproject->socid != $object->thirdparty->id))
6262
                    $listofidcompanytoscan .= ',' . $tmpproject->socid;
6263
                unset($tmpproject);
6264
            }
6265
6266
            $possiblelinks = array(
6267
                'propal' => array('enabled' => $conf->propal->enabled, 'perms' => 1, 'label' => 'LinkToProposal', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('propal') . ')'),
6268
                'order' => array('enabled' => $conf->commande->enabled, 'perms' => 1, 'label' => 'LinkToOrder', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('commande') . ')'),
6269
                'invoice' => array('enabled' => $conf->facture->enabled, 'perms' => 1, 'label' => 'LinkToInvoice', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total as total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('invoice') . ')'),
6270
                'invoice_template' => array('enabled' => $conf->facture->enabled, 'perms' => 1, 'label' => 'LinkToTemplateInvoice', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.titre as ref, t.total as total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "facture_rec as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('invoice') . ')'),
6271
                'contrat' => array('enabled' => $conf->contrat->enabled, 'perms' => 1, 'label' => 'LinkToContract', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('contract') . ')'),
6272
                'fichinter' => array('enabled' => $conf->ficheinter->enabled, 'perms' => 1, 'label' => 'LinkToIntervention', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('intervention') . ')'),
6273
                'supplier_proposal' => array('enabled' => $conf->supplier_proposal->enabled, 'perms' => 1, 'label' => 'LinkToSupplierProposal', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('supplier_proposal') . ')'),
6274
                'order_supplier' => array('enabled' => $conf->supplier_order->enabled, 'perms' => 1, 'label' => 'LinkToSupplierOrder', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('commande_fournisseur') . ')'),
6275
                'invoice_supplier' => array('enabled' => $conf->supplier_invoice->enabled, 'perms' => 1, 'label' => 'LinkToSupplierInvoice', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('facture_fourn') . ')')
6276
            );
6277
        }
6278
6279
        global $action;
6280
6281
        // Can complete the possiblelink array
6282
        $hookmanager->initHooks(array('commonobject'));
6283
        $parameters = array('listofidcompanytoscan' => $listofidcompanytoscan);
6284
        $reshook = $hookmanager->executeHooks('showLinkToObjectBlock', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
6285
        if (empty($reshook)) {
6286
            if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
6287
                $possiblelinks = array_merge($possiblelinks, $hookmanager->resArray);
6288
            }
6289
        } else if ($reshook > 0) {
6290
            if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
6291
                $possiblelinks = $hookmanager->resArray;
6292
            }
6293
        }
6294
6295
        foreach ($possiblelinks as $key => $possiblelink) {
6296
            $num = 0;
6297
6298
            if (empty($possiblelink['enabled']))
6299
                continue;
6300
6301
            if (!empty($possiblelink['perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || !in_array($key, $excludelinksto))) {
6302
                print '<div id="' . $key . 'list"' . (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ' style="display:none"' : '') . '>';
6303
                $sql = $possiblelink['sql'];
6304
6305
                $resqllist = $this->db->query($sql);
6306
                if ($resqllist) {
6307
                    $num = $this->db->num_rows($resqllist);
6308
                    $i = 0;
6309
6310
                    print '<br><form action="' . $_SERVER["PHP_SELF"] . '" method="POST" name="formlinked' . $key . '">';
6311
                    print '<input type="hidden" name="id" value="' . $object->id . '">';
6312
                    print '<input type="hidden" name="action" value="addlink">';
6313
                    print '<input type="hidden" name="addlink" value="' . $key . '">';
6314
                    print '<table class="noborder">';
6315
                    print '<tr class="liste_titre">';
6316
                    print '<td class="nowrap"></td>';
6317
                    print '<td align="center">' . $langs->trans("Ref") . '</td>';
6318
                    print '<td align="left">' . $langs->trans("RefCustomer") . '</td>';
6319
                    print '<td align="right">' . $langs->trans("AmountHTShort") . '</td>';
6320
                    print '<td align="left">' . $langs->trans("Company") . '</td>';
6321
                    print '</tr>';
6322
                    while ($i < $num) {
6323
                        $objp = $this->db->fetch_object($resqllist);
6324
6325
                        print '<tr class="oddeven">';
6326
                        print '<td aling="left">';
6327
                        print '<input type="radio" name="idtolinkto" value=' . $objp->rowid . '>';
6328
                        print '</td>';
6329
                        print '<td align="center">' . $objp->ref . '</td>';
6330
                        print '<td>' . $objp->ref_client . '</td>';
6331
                        print '<td align="right">' . price($objp->total_ht) . '</td>';
6332
                        print '<td>' . $objp->name . '</td>';
6333
                        print '</tr>';
6334
                        $i++;
6335
                    }
6336
                    print '</table>';
6337
                    print '<div class="center"><input type="submit" class="button valignmiddle" value="' . $langs->trans('ToLink') . '">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" class="button" name="cancel" value="' . $langs->trans('Cancel') . '"></div>';
6338
6339
                    print '</form>';
6340
                    $this->db->free($resqllist);
6341
                } else {
6342
                    dol_print_error($this->db);
6343
                }
6344
                print '</div>';
6345
                if ($num > 0) {
6346
6347
                }
6348
6349
                //$linktoelem.=($linktoelem?' &nbsp; ':'');
6350
                if ($num > 0)
6351
                    $linktoelemlist .= '<li><a href="#linkto' . $key . '" class="linkto dropdowncloseonclick" rel="' . $key . '">' . $langs->trans($possiblelink['label']) . ' (' . $num . ')</a></li>';
6352
                //else $linktoelem.=$langs->trans($possiblelink['label']);
6353
                else
6354
                    $linktoelemlist .= '<li><span class="linktodisabled">' . $langs->trans($possiblelink['label']) . ' (0)</span></li>';
6355
            }
6356
        }
6357
6358
        if ($linktoelemlist) {
6359
            $linktoelem = '
6360
    		<dl class="dropdown" id="linktoobjectname">
6361
    		<dt><a href="#linktoobjectname">' . $langs->trans("LinkTo") . '...</a></dt>
6362
    		<dd>
6363
    		<div class="multiselectlinkto">
6364
    		<ul class="ulselectedfields">' . $linktoelemlist . '
6365
    		</ul>
6366
    		</div>
6367
    		</dd>
6368
    		</dl>';
6369
        } else {
6370
            $linktoelem = '';
6371
        }
6372
6373
        print '<!-- Add js to show linkto box -->
6374
				<script type="text/javascript" language="javascript">
6375
				jQuery(document).ready(function() {
6376
					jQuery(".linkto").click(function() {
6377
						console.log("We choose to show/hide link for rel="+jQuery(this).attr(\'rel\'));
6378
					    jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle();
6379
						jQuery(this).toggle();
6380
					});
6381
				});
6382
				</script>
6383
		';
6384
6385
        return $linktoelem;
6386
    }
6387
6388
    /**
6389
     * 	Return an html string with a select combo box to choose yes or no
6390
     *
6391
     * 	@param	string		$htmlname		Name of html select field
6392
     * 	@param	string		$value			Pre-selected value
6393
     * 	@param	int			$option			0 return yes/no, 1 return 1/0
6394
     * 	@param	bool		$disabled		true or false
6395
     *  @param	int      	$useempty		1=Add empty line
6396
     * 	@return	string						See option
6397
     */
6398
    function selectyesno($htmlname, $value = '', $option = 0, $disabled = false, $useempty = 0)
6399
    {
6400
        global $langs;
6401
6402
        $yes = "yes";
6403
        $no = "no";
6404
        if ($option) {
6405
            $yes = "1";
6406
            $no = "0";
6407
        }
6408
6409
        $disabled = ($disabled ? ' disabled' : '');
6410
6411
        $resultyesno = '<select class="flat width75" id="' . $htmlname . '" name="' . $htmlname . '"' . $disabled . '>' . "\n";
6412
        if ($useempty)
6413
            $resultyesno .= '<option value="-1"' . (($value < 0) ? ' selected' : '') . '>&nbsp;</option>' . "\n";
6414
        if (("$value" == 'yes') || ($value == 1)) {
6415
            $resultyesno .= '<option value="' . $yes . '" selected>' . $langs->trans("Yes") . '</option>' . "\n";
6416
            $resultyesno .= '<option value="' . $no . '">' . $langs->trans("No") . '</option>' . "\n";
6417
        } else {
6418
            $selected = (($useempty && $value != '0' && $value != 'no') ? '' : ' selected');
6419
            $resultyesno .= '<option value="' . $yes . '">' . $langs->trans("Yes") . '</option>' . "\n";
6420
            $resultyesno .= '<option value="' . $no . '"' . $selected . '>' . $langs->trans("No") . '</option>' . "\n";
6421
        }
6422
        $resultyesno .= '</select>' . "\n";
6423
        return $resultyesno;
6424
    }
6425
6426
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
6427
    /**
6428
     *  Return list of export templates
6429
     *
6430
     *  @param	string	$selected          Id modele pre-selectionne
6431
     *  @param  string	$htmlname          Name of HTML select
6432
     *  @param  string	$type              Type of searched templates
6433
     *  @param  int		$useempty          Affiche valeur vide dans liste
6434
     *  @return	void
6435
     */
6436
    function select_export_model($selected = '', $htmlname = 'exportmodelid', $type = '', $useempty = 0)
6437
    {
6438
        // phpcs:enable
6439
        $sql = "SELECT rowid, label";
6440
        $sql .= " FROM " . MAIN_DB_PREFIX . "export_model";
6441
        $sql .= " WHERE type = '" . $type . "'";
6442
        $sql .= " ORDER BY rowid";
6443
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
6444
        if ($result) {
6445
            print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
6446
            if ($useempty) {
6447
                print '<option value="-1">&nbsp;</option>';
6448
            }
6449
6450
            $num = $this->db->num_rows($result);
6451
            $i = 0;
6452
            while ($i < $num) {
6453
                $obj = $this->db->fetch_object($result);
6454
                if ($selected == $obj->rowid) {
6455
                    print '<option value="' . $obj->rowid . '" selected>';
6456
                } else {
6457
                    print '<option value="' . $obj->rowid . '">';
6458
                }
6459
                print $obj->label;
6460
                print '</option>';
6461
                $i++;
6462
            }
6463
            print "</select>";
6464
        } else {
6465
            dol_print_error($this->db);
6466
        }
6467
    }
6468
6469
    /**
6470
     *    Return a HTML area with the reference of object and a navigation bar for a business object
6471
     *    Note: To complete search with a particular filter on select, you can set $object->next_prev_filter set to define SQL criterias.
6472
     *
6473
     *    @param	object	$object			Object to show.
6474
     *    @param	string	$paramid   		Name of parameter to use to name the id into the URL next/previous link.
6475
     *    @param	string	$morehtml  		More html content to output just before the nav bar.
6476
     *    @param	int		$shownav	  	Show Condition (navigation is shown if value is 1).
6477
     *    @param	string	$fieldid   		Name of field id into database to use for select next and previous (we make the select max and min on this field compared to $object->ref). Use 'none' to disable next/prev.
6478
     *    @param	string	$fieldref   	Name of field ref of object (object->ref) to show or 'none' to not show ref.
6479
     *    @param	string	$morehtmlref  	More html to show after ref.
6480
     *    @param	string	$moreparam  	More param to add in nav link url. Must start with '&...'.
6481
     * 	  @param	int		$nodbprefix		Do not include DB prefix to forge table name.
6482
     * 	  @param	string	$morehtmlleft	More html code to show before ref.
6483
     * 	  @param	string	$morehtmlstatus	More html code to show under navigation arrows (status place).
6484
     * 	  @param	string	$morehtmlright	More html code to show after ref.
6485
     * 	  @return	string    				Portion HTML with ref + navigation buttons
6486
     */
6487
    function showrefnav($object, $paramid, $morehtml = '', $shownav = 1, $fieldid = 'rowid', $fieldref = 'ref', $morehtmlref = '', $moreparam = '', $nodbprefix = 0, $morehtmlleft = '', $morehtmlstatus = '', $morehtmlright = '')
6488
    {
6489
        global $langs, $conf, $hookmanager;
6490
6491
        $ret = '';
6492
        if (empty($fieldid))
6493
            $fieldid = 'rowid';
6494
        if (empty($fieldref))
6495
            $fieldref = 'ref';
6496
6497
        // Add where from hooks
6498
        if (is_object($hookmanager)) {
6499
            $parameters = array();
6500
            $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object);    // Note that $action and $object may have been modified by hook
6501
            $object->next_prev_filter .= $hookmanager->resPrint;
6502
        }
6503
        $previous_ref = $next_ref = '';
6504
        if ($shownav) {
6505
            //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam";
6506
            $object->load_previous_next_ref((isset($object->next_prev_filter) ? $object->next_prev_filter : ''), $fieldid, $nodbprefix);
6507
6508
            $navurl = $_SERVER["PHP_SELF"];
6509
            // Special case for project/task page
6510
            if ($paramid == 'project_ref') {
6511
                $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document)\.php/', '/tasks.php', $navurl);
6512
                $paramid = 'ref';
6513
            }
6514
6515
            // accesskey is for Windows or Linux:  ALT + key for chrome, ALT + SHIFT + KEY for firefox
6516
            // accesskey is for Mac:               CTRL + key for all browsers
6517
            $stringforfirstkey = $langs->trans("KeyboardShortcut");
6518
            if ($conf->browser->name == 'chrome') {
6519
                $stringforfirstkey .= ' ALT +';
6520
            } elseif ($conf->browser->name == 'firefox') {
6521
                $stringforfirstkey .= ' ALT + SHIFT +';
6522
            } else {
6523
                $stringforfirstkey .= ' CTL +';
6524
            }
6525
6526
            $previous_ref = $object->ref_previous ? '<a accesskey="p" title="' . $stringforfirstkey . ' p" class="classfortooltip" href="' . $navurl . '?' . $paramid . '=' . urlencode($object->ref_previous) . $moreparam . '"><i class="fa fa-chevron-left"></i></a>' : '<span class="inactive"><i class="fa fa-chevron-left opacitymedium"></i></span>';
6527
            $next_ref = $object->ref_next ? '<a accesskey="n" title="' . $stringforfirstkey . ' n" class="classfortooltip" href="' . $navurl . '?' . $paramid . '=' . urlencode($object->ref_next) . $moreparam . '"><i class="fa fa-chevron-right"></i></a>' : '<span class="inactive"><i class="fa fa-chevron-right opacitymedium"></i></span>';
6528
        }
6529
6530
        //print "xx".$previous_ref."x".$next_ref;
6531
        $ret .= '<!-- Start banner content --><div style="vertical-align: middle">';
6532
6533
        // Right part of banner
6534
        if ($morehtmlright)
6535
            $ret .= '<div class="inline-block floatleft">' . $morehtmlright . '</div>';
6536
6537
        if ($previous_ref || $next_ref || $morehtml) {
6538
            $ret .= '<div class="pagination paginationref"><ul class="right">';
6539
        }
6540
        if ($morehtml) {
6541
            $ret .= '<li class="noborder litext">' . $morehtml . '</li>';
6542
        }
6543
        if ($shownav && ($previous_ref || $next_ref)) {
6544
            $ret .= '<li class="pagination">' . $previous_ref . '</li>';
6545
            $ret .= '<li class="pagination">' . $next_ref . '</li>';
6546
        }
6547
        if ($previous_ref || $next_ref || $morehtml) {
6548
            $ret .= '</ul></div>';
6549
        }
6550
6551
        $parameters = array();
6552
        $reshook = $hookmanager->executeHooks('moreHtmlStatus', $parameters, $object);    // Note that $action and $object may have been modified by hook
6553
        if (empty($reshook))
6554
            $morehtmlstatus .= $hookmanager->resPrint;
6555
        else
6556
            $morehtmlstatus = $hookmanager->resPrint;
6557
        if ($morehtmlstatus)
6558
            $ret .= '<div class="statusref">' . $morehtmlstatus . '</div>';
6559
6560
        $parameters = array();
6561
        $reshook = $hookmanager->executeHooks('moreHtmlRef', $parameters, $object); // Note that $action and $object may have been modified by hook
6562
        if (empty($reshook))
6563
            $morehtmlref .= $hookmanager->resPrint;
6564
        elseif ($reshook > 0)
6565
            $morehtmlref = $hookmanager->resPrint;
6566
6567
        // Left part of banner
6568
        if ($morehtmlleft) {
6569
            if ($conf->browser->layout == 'phone')
6570
                $ret .= '<div class="floatleft">' . $morehtmlleft . '</div>';    // class="center" to have photo in middle
6571
            else
6572
                $ret .= '<div class="inline-block floatleft">' . $morehtmlleft . '</div>';
6573
        }
6574
6575
        //if ($conf->browser->layout == 'phone') $ret.='<div class="clearboth"></div>';
6576
        $ret .= '<div class="inline-block floatleft valignmiddle refid' . (($shownav && ($previous_ref || $next_ref)) ? ' refidpadding' : '') . '">';
6577
6578
        // For thirdparty, contact, user, member, the ref is the id, so we show something else
6579
        if ($object->element == 'societe') {
6580
            $ret .= dol_htmlentities($object->name);
6581
        } else if ($object->element == 'member') {
6582
            $ret .= $object->ref . '<br>';
6583
            $fullname = $object->getFullName($langs);
6584
            if ($object->morphy == 'mor' && $object->societe) {
6585
                $ret .= dol_htmlentities($object->societe) . ((!empty($fullname) && $object->societe != $fullname) ? ' (' . dol_htmlentities($fullname) . ')' : '');
6586
            } else {
6587
                $ret .= dol_htmlentities($fullname) . ((!empty($object->societe) && $object->societe != $fullname) ? ' (' . dol_htmlentities($object->societe) . ')' : '');
6588
            }
6589
        } else if (in_array($object->element, array('contact', 'user', 'usergroup'))) {
6590
            $ret .= dol_htmlentities($object->getFullName($langs));
6591
        } else if (in_array($object->element, array('action', 'agenda'))) {
6592
            $ret .= $object->ref . '<br>' . $object->label;
6593
        } else if (in_array($object->element, array('adherent_type'))) {
6594
            $ret .= $object->label;
6595
        } else if ($object->element == 'ecm_directories') {
6596
            $ret .= '';
6597
        } else if ($fieldref != 'none')
6598
            $ret .= dol_htmlentities($object->$fieldref);
6599
6600
6601
        if ($morehtmlref) {
6602
            $ret .= ' ' . $morehtmlref;
6603
        }
6604
        $ret .= '</div>';
6605
6606
        $ret .= '</div><!-- End banner content -->';
6607
6608
        return $ret;
6609
    }
6610
6611
    /**
6612
     *    	Return HTML code to output a barcode
6613
     *
6614
     *     	@param	Object	$object		Object containing data to retrieve file name
6615
     * 		@param	int		$width			Width of photo
6616
     * 	  	@return string    				HTML code to output barcode
6617
     */
6618
    function showbarcode(&$object, $width = 100)
6619
    {
6620
        global $conf;
6621
6622
        //Check if barcode is filled in the card
6623
        if (empty($object->barcode))
6624
            return '';
6625
6626
        // Complete object if not complete
6627
        if (empty($object->barcode_type_code) || empty($object->barcode_type_coder)) {
6628
            $result = $object->fetch_barcode();
6629
            //Check if fetch_barcode() failed
6630
            if ($result < 1)
6631
                return '<!-- ErrorFetchBarcode -->';
6632
        }
6633
6634
        // Barcode image
6635
        $url = DOL_URL_ROOT . '/viewimage.php?modulepart=barcode&generator=' . urlencode($object->barcode_type_coder) . '&code=' . urlencode($object->barcode) . '&encoding=' . urlencode($object->barcode_type_code);
6636
        $out = '<!-- url barcode = ' . $url . ' -->';
6637
        $out .= '<img src="' . $url . '">';
6638
        return $out;
6639
    }
6640
6641
    /**
6642
     *    	Return HTML code to output a photo
6643
     *
6644
     *    	@param	string		$modulepart			Key to define module concerned ('societe', 'userphoto', 'memberphoto')
6645
     *     	@param  object		$object				Object containing data to retrieve file name
6646
     * 		@param	int			$width				Width of photo
6647
     * 		@param	int			$height				Height of photo (auto if 0)
6648
     * 		@param	int			$caneditfield		Add edit fields
6649
     * 		@param	string		$cssclass			CSS name to use on img for photo
6650
     * 		@param	string		$imagesize		    'mini', 'small' or '' (original)
6651
     *      @param  int         $addlinktofullsize  Add link to fullsize image
6652
     *      @param  int         $cache              1=Accept to use image in cache
6653
     *      @param	string		$forcecapture		Force parameter capture on HTML input file element to ask a smartphone to allow to open camera to take photo. Auto if empty.
6654
     * 	  	@return string    						HTML code to output photo
6655
     */
6656
    static function showphoto($modulepart, $object, $width = 100, $height = 0, $caneditfield = 0, $cssclass = 'photowithmargin', $imagesize = '', $addlinktofullsize = 1, $cache = 0, $forcecapture = '')
6657
    {
6658
        global $conf, $langs;
6659
6660
        $entity = (!empty($object->entity) ? $object->entity : $conf->entity);
6661
        $id = (!empty($object->id) ? $object->id : $object->rowid);
6662
6663
        $ret = '';
6664
        $dir = '';
6665
        $file = '';
6666
        $originalfile = '';
6667
        $altfile = '';
6668
        $email = '';
6669
        $capture = '';
6670
        if ($modulepart == 'societe') {
6671
            $dir = $conf->societe->multidir_output[$entity];
6672
            if (!empty($object->logo)) {
6673
                if ((string) $imagesize == 'mini')
6674
                    $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . getImageFileNameForSize($object->logo, '_mini');             // getImageFileNameForSize include the thumbs
6675
                else if ((string) $imagesize == 'small')
6676
                    $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . getImageFileNameForSize($object->logo, '_small');
6677
                else
6678
                    $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . $object->logo;
6679
                $originalfile = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . $object->logo;
6680
            }
6681
            $email = $object->email;
6682
        }
6683
        else if ($modulepart == 'contact') {
6684
            $dir = $conf->societe->multidir_output[$entity] . '/contact';
6685
            if (!empty($object->photo)) {
6686
                if ((string) $imagesize == 'mini')
6687
                    $file = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . getImageFileNameForSize($object->photo, '_mini');
6688
                else if ((string) $imagesize == 'small')
6689
                    $file = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . getImageFileNameForSize($object->photo, '_small');
6690
                else
6691
                    $file = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . $object->photo;
6692
                $originalfile = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . $object->photo;
6693
            }
6694
            $email = $object->email;
6695
            $capture = 'user';
6696
        }
6697
        else if ($modulepart == 'userphoto') {
6698
            $dir = $conf->user->dir_output;
6699
            if (!empty($object->photo)) {
6700
                if ((string) $imagesize == 'mini')
6701
                    $file = get_exdir(0, 0, 0, 0, $object, 'user') . $object->id . '/' . getImageFileNameForSize($object->photo, '_mini');
6702
                else if ((string) $imagesize == 'small')
6703
                    $file = get_exdir(0, 0, 0, 0, $object, 'user') . $object->id . '/' . getImageFileNameForSize($object->photo, '_small');
6704
                else
6705
                    $file = get_exdir(0, 0, 0, 0, $object, 'user') . '/' . $object->id . '/' . $object->photo;
6706
                $originalfile = get_exdir(0, 0, 0, 0, $object, 'user') . '/' . $object->id . '/' . $object->photo;
6707
            }
6708
            if (!empty($conf->global->MAIN_OLD_IMAGE_LINKS))
6709
                $altfile = $object->id . ".jpg"; // For backward compatibility
6710
            $email = $object->email;
6711
            $capture = 'user';
6712
        }
6713
        else if ($modulepart == 'memberphoto') {
6714
            $dir = $conf->adherent->dir_output;
6715
            if (!empty($object->photo)) {
6716
                if ((string) $imagesize == 'mini')
6717
                    $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($object->photo, '_mini');
6718
                else if ((string) $imagesize == 'small')
6719
                    $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($object->photo, '_small');
6720
                else
6721
                    $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $object->photo;
6722
                $originalfile = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $object->photo;
6723
            }
6724
            if (!empty($conf->global->MAIN_OLD_IMAGE_LINKS))
6725
                $altfile = $object->id . ".jpg"; // For backward compatibility
6726
            $email = $object->email;
6727
            $capture = 'user';
6728
        }
6729
        else {
6730
            // Generic case to show photos
6731
            $dir = $conf->$modulepart->dir_output;
6732
            if (!empty($object->photo)) {
6733
                if ((string) $imagesize == 'mini')
6734
                    $file = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . getImageFileNameForSize($object->photo, '_mini');
6735
                else if ((string) $imagesize == 'small')
6736
                    $file = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . getImageFileNameForSize($object->photo, '_small');
6737
                else
6738
                    $file = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . $object->photo;
6739
                $originalfile = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . $object->photo;
6740
            }
6741
            if (!empty($conf->global->MAIN_OLD_IMAGE_LINKS))
6742
                $altfile = $object->id . ".jpg"; // For backward compatibility
6743
            $email = $object->email;
6744
        }
6745
6746
        if ($forcecapture)
6747
            $capture = $forcecapture;
6748
6749
        if ($dir) {
6750
            if ($file && file_exists($dir . "/" . $file)) {
6751
                if ($addlinktofullsize) {
6752
                    $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity=' . $entity);
6753
                    if ($urladvanced)
6754
                        $ret .= '<a href="' . $urladvanced . '">';
6755
                    else
6756
                        $ret .= '<a href="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $modulepart . '&entity=' . $entity . '&file=' . urlencode($originalfile) . '&cache=' . $cache . '">';
6757
                }
6758
                $ret .= '<img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="Photo" id="photologo' . (preg_replace('/[^a-z]/i', '_', $file)) . '" ' . ($width ? ' width="' . $width . '"' : '') . ($height ? ' height="' . $height . '"' : '') . ' src="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $modulepart . '&entity=' . $entity . '&file=' . urlencode($file) . '&cache=' . $cache . '">';
6759
                if ($addlinktofullsize)
6760
                    $ret .= '</a>';
6761
            }
6762
            else if ($altfile && file_exists($dir . "/" . $altfile)) {
6763
                if ($addlinktofullsize) {
6764
                    $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity=' . $entity);
6765
                    if ($urladvanced)
6766
                        $ret .= '<a href="' . $urladvanced . '">';
6767
                    else
6768
                        $ret .= '<a href="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $modulepart . '&entity=' . $entity . '&file=' . urlencode($originalfile) . '&cache=' . $cache . '">';
6769
                }
6770
                $ret .= '<img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="Photo alt" id="photologo' . (preg_replace('/[^a-z]/i', '_', $file)) . '" class="' . $cssclass . '" ' . ($width ? ' width="' . $width . '"' : '') . ($height ? ' height="' . $height . '"' : '') . ' src="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $modulepart . '&entity=' . $entity . '&file=' . urlencode($altfile) . '&cache=' . $cache . '">';
6771
                if ($addlinktofullsize)
6772
                    $ret .= '</a>';
6773
            }
6774
            else {
6775
                $nophoto = '/public/theme/common/nophoto.png';
6776
                if (in_array($modulepart, array('userphoto', 'contact'))) { // For module that are "physical" users
6777
                    $nophoto = '/public/theme/common/user_anonymous.png';
6778
                    if ($object->gender == 'man') {
6779
                        $nophoto = '/public/theme/common/user_man.png';
6780
                    }
6781
                    if ($object->gender == 'woman') {
6782
                        $nophoto = '/public/theme/common/user_woman.png';
6783
                    }
6784
                }
6785
6786
                if (!empty($conf->gravatar->enabled) && $email) {
6787
                    /**
6788
                     * @see https://gravatar.com/site/implement/images/php/
6789
                     */
6790
                    global $dolibarr_main_url_root;
6791
                    $ret .= '<!-- Put link to gravatar -->';
6792
                    //$defaultimg=urlencode(dol_buildpath($nophoto,3));
6793
                    $defaultimg = 'mm';
6794
                    $ret .= '<img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="Gravatar avatar" title="' . $email . ' Gravatar avatar" ' . ($width ? ' width="' . $width . '"' : '') . ($height ? ' height="' . $height . '"' : '') . ' src="https://www.gravatar.com/avatar/' . dol_hash(strtolower(trim($email)), 3) . '?s=' . $width . '&d=' . $defaultimg . '">'; // gravatar need md5 hash
6795
                } else {
6796
                    //$ret .= '<img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" ' . ($width ? ' width="' . $width . '"' : '') . ($height ? ' height="' . $height . '"' : '') . ' src="' . DOL_URL_ROOT . $nophoto . '">';
6797
                    $ret .= '<img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" ' . ($width ? ' width="' . $width . '"' : '') . ($height ? ' height="' . $height . '"' : '') . ' src="' . DOL_BASE_URI . $nophoto . '">';
6798
                }
6799
            }
6800
6801
            if ($caneditfield) {
6802
                if ($object->photo) {
6803
                    $ret .= "<br>\n";
6804
                }
6805
                $ret .= '<table class="nobordernopadding centpercent">';
6806
                if ($object->photo) {
6807
                    $ret .= '<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> ' . $langs->trans("Delete") . '<br><br></td></tr>';
6808
                }
6809
                $ret .= '<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"' . ($capture ? ' capture="' . $capture . '"' : '') . '></td></tr>';
6810
                $ret .= '</table>';
6811
            }
6812
        } else
6813
            dol_print_error('', 'Call of showphoto with wrong parameters modulepart=' . $modulepart);
6814
6815
        return $ret;
6816
    }
6817
6818
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
6819
    /**
6820
     * 	Return select list of groups
6821
     *
6822
     *  @param	string	$selected       Id group preselected
6823
     *  @param  string	$htmlname       Field name in form
6824
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
6825
     *  @param  string	$exclude        Array list of groups id to exclude
6826
     * 	@param	int		$disabled		If select list must be disabled
6827
     *  @param  string	$include        Array list of groups id to include
6828
     * 	@param	int		$enableonly		Array list of groups id to be enabled. All other must be disabled
6829
     * 	@param	string	$force_entity	'0' or Ids of environment to force
6830
     * 	@param	bool	$multiple		add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
6831
     *  @return	string
6832
     *  @see select_dolusers
6833
     */
6834
    function select_dolgroups($selected = '', $htmlname = 'groupid', $show_empty = 0, $exclude = '', $disabled = 0, $include = '', $enableonly = '', $force_entity = '0', $multiple = false)
6835
    {
6836
        // phpcs:enable
6837
        global $conf, $user, $langs;
6838
6839
        // Permettre l'exclusion de groupes
6840
        if (is_array($exclude))
6841
            $excludeGroups = implode("','", $exclude);
6842
        // Permettre l'inclusion de groupes
6843
        if (is_array($include))
6844
            $includeGroups = implode("','", $include);
6845
6846
        if (!is_array($selected))
6847
            $selected = array($selected);
6848
6849
        $out = '';
6850
6851
        // On recherche les groupes
6852
        $sql = "SELECT ug.rowid, ug.nom as name";
6853
        if (!empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && !$user->entity) {
6854
            $sql .= ", e.label";
6855
        }
6856
        $sql .= " FROM " . MAIN_DB_PREFIX . "usergroup as ug ";
6857
        if (!empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && !$user->entity) {
6858
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=ug.entity";
6859
            if ($force_entity)
6860
                $sql .= " WHERE ug.entity IN (0," . $force_entity . ")";
6861
            else
6862
                $sql .= " WHERE ug.entity IS NOT NULL";
6863
        }
6864
        else {
6865
            $sql .= " WHERE ug.entity IN (0," . $conf->entity . ")";
6866
        }
6867
        if (is_array($exclude) && $excludeGroups)
6868
            $sql .= " AND ug.rowid NOT IN ('" . $excludeGroups . "')";
6869
        if (is_array($include) && $includeGroups)
6870
            $sql .= " AND ug.rowid IN ('" . $includeGroups . "')";
6871
        $sql .= " ORDER BY ug.nom ASC";
6872
6873
        dol_syslog(get_class($this) . "::select_dolgroups", LOG_DEBUG);
6874
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
6875
        if ($resql) {
6876
            // Enhance with select2
6877
            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
6878
            $out .= ajax_combobox($htmlname);
6879
6880
            $out .= '<select class="flat minwidth200" id="' . $htmlname . '" name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . ' ' . ($disabled ? ' disabled' : '') . '>';
6881
6882
            $num = $this->db->num_rows($resql);
6883
            $i = 0;
6884
            if ($num) {
6885
                if ($show_empty && !$multiple)
6886
                    $out .= '<option value="-1"' . (in_array(-1, $selected) ? ' selected' : '') . '>&nbsp;</option>' . "\n";
6887
6888
                while ($i < $num) {
6889
                    $obj = $this->db->fetch_object($resql);
6890
                    $disableline = 0;
6891
                    if (is_array($enableonly) && count($enableonly) && !in_array($obj->rowid, $enableonly))
6892
                        $disableline = 1;
6893
6894
                    $out .= '<option value="' . $obj->rowid . '"';
6895
                    if ($disableline)
6896
                        $out .= ' disabled';
6897
                    if ((is_object($selected[0]) && $selected[0]->id == $obj->rowid) || (!is_object($selected[0]) && in_array($obj->rowid, $selected) )) {
6898
                        $out .= ' selected';
6899
                    }
6900
                    $out .= '>';
6901
6902
                    $out .= $obj->name;
6903
                    if (!empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1) {
6904
                        $out .= " (" . $obj->label . ")";
6905
                    }
6906
6907
                    $out .= '</option>';
6908
                    $i++;
6909
                }
6910
            } else {
6911
                if ($show_empty)
6912
                    $out .= '<option value="-1"' . (in_array(-1, $selected) ? ' selected' : '') . '></option>' . "\n";
6913
                $out .= '<option value="" disabled>' . $langs->trans("NoUserGroupDefined") . '</option>';
6914
            }
6915
            $out .= '</select>';
6916
        }
6917
        else {
6918
            dol_print_error($this->db);
6919
        }
6920
6921
        return $out;
6922
    }
6923
6924
    /**
6925
     * 	Return HTML to show the search and clear seach button
6926
     *
6927
     *  @return	string
6928
     */
6929
    function showFilterButtons()
6930
    {
6931
        global $conf, $langs;
6932
6933
        $out = '<div class="nowrap">';
6934
        $out .= '<input type="image" class="liste_titre" name="button_search" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
6935
        $out .= '<input type="image" class="liste_titre" name="button_removefilter" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '">';
6936
        $out .= '</div>';
6937
6938
        return $out;
6939
    }
6940
6941
    /**
6942
     * 	Return HTML to show the search and clear seach button
6943
     *
6944
     *  @param  string  $cssclass                  CSS class
6945
     *  @param  int     $calljsfunction            0=default. 1=call function initCheckForSelect() after changing status of checkboxes
6946
     *  @return	string
6947
     */
6948
    function showCheckAddButtons($cssclass = 'checkforaction', $calljsfunction = 0)
6949
    {
6950
        global $conf, $langs;
6951
6952
        $out = '';
6953
        if (!empty($conf->use_javascript_ajax))
6954
            $out .= '<div class="inline-block checkallactions"><input type="checkbox" id="checkallactions" name="checkallactions" class="checkallactions"></div>';
6955
        $out .= '<script type="text/javascript">
6956
            $(document).ready(function() {
6957
            	$("#checkallactions").click(function() {
6958
                    if($(this).is(\':checked\')){
6959
                        console.log("We check all");
6960
                		$(".' . $cssclass . '").prop(\'checked\', true).trigger(\'change\');
6961
                    }
6962
                    else
6963
                    {
6964
                        console.log("We uncheck all");
6965
                		$(".' . $cssclass . '").prop(\'checked\', false).trigger(\'change\');
6966
                    }' . "\n";
6967
        if ($calljsfunction)
6968
            $out .= 'if (typeof initCheckForSelect == \'function\') { initCheckForSelect(0); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }';
6969
        $out .= '         });
6970
6971
        	$(".checkforselect").change(function() {
6972
				$(this).closest("tr").toggleClass("highlight", this.checked);
6973
			});
6974
6975
 	});
6976
    </script>';
6977
6978
        return $out;
6979
    }
6980
6981
    /**
6982
     * 	Return HTML to show the search and clear seach button
6983
     *
6984
     *  @param	int  	$addcheckuncheckall        Add the check all/uncheck all checkbox (use javascript) and code to manage this
6985
     *  @param  string  $cssclass                  CSS class
6986
     *  @param  int     $calljsfunction            0=default. 1=call function initCheckForSelect() after changing status of checkboxes
6987
     *  @return	string
6988
     */
6989
    function showFilterAndCheckAddButtons($addcheckuncheckall = 0, $cssclass = 'checkforaction', $calljsfunction = 0)
6990
    {
6991
        $out .= $this->showFilterButtons();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $out seems to be never defined.
Loading history...
6992
        if ($addcheckuncheckall) {
6993
            $out .= $this->showCheckAddButtons($cssclass, $calljsfunction);
6994
        }
6995
        return $out;
6996
    }
6997
6998
    /**
6999
     * Return HTML to show the select of expense categories
7000
     *
7001
     * @param	string	$selected              preselected category
7002
     * @param	string	$htmlname              name of HTML select list
7003
     * @param	integer	$useempty              1=Add empty line
7004
     * @param	array	$excludeid             id to exclude
7005
     * @param	string	$target                htmlname of target select to bind event
7006
     * @param	int		$default_selected      default category to select if fk_c_type_fees change = EX_KME
7007
     * @param	array	$params                param to give
7008
     * @return	string
7009
     */
7010
    function selectExpenseCategories($selected = '', $htmlname = 'fk_c_exp_tax_cat', $useempty = 0, $excludeid = array(), $target = '', $default_selected = 0, $params = array())
7011
    {
7012
        global $db, $conf, $langs, $user;
7013
7014
        $sql = 'SELECT rowid, label FROM ' . MAIN_DB_PREFIX . 'c_exp_tax_cat WHERE active = 1';
7015
        $sql .= ' AND entity IN (0,' . getEntity('exp_tax_cat') . ')';
7016
        if (!empty($excludeid))
7017
            $sql .= ' AND rowid NOT IN (' . implode(',', $excludeid) . ')';
7018
        $sql .= ' ORDER BY label';
7019
7020
        $resql = $db->query($sql);
7021
        if ($resql) {
7022
            $out = '<select id="select_' . $htmlname . '" name="' . $htmlname . '" class="' . $htmlname . ' flat minwidth75imp">';
7023
            if ($useempty)
7024
                $out .= '<option value="0">&nbsp;</option>';
7025
7026
            while ($obj = $db->fetch_object($resql)) {
7027
                $out .= '<option ' . ($selected == $obj->rowid ? 'selected="selected"' : '') . ' value="' . $obj->rowid . '">' . $langs->trans($obj->label) . '</option>';
7028
            }
7029
            $out .= '</select>';
7030
            if (!empty($htmlname) && $user->admin)
7031
                $out .= ' ' . info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
7032
7033
            if (!empty($target)) {
7034
                $sql = "SELECT c.id FROM " . MAIN_DB_PREFIX . "c_type_fees as c WHERE c.code = 'EX_KME' AND c.active = 1";
7035
                $resql = $db->query($sql);
7036
                if ($resql) {
7037
                    if ($db->num_rows($resql) > 0) {
7038
                        $obj = $db->fetch_object($resql);
7039
                        $out .= '<script type="text/javascript">
7040
							$(function() {
7041
								$("select[name=' . $target . ']").on("change", function() {
7042
									var current_val = $(this).val();
7043
									if (current_val == ' . $obj->id . ') {';
7044
                        if (!empty($default_selected) || !empty($selected))
7045
                            $out .= '$("select[name=' . $htmlname . ']").val("' . ($default_selected > 0 ? $default_selected : $selected) . '");';
7046
7047
                        $out .= '
7048
										$("select[name=' . $htmlname . ']").change();
7049
									}
7050
								});
7051
7052
								$("select[name=' . $htmlname . ']").change(function() {
7053
7054
									if ($("select[name=' . $target . ']").val() == ' . $obj->id . ') {
7055
										// get price of kilometer to fill the unit price
7056
										var data = ' . json_encode($params) . ';
7057
										data.fk_c_exp_tax_cat = $(this).val();
7058
7059
										$.ajax({
7060
											method: "POST",
7061
											dataType: "json",
7062
											data: data,
7063
											url: "' . (DOL_URL_ROOT . '/expensereport/ajax/ajaxik.php') . '",
7064
										}).done(function( data, textStatus, jqXHR ) {
7065
											console.log(data);
7066
											if (typeof data.up != "undefined") {
7067
												$("input[name=value_unit]").val(data.up);
7068
												$("select[name=' . $htmlname . ']").attr("title", data.title);
7069
											} else {
7070
												$("input[name=value_unit]").val("");
7071
												$("select[name=' . $htmlname . ']").attr("title", "");
7072
											}
7073
										});
7074
									}
7075
								});
7076
							});
7077
						</script>';
7078
                    }
7079
                }
7080
            }
7081
        }
7082
        else {
7083
            dol_print_error($db);
7084
        }
7085
7086
        return $out;
7087
    }
7088
7089
    /**
7090
     * Return HTML to show the select ranges of expense range
7091
     *
7092
     * @param	string	$selected    preselected category
7093
     * @param	string	$htmlname    name of HTML select list
7094
     * @param	integer	$useempty    1=Add empty line
7095
     * @return	string
7096
     */
7097
    function selectExpenseRanges($selected = '', $htmlname = 'fk_range', $useempty = 0)
7098
    {
7099
        global $db, $conf, $langs;
7100
7101
        $sql = 'SELECT rowid, range_ik FROM ' . MAIN_DB_PREFIX . 'c_exp_tax_range';
7102
        $sql .= ' WHERE entity = ' . $conf->entity . ' AND active = 1';
7103
7104
        $resql = $db->query($sql);
7105
        if ($resql) {
7106
            $out = '<select id="select_' . $htmlname . '" name="' . $htmlname . '" class="' . $htmlname . ' flat minwidth75imp">';
7107
            if ($useempty)
7108
                $out .= '<option value="0"></option>';
7109
7110
            while ($obj = $db->fetch_object($resql)) {
7111
                $out .= '<option ' . ($selected == $obj->rowid ? 'selected="selected"' : '') . ' value="' . $obj->rowid . '">' . price($obj->range_ik, 0, $langs, 1, 0) . '</option>';
7112
            }
7113
            $out .= '</select>';
7114
        } else {
7115
            dol_print_error($db);
7116
        }
7117
7118
        return $out;
7119
    }
7120
7121
    /**
7122
     * Return HTML to show a select of expense
7123
     *
7124
     * @param	string	$selected    preselected category
7125
     * @param	string	$htmlname    name of HTML select list
7126
     * @param	integer	$useempty    1=Add empty choice
7127
     * @param	integer	$allchoice   1=Add all choice
7128
     * @param	integer	$useid       0=use 'code' as key, 1=use 'id' as key
7129
     * @return	string
7130
     */
7131
    function selectExpense($selected = '', $htmlname = 'fk_c_type_fees', $useempty = 0, $allchoice = 1, $useid = 0)
7132
    {
7133
        global $db, $langs;
7134
7135
        $sql = 'SELECT id, code, label FROM ' . MAIN_DB_PREFIX . 'c_type_fees';
7136
        $sql .= ' WHERE active = 1';
7137
7138
        $resql = $db->query($sql);
7139
        if ($resql) {
7140
            $out = '<select id="select_' . $htmlname . '" name="' . $htmlname . '" class="' . $htmlname . ' flat minwidth75imp">';
7141
            if ($useempty)
7142
                $out .= '<option value="0"></option>';
7143
            if ($allchoice)
7144
                $out .= '<option value="-1">' . $langs->trans('AllExpenseReport') . '</option>';
7145
7146
            $field = 'code';
7147
            if ($useid)
7148
                $field = 'id';
7149
7150
            while ($obj = $db->fetch_object($resql)) {
7151
                $key = $langs->trans($obj->code);
7152
                $out .= '<option ' . ($selected == $obj->{$field} ? 'selected="selected"' : '') . ' value="' . $obj->{$field} . '">' . ($key != $obj->code ? $key : $obj->label) . '</option>';
7153
            }
7154
            $out .= '</select>';
7155
        } else {
7156
            dol_print_error($db);
7157
        }
7158
7159
        return $out;
7160
    }
7161
}
7162