Test Failed
Branch develop (8578a1)
by
unknown
25:54
created

Form::select_conditions_paiements()   D

Complexity

Conditions 9
Paths 48

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 16
nc 48
nop 6
dl 0
loc 29
rs 4.909
c 0
b 0
f 0
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
 *
20
 * This program is free software; you can redistribute it and/or modify
21
 * it under the terms of the GNU General Public License as published by
22
 * the Free Software Foundation; either version 3 of the License, or
23
 * (at your option) any later version.
24
 *
25
 * This program is distributed in the hope that it will be useful,
26
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
 * GNU General Public License for more details.
29
 *
30
 * You should have received a copy of the GNU General Public License
31
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32
 */
33
34
/**
35
 *	\file       htdocs/core/class/html.form.class.php
36
 *  \ingroup    core
37
 *	\brief      File of class with all html predefined components
38
 */
39
40
41
/**
42
 *	Class to manage generation of HTML components
43
 *	Only common components must be here.
44
 *
45
 *  TODO Merge all function load_cache_* and loadCache* (except load_cache_vatrates) into one generic function loadCacheTable
46
 */
47
class Form
48
{
49
    var $db;
50
    var $error;
51
    var $num;
52
53
    // Cache arrays
54
    var $cache_types_paiements=array();
55
    var $cache_conditions_paiements=array();
56
    var $cache_availability=array();
57
    var $cache_demand_reason=array();
58
    var $cache_types_fees=array();
59
    var $cache_vatrates=array();
60
61
62
    /**
63
     * Constructor
64
     *
65
     * @param		DoliDB		$db      Database handler
66
     */
67
    public function __construct($db)
68
    {
69
        $this->db = $db;
70
    }
71
72
    /**
73
     * Output key field for an editable field
74
     *
75
     * @param   string	$text			Text of label or key to translate
76
     * @param   string	$htmlname		Name of select field ('edit' prefix will be added)
77
     * @param   string	$preselected    Value to show/edit (not used in this function)
78
     * @param	object	$object			Object
79
     * @param	boolean	$perm			Permission to allow button to edit parameter. Set it to 0 to have a not edited field.
80
     * @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]'...)
81
     * @param	string	$moreparam		More param to add on a href URL.
82
     * @param   int     $fieldrequired  1 if we want to show field as mandatory using the "fieldrequired" CSS.
83
     * @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 ' '
84
     * @return	string					HTML edit field
85
     */
86
    function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata='string', $moreparam='', $fieldrequired=0, $notabletag=0)
87
    {
88
        global $conf,$langs;
89
90
        $ret='';
91
92
        // TODO change for compatibility
93
        if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;/',$typeofdata))
94
        {
95
            if (! empty($perm))
96
            {
97
                $tmp=explode(':',$typeofdata);
98
                $ret.= '<div class="editkey_'.$tmp[0].(! empty($tmp[1]) ? ' '.$tmp[1] : '').'" id="'.$htmlname.'">';
99
	            if ($fieldrequired) $ret.='<span class="fieldrequired">';
100
                $ret.= $langs->trans($text);
101
	            if ($fieldrequired) $ret.='</span>';
102
                $ret.= '</div>'."\n";
103
            }
104
            else
105
            {
106
	            if ($fieldrequired) $ret.='<span class="fieldrequired">';
107
                $ret.= $langs->trans($text);
108
	            if ($fieldrequired) $ret.='</span>';
109
            }
110
        }
111
        else
112
		{
113
            if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
114
	        if ($fieldrequired) $ret.='<span class="fieldrequired">';
115
            $ret.=$langs->trans($text);
116
	        if ($fieldrequired) $ret.='</span>';
117
	        if (! empty($notabletag)) $ret.=' ';
118
            if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</td>';
119
            if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<td align="right">';
120
            if ($htmlname && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<a href="'.$_SERVER["PHP_SELF"].'?action=edit'.$htmlname.'&amp;id='.$object->id.$moreparam.'">'.img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1)).'</a>';
121
	        if (! empty($notabletag) && $notabletag == 1) $ret.=' : ';
122
	        if (! empty($notabletag) && $notabletag == 3) $ret.=' ';
123
            if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</td>';
124
            if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</tr></table>';
125
        }
126
127
        return $ret;
128
    }
129
130
    /**
131
     * Output val field for an editable field
132
     *
133
     * @param	string	$text			Text of label (not used in this function)
134
     * @param	string	$htmlname		Name of select field
135
     * @param	string	$value			Value to show/edit
136
     * @param	object	$object			Object
137
     * @param	boolean	$perm			Permission to allow button to edit parameter
138
     * @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'...)
139
     * @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
140
     * @param	object	$extObject		External object
141
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
142
     * @param	string	$moreparam		More param to add on a href URL
143
     * @param   int     $notabletag     Do no output table tags
144
     * @return  string					HTML edit field
145
     */
146
    function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata='string', $editvalue='', $extObject=null, $custommsg=null, $moreparam='', $notabletag=0)
147
    {
148
        global $conf,$langs,$db;
149
150
        $ret='';
151
152
        // Check parameters
153
        if (empty($typeofdata)) return 'ErrorBadParameter';
154
155
        // When option to edit inline is activated
156
        if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;|datehourpicker/',$typeofdata)) // TODO add jquery timepicker
157
        {
158
            $ret.=$this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg);
159
        }
160
        else
161
        {
162
            if (GETPOST('action','aZ09') == 'edit'.$htmlname)
163
            {
164
                $ret.="\n";
165
                $ret.='<form method="post" action="'.$_SERVER["PHP_SELF"].($moreparam?'?'.$moreparam:'').'">';
166
                $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">';
167
                $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
168
                $ret.='<input type="hidden" name="id" value="'.$object->id.'">';
169
                if (empty($notabletag)) $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
170
                if (empty($notabletag)) $ret.='<tr><td>';
171
                if (preg_match('/^(string|email)/',$typeofdata))
172
                {
173
                    $tmp=explode(':',$typeofdata);
174
                    $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($editvalue?$editvalue:$value).'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>';
175
                }
176
                else if (preg_match('/^(numeric|amount)/',$typeofdata))
177
                {
178
                    $tmp=explode(':',$typeofdata);
179
                    $valuetoshow=price2num($editvalue?$editvalue:$value);
180
                    $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($valuetoshow!=''?price($valuetoshow):'').'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>';
181
                }
182
                else if (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata))
183
                {
184
                    $tmp=explode(':',$typeofdata);
185
                    $cols=$tmp[2];
186
                    $morealt='';
187
                    if (preg_match('/%/',$cols))
188
                    {
189
                        $morealt=' style="width: '.$cols.'"';
190
                        $cols='';
191
                    }
192
                    $ret.='<textarea id="'.$htmlname.'" name="'.$htmlname.'" wrap="soft" rows="'.($tmp[1]?$tmp[1]:'20').'"'.($cols?' cols="'.$cols.'"':'').$morealt.'">'.($editvalue?$editvalue:$value).'</textarea>';
193
                }
194
                else if ($typeofdata == 'day' || $typeofdata == 'datepicker')
195
                {
196
                    $ret.=$this->select_date($value,$htmlname,0,0,1,'form'.$htmlname,1,0,1);
197
                }
198
                else if ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker')
199
                {
200
                    $ret.=$this->select_date($value,$htmlname,1,1,1,'form'.$htmlname,1,0,1);
201
                }
202
                else if (preg_match('/^select;/',$typeofdata))
203
                {
204
                     $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata));
205
                     foreach($arraydata as $val)
206
                     {
207
                         $tmp=explode(':',$val);
208
                         $arraylist[$tmp[0]]=$tmp[1];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arraylist was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arraylist = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
209
                     }
210
                     $ret.=$this->selectarray($htmlname,$arraylist,$value);
0 ignored issues
show
Bug introduced by
The variable $arraylist does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
211
                }
212
                else if (preg_match('/^ckeditor/',$typeofdata))
213
                {
214
                    $tmp=explode(':',$typeofdata);
215
                    require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
216
                    $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'));
217
                    $ret.=$doleditor->Create(1);
218
                }
219
                if (empty($notabletag)) $ret.='</td>';
220
221
                if (empty($notabletag)) $ret.='<td align="left">';
222
                //else $ret.='<div class="clearboth"></div>';
223
               	$ret.='<input type="submit" class="button'.(empty($notabletag)?'':' ').'" name="modify" value="'.$langs->trans("Modify").'">';
224
               	if (preg_match('/ckeditor|textarea/',$typeofdata) && empty($notabletag)) $ret.='<br>'."\n";
225
               	$ret.='<input type="submit" class="button'.(empty($notabletag)?'':' ').'" name="cancel" value="'.$langs->trans("Cancel").'">';
226
               	if (empty($notabletag)) $ret.='</td>';
227
228
               	if (empty($notabletag)) $ret.='</tr></table>'."\n";
229
                $ret.='</form>'."\n";
230
            }
231
            else
232
			{
233
				if (preg_match('/^(email)/',$typeofdata))              $ret.=dol_print_email($value,0,0,0,0,1);
234
                elseif (preg_match('/^(amount|numeric)/',$typeofdata)) $ret.=($value != '' ? price($value,'',$langs,0,-1,-1,$conf->currency) : '');
235
                elseif (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata))  $ret.=dol_htmlentitiesbr($value);
236
                elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') $ret.=dol_print_date($value,'day');
237
                elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') $ret.=dol_print_date($value,'dayhour');
238
                else if (preg_match('/^select;/',$typeofdata))
239
                {
240
                    $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata));
241
                    foreach($arraydata as $val)
242
                    {
243
                        $tmp=explode(':',$val);
244
                        $arraylist[$tmp[0]]=$tmp[1];
245
                    }
246
                    $ret.=$arraylist[$value];
247
                }
248
                else if (preg_match('/^ckeditor/',$typeofdata))
249
                {
250
                    $tmpcontent=dol_htmlentitiesbr($value);
251
                    if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB))
252
                    {
253
                        $firstline=preg_replace('/<br>.*/','',$tmpcontent);
254
                        $firstline=preg_replace('/[\n\r].*/','',$firstline);
255
                        $tmpcontent=$firstline.((strlen($firstline) != strlen($tmpcontent))?'...':'');
256
                    }
257
                    $ret.=$tmpcontent;
258
                }
259
                else $ret.=$value;
260
            }
261
        }
262
        return $ret;
263
    }
264
265
    /**
266
     * Output edit in place form
267
     *
268
     * @param	object	$object			Object
269
     * @param	string	$value			Value to show/edit
270
     * @param	string	$htmlname		DIV ID (field name)
271
     * @param	int		$condition		Condition to edit
272
     * @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')
273
     * @param	string	$editvalue		When in edit mode, use this value as $value instead of value
274
     * @param	object	$extObject		External object
275
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
276
     * @return	string   		      	HTML edit in place
277
     */
278
    private function editInPlace($object, $value, $htmlname, $condition, $inputType='textarea', $editvalue=null, $extObject=null, $custommsg=null)
279
    {
280
        global $conf;
281
282
        $out='';
283
284
        // Check parameters
285
        if ($inputType == 'textarea') $value = dol_nl2br($value);
286
        else if (preg_match('/^numeric/',$inputType)) $value = price($value);
287
        else if ($inputType == 'day' || $inputType == 'datepicker') $value = dol_print_date($value, 'day');
288
289
        if ($condition)
290
        {
291
            $element		= false;
292
            $table_element	= false;
293
            $fk_element		= false;
294
            $loadmethod		= false;
295
            $savemethod		= false;
296
            $ext_element	= false;
297
            $button_only	= false;
298
            $inputOption    = '';
299
300
            if (is_object($object))
301
            {
302
                $element = $object->element;
303
                $table_element = $object->table_element;
304
                $fk_element = $object->id;
305
            }
306
307
            if (is_object($extObject))
308
            {
309
                $ext_element = $extObject->element;
310
            }
311
312
            if (preg_match('/^(string|email|numeric)/',$inputType))
313
            {
314
                $tmp=explode(':',$inputType);
315
                $inputType=$tmp[0];
316
                if (! empty($tmp[1])) $inputOption=$tmp[1];
317
                if (! empty($tmp[2])) $savemethod=$tmp[2];
318
				$out.= '<input id="width_'.$htmlname.'" value="'.$inputOption.'" type="hidden"/>'."\n";
319
            }
320
            else if ((preg_match('/^day$/',$inputType)) || (preg_match('/^datepicker/',$inputType)) || (preg_match('/^datehourpicker/',$inputType)))
321
            {
322
                $tmp=explode(':',$inputType);
323
                $inputType=$tmp[0];
324
                if (! empty($tmp[1])) $inputOption=$tmp[1];
325
                if (! empty($tmp[2])) $savemethod=$tmp[2];
326
327
                $out.= '<input id="timestamp" type="hidden"/>'."\n"; // Use for timestamp format
328
            }
329
            else if (preg_match('/^(select|autocomplete)/',$inputType))
330
            {
331
                $tmp=explode(':',$inputType);
332
                $inputType=$tmp[0]; $loadmethod=$tmp[1];
333
                if (! empty($tmp[2])) $savemethod=$tmp[2];
334
                if (! empty($tmp[3])) $button_only=true;
335
            }
336
            else if (preg_match('/^textarea/',$inputType))
337
            {
338
            	$tmp=explode(':',$inputType);
339
            	$inputType=$tmp[0];
340
            	$rows=(empty($tmp[1])?'8':$tmp[1]);
341
            	$cols=(empty($tmp[2])?'80':$tmp[2]);
342
            }
343
            else if (preg_match('/^ckeditor/',$inputType))
344
            {
345
                $tmp=explode(':',$inputType);
346
                $inputType=$tmp[0]; $toolbar=$tmp[1];
347
                if (! empty($tmp[2])) $width=$tmp[2];
348
                if (! empty($tmp[3])) $heigth=$tmp[3];
349
                if (! empty($tmp[4])) $savemethod=$tmp[4];
350
351
                if (! empty($conf->fckeditor->enabled))
352
                {
353
                    $out.= '<input id="ckeditor_toolbar" value="'.$toolbar.'" type="hidden"/>'."\n";
354
                }
355
                else
356
                {
357
                    $inputType = 'textarea';
358
                }
359
            }
360
361
            $out.= '<input id="element_'.$htmlname.'" value="'.$element.'" type="hidden"/>'."\n";
362
            $out.= '<input id="table_element_'.$htmlname.'" value="'.$table_element.'" type="hidden"/>'."\n";
363
            $out.= '<input id="fk_element_'.$htmlname.'" value="'.$fk_element.'" type="hidden"/>'."\n";
364
            $out.= '<input id="loadmethod_'.$htmlname.'" value="'.$loadmethod.'" type="hidden"/>'."\n";
365
            if (! empty($savemethod))	$out.= '<input id="savemethod_'.$htmlname.'" value="'.$savemethod.'" type="hidden"/>'."\n";
366
            if (! empty($ext_element))	$out.= '<input id="ext_element_'.$htmlname.'" value="'.$ext_element.'" type="hidden"/>'."\n";
367
            if (! empty($custommsg))
368
            {
369
            	if (is_array($custommsg))
370
            	{
371
            		if (!empty($custommsg['success']))
372
            			$out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg['success'].'" type="hidden"/>'."\n";
373
            		if (!empty($custommsg['error']))
374
            			$out.= '<input id="errormsg_'.$htmlname.'" value="'.$custommsg['error'].'" type="hidden"/>'."\n";
375
            	}
376
            	else
377
            		$out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg.'" type="hidden"/>'."\n";
378
            }
379
            if ($inputType == 'textarea') {
380
            	$out.= '<input id="textarea_'.$htmlname.'_rows" value="'.$rows.'" type="hidden"/>'."\n";
0 ignored issues
show
Bug introduced by
The variable $rows does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
381
            	$out.= '<input id="textarea_'.$htmlname.'_cols" value="'.$cols.'" type="hidden"/>'."\n";
0 ignored issues
show
Bug introduced by
The variable $cols does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
382
            }
383
            $out.= '<span id="viewval_'.$htmlname.'" class="viewval_'.$inputType.($button_only ? ' inactive' : ' active').'">'.$value.'</span>'."\n";
384
            $out.= '<span id="editval_'.$htmlname.'" class="editval_'.$inputType.($button_only ? ' inactive' : ' active').' hideobject">'.(! empty($editvalue) ? $editvalue : $value).'</span>'."\n";
385
        }
386
        else
387
        {
388
            $out = $value;
389
        }
390
391
        return $out;
392
    }
393
394
    /**
395
     *	Show a text and picto with tooltip on text or picto.
396
     *  Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip
397
     *
398
     *	@param	string		$text				Text to show
399
     *	@param	string		$htmltext			HTML content of tooltip. Must be HTML/UTF8 encoded.
400
     *	@param	int			$tooltipon			1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2
401
     *	@param	int			$direction			-1=image is before, 0=no image, 1=image is after
402
     *	@param	string		$img				Html code for image (use img_xxx() function to get it)
403
     *	@param	string		$extracss			Add a CSS style to td tags
404
     *	@param	int			$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
405
     *	@param	string		$incbefore			Include code before the text
406
     *	@param	int			$noencodehtmltext	Do not encode into html entity the htmltext
407
     *  @param  string      $tooltiptrigger     ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
408
     *	@return	string							Code html du tooltip (texte+picto)
409
     *	@see	Use function textwithpicto if you can.
410
     *  TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip
411
     */
412
    function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger='')
413
    {
414
        global $conf;
415
416
        if ($incbefore) $text = $incbefore.$text;
417
        if (! $htmltext) return $text;
418
419
        $tag='td';
420
        if ($notabs == 2) $tag='div';
421
        if ($notabs == 3) $tag='span';
422
        // Sanitize tooltip
423
        $htmltext=str_replace("\\","\\\\",$htmltext);
424
        $htmltext=str_replace("\r","",$htmltext);
425
        $htmltext=str_replace("\n","",$htmltext);
426
427
        $extrastyle='';
428
        if ($direction < 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-left: 3px !important;'; }
429
        if ($direction > 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-right: 3px !important;'; }
430
431
        $classfortooltip='classfortooltip';
432
433
        $s='';$textfordialog='';
434
435
        $htmltext=str_replace('"',"&quot;",$htmltext);
436
        if ($tooltiptrigger != '')
437
        {
438
            $classfortooltip='classfortooltiponclick';
439
            $textfordialog.='<div style="display: none;" id="idfortooltiponclick_'.$tooltiptrigger.'" class="classfortooltiponclicktext">'.$htmltext.'</div>';
440
        }
441
        if ($tooltipon == 2 || $tooltipon == 3)
442
        {
443
            $paramfortooltipimg=' class="'.$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'"';
444
            if ($tooltiptrigger == '') $paramfortooltipimg.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on img tag to store tooltip
445
            else $paramfortooltipimg.=' dolid="'.$tooltiptrigger.'"';
446
        }
447
        else $paramfortooltipimg =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag
448
        if ($tooltipon == 1 || $tooltipon == 3)
449
        {
450
            $paramfortooltiptd=' class="'.($tooltipon == 3 ? 'cursorpointer ' : '').$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'" ';
451
            if ($tooltiptrigger == '') $paramfortooltiptd.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td tag to store tooltip
452
            else $paramfortooltiptd.=' dolid="'.$tooltiptrigger.'"';
453
        }
454
        else $paramfortooltiptd =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag
455
        if (empty($notabs)) $s.='<table class="nobordernopadding" summary=""><tr style="height: auto;">';
456
        elseif ($notabs == 2) $s.='<div class="inline-block">';
457
        // Define value if value is before
458
        if ($direction < 0) {
459
            $s.='<'.$tag.$paramfortooltipimg;
460
            if ($tag == 'td') {
461
                $s .= ' valign="top" width="14"';
462
            }
463
            $s.= '>'.$textfordialog.$img.'</'.$tag.'>';
464
        }
465
        // Use another method to help avoid having a space in value in order to use this value with jquery
466
        // Define label
467
        if ((string) $text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.'</'.$tag.'>';
468
        // Define value if value is after
469
        if ($direction > 0) {
470
            $s.='<'.$tag.$paramfortooltipimg;
471
            if ($tag == 'td') $s .= ' valign="middle" width="14"';
472
            $s.= '>'.$textfordialog.$img.'</'.$tag.'>';
473
        }
474
        if (empty($notabs)) $s.='</tr></table>';
475
		elseif ($notabs == 2) $s.='</div>';
476
477
        return $s;
478
    }
479
480
    /**
481
     *	Show a text with a picto and a tooltip on picto
482
     *
483
     *	@param	string	$text				Text to show
484
     *	@param  string	$htmltext	     	Content of tooltip
485
     *	@param	int		$direction			1=Icon is after text, -1=Icon is before text, 0=no icon
486
     * 	@param	string	$type				Type of picto ('info', 'help', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath
487
     *  @param  string	$extracss           Add a CSS style to td, div or span tag
488
     *  @param  int		$noencodehtmltext   Do not encode into html entity the htmltext
489
     *  @param	int		$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
490
     *  @param  string  $tooltiptrigger     ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
491
     * 	@return	string						HTML code of text, picto, tooltip
492
     */
493
    function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger='')
494
    {
495
        global $conf, $langs;
496
497
        $alt = '';
498
        if ($tooltiptrigger) $alt=$langs->trans("ClickToShowHelp");
499
500
        //For backwards compatibility
501
        if ($type == '0') $type = 'info';
502
        elseif ($type == '1') $type = 'help';
503
504
        // If info or help with no javascript, show only text
505
        if (empty($conf->use_javascript_ajax))
506
        {
507
            if ($type == 'info' || $type == 'help')	return $text;
508
            else
509
            {
510
                $alt = $htmltext;
511
                $htmltext = '';
512
            }
513
        }
514
515
        // If info or help with smartphone, show only text (tooltip can't works)
516
        if (! empty($conf->dol_no_mouse_hover))
517
        {
518
            if ($type == 'info' || $type == 'help') return $text;
519
        }
520
521
        if ($type == 'info') $img = img_help(0, $alt);
522
        elseif ($type == 'help') $img = img_help(($tooltiptrigger != '' ? 2 : 1), $alt);
523
        elseif ($type == 'superadmin') $img = img_picto($alt, 'redstar');
524
        elseif ($type == 'admin') $img = img_picto($alt, 'star');
525
        elseif ($type == 'warning') $img = img_warning($alt);
526
		else $img = img_picto($alt, $type);
527
528
        return $this->textwithtooltip($text, $htmltext, ($tooltiptrigger?3:2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger);
529
    }
530
531
    /**
532
     * Generate select HTML to choose massaction
533
     *
534
     * @param	string	$selected		Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default.
535
     * @param	int		$arrayofaction	array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action.
536
     * @param   int     $alwaysvisible  1=select button always visible
537
     * @return	string					Select list
538
     */
539
    function selectMassAction($selected, $arrayofaction, $alwaysvisible=0)
540
    {
541
    	global $conf,$langs,$hookmanager;
542
543
    	if (count($arrayofaction) == 0) return;
544
545
    	$disabled=0;
546
    	$ret='<div class="centpercent center">';
547
    	$ret.='<select data-role="none" class="flat'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionselect" name="massaction"'.($disabled?' disabled="disabled"':'').'>';
548
549
        // 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.
550
    	$parameters=array();
551
    	$reshook=$hookmanager->executeHooks('addMoreMassActions',$parameters);    // Note that $action and $object may have been modified by hook
552
        if (empty($reshook))
553
        {
554
        	$ret.='<option value="0"'.($disabled?' disabled="disabled"':'').'>-- '.$langs->trans("SelectAction").' --</option>';
555
        	foreach($arrayofaction as $code => $label)
0 ignored issues
show
Bug introduced by
The expression $arrayofaction of type integer is not traversable.
Loading history...
556
        	{
557
        		$ret.='<option value="'.$code.'"'.($disabled?' disabled="disabled"':'').'>'.$label.'</option>';
558
        	}
559
        }
560
        $ret.=$hookmanager->resPrint;
561
562
    	$ret.='</select>';
563
    	// Warning: if you set submit button to disabled, post using 'Enter' will no more work.
564
    	$ret.='<input type="submit" data-role="none" name="confirmmassaction" class="button'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">';
565
    	$ret.='</div>';
566
567
    	if (! empty($conf->use_javascript_ajax))
568
    	{
569
        	$ret.='<!-- JS CODE TO ENABLE mass action select -->
570
    		<script type="text/javascript">
571
        		function initCheckForSelect()
572
        		{
573
        			atleastoneselected=0;
574
    	    		jQuery(".checkforselect").each(function( index ) {
575
    	  				/* console.log( index + ": " + $( this ).text() ); */
576
    	  				if ($(this).is(\':checked\')) atleastoneselected++;
577
    	  			});
578
    	  			if (atleastoneselected || '.$alwaysvisible.')
579
    	  			{
580
    	  				jQuery(".massaction").show();
581
        			    '.($selected ? 'if (atleastoneselected) jQuery(".massactionselect").val("'.$selected.'");' : '').'
582
        			    '.($selected ? 'if (! atleastoneselected) jQuery(".massactionselect").val("0");' : '').'
583
    	  			}
584
    	  			else
585
    	  			{
586
    	  				jQuery(".massaction").hide();
587
    	            }
588
        		}
589
590
        	jQuery(document).ready(function () {
591
        		initCheckForSelect();
592
        		jQuery(".checkforselect").click(function() {
593
        			initCheckForSelect();
594
    	  		});
595
    	  		jQuery(".massactionselect").change(function() {
596
        			var massaction = $( this ).val();
597
        			var urlform = $( this ).closest("form").attr("action").replace("#show_files","");
598
        			if (massaction == "builddoc")
599
                    {
600
                        urlform = urlform + "#show_files";
601
    	            }
602
        			$( this ).closest("form").attr("action", urlform);
603
                    console.log("we select a mass action "+massaction+" - "+urlform);
604
        	        /* Warning: if you set submit button to disabled, post using Enter will no more work
605
        			if ($(this).val() != \'0\')
606
    	  			{
607
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', false);
608
    	  			}
609
    	  			else
610
    	  			{
611
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', true);
612
    	  			}
613
        	        */
614
    	        });
615
        	});
616
    		</script>
617
        	';
618
    	}
619
620
    	return $ret;
621
    }
622
623
    /**
624
     *  Return combo list of activated countries, into language of user
625
     *
626
     *  @param	string	$selected       Id or Code or Label of preselected country
627
     *  @param  string	$htmlname       Name of html select object
628
     *  @param  string	$htmloption     Options html on select object
629
     *  @param	integer	$maxlength		Max length for labels (0=no limit)
630
     *  @param	string	$morecss		More css class
631
     *  @param	string	$usecodeaskey	'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key
632
     *  @return string           		HTML string with select
633
     */
634
    function select_country($selected='',$htmlname='country_id',$htmloption='',$maxlength=0,$morecss='minwidth300',$usecodeaskey='')
635
    {
636
        global $conf,$langs;
637
638
        $langs->load("dict");
639
640
        $out='';
641
        $countryArray=array();
642
		$favorite=array();
643
        $label=array();
644
		$atleastonefavorite=0;
645
646
        $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite";
647
        $sql.= " FROM ".MAIN_DB_PREFIX."c_country";
648
        $sql.= " WHERE active > 0";
649
        //$sql.= " ORDER BY code ASC";
650
651
        dol_syslog(get_class($this)."::select_country", LOG_DEBUG);
652
        $resql=$this->db->query($sql);
653
        if ($resql)
654
        {
655
            $out.= '<select id="select'.$htmlname.'" class="flat maxwidth200onsmartphone selectcountry'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" '.$htmloption.'>';
656
            $num = $this->db->num_rows($resql);
657
            $i = 0;
658
            if ($num)
659
            {
660
                $foundselected=false;
661
662
                while ($i < $num)
663
                {
664
                    $obj = $this->db->fetch_object($resql);
665
                    $countryArray[$i]['rowid'] 		= $obj->rowid;
666
                    $countryArray[$i]['code_iso'] 	= $obj->code_iso;
667
                    $countryArray[$i]['code_iso3'] 	= $obj->code_iso3;
668
                    $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:''));
669
                    $countryArray[$i]['favorite']   = $obj->favorite;
670
                    $favorite[$i]					= $obj->favorite;
671
					$label[$i] = dol_string_unaccent($countryArray[$i]['label']);
672
                    $i++;
673
                }
674
675
                array_multisort($favorite, SORT_DESC, $label, SORT_ASC, $countryArray);
676
677
                foreach ($countryArray as $row)
678
                {
679
                	if ($row['favorite'] && $row['code_iso']) $atleastonefavorite++;
680
					if (empty($row['favorite']) && $atleastonefavorite)
681
					{
682
						$atleastonefavorite=0;
683
						$out.= '<option value="" disabled class="selectoptiondisabledwhite">----------------------</option>';
684
					}
685
                    if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) )
686
                    {
687
                        $foundselected=true;
688
                        $out.= '<option value="'.($usecodeaskey?($usecodeaskey=='code2'?$row['code_iso']:$row['code_iso3']):$row['rowid']).'" selected>';
689
                    }
690
                    else
691
					{
692
                        $out.= '<option value="'.($usecodeaskey?($usecodeaskey=='code2'?$row['code_iso']:$row['code_iso3']):$row['rowid']).'">';
693
                    }
694
                    $out.= dol_trunc($row['label'],$maxlength,'middle');
695
                    if ($row['code_iso']) $out.= ' ('.$row['code_iso'] . ')';
696
                    $out.= '</option>';
697
                }
698
            }
699
            $out.= '</select>';
700
        }
701
        else
702
		{
703
            dol_print_error($this->db);
704
        }
705
706
        // Make select dynamic
707
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
708
        $out .= ajax_combobox('select'.$htmlname);
709
710
        return $out;
711
    }
712
713
	/**
714
     *  Return select list of incoterms
715
     *
716
     *  @param	string	$selected       		Id or Code of preselected incoterm
717
     *  @param	string	$location_incoterms     Value of input location
718
     *  @param	string	$page       			Defined the form action
719
     *  @param  string	$htmlname       		Name of html select object
720
     *  @param  string	$htmloption     		Options html on select object
721
     * 	@param	int		$forcecombo				Force to use standard combo box (no ajax use)
722
     *  @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')))
723
     *  @return string           				HTML string with select and input
724
     */
725
    function select_incoterms($selected='', $location_incoterms='', $page='', $htmlname='incoterm_id', $htmloption='', $forcecombo=1, $events=array())
726
    {
727
        global $conf,$langs;
728
729
        $langs->load("dict");
730
731
        $out='';
732
        $incotermArray=array();
733
734
        $sql = "SELECT rowid, code";
735
        $sql.= " FROM ".MAIN_DB_PREFIX."c_incoterms";
736
        $sql.= " WHERE active > 0";
737
        $sql.= " ORDER BY code ASC";
738
739
        dol_syslog(get_class($this)."::select_incoterm", LOG_DEBUG);
740
        $resql=$this->db->query($sql);
741
        if ($resql)
742
        {
743
        	if ($conf->use_javascript_ajax && ! $forcecombo)
744
			{
745
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
746
				$out .= ajax_combobox($htmlname, $events);
747
			}
748
749
			if (!empty($page))
750
			{
751
				$out .= '<form method="post" action="'.$page.'">';
752
	            $out .= '<input type="hidden" name="action" value="set_incoterms">';
753
	            $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
754
			}
755
756
            $out.= '<select id="'.$htmlname.'" class="flat selectincoterm noenlargeonsmartphone" name="'.$htmlname.'" '.$htmloption.'>';
757
			$out.= '<option value="0">&nbsp;</option>';
758
            $num = $this->db->num_rows($resql);
759
            $i = 0;
760
            if ($num)
761
            {
762
                $foundselected=false;
763
764
                while ($i < $num)
765
                {
766
                    $obj = $this->db->fetch_object($resql);
767
                    $incotermArray[$i]['rowid'] = $obj->rowid;
768
                    $incotermArray[$i]['code'] = $obj->code;
769
                    $i++;
770
                }
771
772
                foreach ($incotermArray as $row)
773
                {
774
                    if ($selected && ($selected == $row['rowid'] || $selected == $row['code']))
775
                    {
776
                        $out.= '<option value="'.$row['rowid'].'" selected>';
777
                    }
778
                    else
779
					{
780
                        $out.= '<option value="'.$row['rowid'].'">';
781
                    }
782
783
                    if ($row['code']) $out.= $row['code'];
784
785
					$out.= '</option>';
786
                }
787
            }
788
            $out.= '</select>';
789
790
			$out .= '<input id="location_incoterms" class="maxwidth100onsmartphone" name="location_incoterms" value="'.$location_incoterms.'">';
791
792
			if (!empty($page))
793
			{
794
	            $out .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'"></form>';
795
			}
796
        }
797
        else
798
		{
799
            dol_print_error($this->db);
800
        }
801
802
        return $out;
803
    }
804
805
    /**
806
     *	Return list of types of lines (product or service)
807
     * 	Example: 0=product, 1=service, 9=other (for external module)
808
     *
809
     *	@param  string	$selected       Preselected type
810
     *	@param  string	$htmlname       Name of field in html form
811
     * 	@param	int		$showempty		Add an empty field
812
     * 	@param	int		$hidetext		Do not show label 'Type' before combo box (used only if there is at least 2 choices to select)
813
     * 	@param	integer	$forceall		1=Force to show products and services in combo list, whatever are activated modules, 0=No force, -1=Force none (and set hidden field to 'service')
814
     *  @return	void
815
     */
816
    function select_type_of_lines($selected='',$htmlname='type',$showempty=0,$hidetext=0,$forceall=0)
817
    {
818
        global $db,$langs,$user,$conf;
819
820
        // If product & services are enabled or both disabled.
821
        if ($forceall > 0 || (empty($forceall) && ! empty($conf->product->enabled) && ! empty($conf->service->enabled))
822
        || (empty($forceall) && empty($conf->product->enabled) && empty($conf->service->enabled)) )
823
        {
824
            if (empty($hidetext)) print $langs->trans("Type").': ';
825
            print '<select class="flat" id="select_'.$htmlname.'" name="'.$htmlname.'">';
826
            if ($showempty)
827
            {
828
                print '<option value="-1"';
829
                if ($selected == -1) print ' selected';
830
                print '>&nbsp;</option>';
831
            }
832
833
            print '<option value="0"';
834
            if (0 == $selected) print ' selected';
835
            print '>'.$langs->trans("Product");
836
837
            print '<option value="1"';
838
            if (1 == $selected) print ' selected';
839
            print '>'.$langs->trans("Service");
840
841
            print '</select>';
842
            //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
843
        }
844
        if (empty($forceall) && empty($conf->product->enabled) && ! empty($conf->service->enabled))
845
        {
846
        	print $langs->trans("Service");
847
            print '<input type="hidden" name="'.$htmlname.'" value="1">';
848
        }
849
        if (empty($forceall) && ! empty($conf->product->enabled) && empty($conf->service->enabled))
850
        {
851
        	print $langs->trans("Product");
852
            print '<input type="hidden" name="'.$htmlname.'" value="0">';
853
        }
854
		if ($forceall < 0)	// This should happened only for contracts when both predefined product and service are disabled.
855
		{
856
            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
857
		}
858
    }
859
860
    /**
861
     *	Load into cache cache_types_fees, array of types of fees
862
     *
863
     *	@return     int             Nb of lines loaded, <0 if KO
864
     */
865
    function load_cache_types_fees()
866
    {
867
        global $langs;
868
869
        $num = count($this->cache_types_fees);
870
        if ($num > 0) return 0;    // Cache already loaded
871
872
        dol_syslog(__METHOD__, LOG_DEBUG);
873
874
        $langs->load("trips");
875
876
        $sql = "SELECT c.code, c.label";
877
        $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c";
878
        $sql.= " WHERE active > 0";
879
880
        $resql=$this->db->query($sql);
881
        if ($resql)
882
        {
883
            $num = $this->db->num_rows($resql);
884
            $i = 0;
885
886
            while ($i < $num)
887
            {
888
                $obj = $this->db->fetch_object($resql);
889
890
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
891
                $label=($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label));
892
                $this->cache_types_fees[$obj->code] = $label;
893
                $i++;
894
            }
895
896
			asort($this->cache_types_fees);
897
898
            return $num;
899
        }
900
        else
901
		{
902
            dol_print_error($this->db);
903
            return -1;
904
        }
905
    }
906
907
    /**
908
     *	Return list of types of notes
909
     *
910
     *	@param	string		$selected		Preselected type
911
     *	@param  string		$htmlname		Name of field in form
912
     * 	@param	int			$showempty		Add an empty field
913
     * 	@return	void
914
     */
915
    function select_type_fees($selected='',$htmlname='type',$showempty=0)
916
    {
917
        global $user, $langs;
918
919
        dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
920
921
        $this->load_cache_types_fees();
922
923
        print '<select class="flat" name="'.$htmlname.'">';
924
        if ($showempty)
925
        {
926
            print '<option value="-1"';
927
            if ($selected == -1) print ' selected';
928
            print '>&nbsp;</option>';
929
        }
930
931
        foreach($this->cache_types_fees as $key => $value)
932
        {
933
            print '<option value="'.$key.'"';
934
            if ($key == $selected) print ' selected';
935
            print '>';
936
            print $value;
937
            print '</option>';
938
        }
939
940
        print '</select>';
941
        if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
942
    }
943
944
945
    /**
946
     *  Return HTML code to select a company.
947
     *
948
     *  @param		int			$selected				Preselected products
949
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
950
     *  @param		int			$filter					Filter on thirdparty
951
     *  @param		int			$limit					Limit on number of returned lines
952
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
953
     * 	@param		int			$forcecombo				Force to use combo box
954
     *  @return		string								Return select box for thirdparty.
955
	 *  @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)
956
     */
957
    function select_thirdparty($selected='', $htmlname='socid', $filter='', $limit=20, $ajaxoptions=array(), $forcecombo=0)
958
    {
959
   		return $this->select_thirdparty_list($selected,$htmlname,$filter,1,0,$forcecombo,array(),'',0, $limit);
960
    }
961
962
    /**
963
     *  Output html form to select a third party
964
     *
965
     *	@param	string	$selected       		Preselected type
966
     *	@param  string	$htmlname       		Name of field in form
967
     *  @param  string	$filter         		optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)')
968
     *	@param	string	$showempty				Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
969
     * 	@param	int		$showtype				Show third party type in combolist (customer, prospect or supplier)
970
     * 	@param	int		$forcecombo				Force to use combo box
971
     *  @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')))
972
     *	@param	int		$limit					Maximum number of elements
973
     *  @param	string	$morecss				Add more css styles to the SELECT component
974
     *	@param  string	$moreparam      		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
975
	 *	@param	string	$selected_input_value	Value of preselected input text (for use with ajax)
976
     *  @param	int		$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
977
     *  @param	array	$ajaxoptions			Options for ajax_autocompleter
978
     * 	@return	string							HTML string with select box for thirdparty.
979
     */
980
    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())
981
    {
982
    	global $conf,$user,$langs;
983
984
    	$out='';
985
986
    	if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo)
987
    	{
988
    	    // No immediate load of all database
989
    		$placeholder='';
990
    		if ($selected && empty($selected_input_value))
991
    		{
992
    			require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
993
    			$societetmp = new Societe($this->db);
994
    			$societetmp->fetch($selected);
995
    			$selected_input_value=$societetmp->name;
996
    			unset($societetmp);
997
    		}
998
    		// mode 1
999
    		$urloption='htmlname='.$htmlname.'&outjson=1&filter='.$filter.($showtype?'&showtype='.$showtype:'');
1000
    		$out.=  ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
1001
			$out.='<style type="text/css">
1002
					.ui-autocomplete {
1003
						z-index: 250;
1004
					}
1005
				</style>';
1006
    		if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : ';
1007
    		else if ($hidelabel > 1) {
1008
    			if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"';
1009
    			else $placeholder=' title="'.$langs->trans("RefOrLabel").'"';
1010
    			if ($hidelabel == 2) {
1011
    				$out.=  img_picto($langs->trans("Search"), 'search');
1012
    			}
1013
    		}
1014
            $out.=  '<input type="text" class="'.$morecss.'" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />';
1015
    		if ($hidelabel == 3) {
1016
    			$out.=  img_picto($langs->trans("Search"), 'search');
1017
    		}
1018
    	}
1019
    	else
1020
    	{
1021
    	    // Immediate load of all database
1022
    		$out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam);
1023
    	}
1024
1025
    	return $out;
1026
    }
1027
1028
    /**
1029
     *  Output html form to select a third party.
1030
     *  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.
1031
     *
1032
     *	@param	string	$selected       Preselected type
1033
     *	@param  string	$htmlname       Name of field in form
1034
     *  @param  string	$filter         optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)')
1035
     *	@param	string	$showempty		Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
1036
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
1037
     * 	@param	int		$forcecombo		Force to use combo box
1038
     *  @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')))
1039
     *  @param	string	$filterkey		Filter on key value
1040
     *  @param	int		$outputmode		0=HTML select string, 1=Array
1041
     *  @param	int		$limit			Limit number of answers
1042
     *  @param	string	$morecss		Add more css styles to the SELECT component
1043
     *	@param  string	$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1044
     * 	@return	string					HTML string with
1045
     */
1046
    function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty='', $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='')
1047
    {
1048
        global $conf,$user,$langs;
1049
1050
        $out='';
1051
        $num=0;
1052
        $outarray=array();
1053
1054
        // On recherche les societes
1055
        $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
1056
        $sql.= " FROM ".MAIN_DB_PREFIX ."societe as s";
1057
        if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
1058
        $sql.= " WHERE s.entity IN (".getEntity('societe').")";
1059
        if (! empty($user->societe_id)) $sql.= " AND s.rowid = ".$user->societe_id;
1060
        if ($filter) $sql.= " AND (".$filter.")";
1061
        if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
1062
        if (! empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND s.status <> 0";
1063
        // Add criteria
1064
        if ($filterkey && $filterkey != '')
1065
        {
1066
			$sql.=" AND (";
1067
        	$prefix=empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)?'%':'';	// Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on
1068
        	// For natural search
1069
        	$scrit = explode(' ', $filterkey);
1070
        	$i=0;
1071
        	if (count($scrit) > 1) $sql.="(";
1072
        	foreach ($scrit as $crit) {
1073
        		if ($i > 0) $sql.=" AND ";
1074
        		$sql.="(s.nom LIKE '".$this->db->escape($prefix.$crit)."%')";
1075
        		$i++;
1076
        	}
1077
        	if (count($scrit) > 1) $sql.=")";
1078
            if (! empty($conf->barcode->enabled))
1079
        	{
1080
        		$sql .= " OR s.barcode LIKE '".$this->db->escape($filterkey)."%'";
1081
        	}
1082
        	$sql.=")";
1083
        }
1084
        $sql.=$this->db->order("nom","ASC");
1085
		$sql.=$this->db->plimit($limit, 0);
1086
1087
		// Build output string
1088
        dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG);
1089
        $resql=$this->db->query($sql);
1090
        if ($resql)
1091
        {
1092
           	if ($conf->use_javascript_ajax && ! $forcecombo)
1093
            {
1094
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1095
            	$comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT);
1096
            	$out.= $comboenhancement;
1097
            }
1098
1099
            // Construct $out and $outarray
1100
            $out.= '<select id="'.$htmlname.'" class="flat'.($morecss?' '.$morecss:'').'"'.($moreparam?' '.$moreparam:'').' name="'.$htmlname.'">'."\n";
1101
1102
            $textifempty='';
1103
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
1104
            //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
1105
            if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT))
1106
            {
1107
                if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty);
1108
                else $textifempty.=$langs->trans("All");
1109
            }
1110
            if ($showempty) $out.= '<option value="-1">'.$textifempty.'</option>'."\n";
1111
1112
			$num = $this->db->num_rows($resql);
1113
            $i = 0;
1114
            if ($num)
1115
            {
1116
                while ($i < $num)
1117
                {
1118
                    $obj = $this->db->fetch_object($resql);
1119
                    $label='';
1120
                    if ($conf->global->SOCIETE_ADD_REF_IN_LIST) {
1121
                    	if (($obj->client) && (!empty($obj->code_client))) {
1122
                    		$label = $obj->code_client. ' - ';
1123
                    	}
1124
                    	if (($obj->fournisseur) && (!empty($obj->code_fournisseur))) {
1125
                    		$label .= $obj->code_fournisseur. ' - ';
1126
                    	}
1127
                    	$label.=' '.$obj->name;
1128
                    }
1129
                    else
1130
                    {
1131
                    	$label=$obj->name;
1132
                    }
1133
1134
					if(!empty($obj->name_alias)) {
1135
						$label.=' ('.$obj->name_alias.')';
1136
					}
1137
1138
                    if ($showtype)
1139
                    {
1140
                        if ($obj->client || $obj->fournisseur) $label.=' (';
1141
                        if ($obj->client == 1 || $obj->client == 3) $label.=$langs->trans("Customer");
1142
                        if ($obj->client == 2 || $obj->client == 3) $label.=($obj->client==3?', ':'').$langs->trans("Prospect");
1143
                        if ($obj->fournisseur) $label.=($obj->client?', ':'').$langs->trans("Supplier");
1144
                        if ($obj->client || $obj->fournisseur) $label.=')';
1145
                    }
1146
                    if ($selected > 0 && $selected == $obj->rowid)
1147
                    {
1148
                        $out.= '<option value="'.$obj->rowid.'" selected>'.$label.'</option>';
1149
                    }
1150
                    else
1151
					{
1152
                        $out.= '<option value="'.$obj->rowid.'">'.$label.'</option>';
1153
                    }
1154
1155
                    array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label));
1156
1157
                    $i++;
1158
                    if (($i % 10) == 0) $out.="\n";
1159
                }
1160
            }
1161
            $out.= '</select>'."\n";
1162
        }
1163
        else
1164
        {
1165
            dol_print_error($this->db);
1166
        }
1167
1168
        $this->result=array('nbofthirdparties'=>$num);
1169
1170
        if ($outputmode) return $outarray;
1171
        return $out;
1172
    }
1173
1174
1175
    /**
1176
     *    	Return HTML combo list of absolute discounts
1177
     *
1178
     *    	@param	string	$selected       Id remise fixe pre-selectionnee
1179
     *    	@param  string	$htmlname       Nom champ formulaire
1180
     *    	@param  string	$filter         Criteres optionnels de filtre
1181
     * 		@param	int		$socid			Id of thirdparty
1182
     * 		@param	int		$maxvalue		Max value for lines that can be selected
1183
     * 		@return	int						Return number of qualifed lines in list
1184
     */
1185
    function select_remises($selected, $htmlname, $filter, $socid, $maxvalue=0)
1186
    {
1187
        global $langs,$conf;
1188
1189
        // On recherche les remises
1190
        $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
1191
        $sql.= " re.description, re.fk_facture_source";
1192
        $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re";
1193
        $sql.= " WHERE re.fk_soc = ".(int) $socid;
1194
        $sql.= " AND re.entity = " . $conf->entity;
1195
        if ($filter) $sql.= " AND ".$filter;
1196
        $sql.= " ORDER BY re.description ASC";
1197
1198
        dol_syslog(get_class($this)."::select_remises", LOG_DEBUG);
1199
        $resql=$this->db->query($sql);
1200
        if ($resql)
1201
        {
1202
            print '<select class="flat maxwidthonsmartphone" name="'.$htmlname.'">';
1203
            $num = $this->db->num_rows($resql);
1204
1205
            $qualifiedlines=$num;
1206
1207
            $i = 0;
1208
            if ($num)
1209
            {
1210
                print '<option value="0">&nbsp;</option>';
1211
                while ($i < $num)
1212
                {
1213
                    $obj = $this->db->fetch_object($resql);
1214
                    $desc=dol_trunc($obj->description,40);
1215
                    if (preg_match('/\(CREDIT_NOTE\)/', $desc)) $desc=preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc);
1216
                    if (preg_match('/\(DEPOSIT\)/', $desc)) $desc=preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc);
1217
                    if (preg_match('/\(EXCESS RECEIVED\)/', $desc)) $desc=preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc);
1218
1219
                    $selectstring='';
1220
                    if ($selected > 0 && $selected == $obj->rowid) $selectstring=' selected';
1221
1222
                    $disabled='';
1223
                    if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue)
1224
                    {
1225
                        $qualifiedlines--;
1226
                        $disabled=' disabled';
1227
                    }
1228
1229
                    print '<option value="'.$obj->rowid.'"'.$selectstring.$disabled.'>'.$desc.' ('.price($obj->amount_ht).' '.$langs->trans("HT").' - '.price($obj->amount_ttc).' '.$langs->trans("TTC").')</option>';
1230
                    $i++;
1231
                }
1232
            }
1233
            print '</select>';
1234
            return $qualifiedlines;
1235
        }
1236
        else
1237
        {
1238
            dol_print_error($this->db);
1239
            return -1;
1240
        }
1241
    }
1242
1243
    /**
1244
     *	Return list of all contacts (for a third party or all)
1245
     *
1246
     *	@param	int		$socid      	Id ot third party or 0 for all
1247
     *	@param  string	$selected   	Id contact pre-selectionne
1248
     *	@param  string	$htmlname  	    Name of HTML field ('none' for a not editable field)
1249
     *	@param  int		$showempty      0=no empty value, 1=add an empty value
1250
     *	@param  string	$exclude        List of contacts id to exclude
1251
     *	@param	string	$limitto		Disable answers that are not id in this array list
1252
     *	@param	integer	$showfunction   Add function into label
1253
     *	@param	string	$moreclass		Add more class to class style
1254
     *	@param	integer	$showsoc	    Add company into label
1255
     * 	@param	int		$forcecombo		Force to use combo box
1256
     *  @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')))
1257
     *  @param	bool	$options_only	Return options only (for ajax treatment)
1258
     *	@return	int						<0 if KO, Nb of contact in list if OK
1259
     */
1260
    function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false)
1261
    {
1262
    	print $this->selectcontacts($socid,$selected,$htmlname,$showempty,$exclude,$limitto,$showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events);
1263
    	return $this->num;
1264
    }
1265
1266
    /**
1267
     *	Return list of all contacts (for a third party or all)
1268
     *
1269
     *	@param	int		$socid      	Id ot third party or 0 for all
1270
     *	@param  string	$selected   	Id contact pre-selectionne
1271
     *	@param  string	$htmlname  	    Name of HTML field ('none' for a not editable field)
1272
     *	@param  int		$showempty     	0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit)
1273
     *	@param  string	$exclude        List of contacts id to exclude
1274
     *	@param	string	$limitto		Disable answers that are not id in this array list
1275
     *	@param	integer	$showfunction   Add function into label
1276
     *	@param	string	$moreclass		Add more class to class style
1277
     *	@param	bool	$options_only	Return options only (for ajax treatment)
1278
     *	@param	integer	$showsoc	    Add company into label
1279
     * 	@param	int		$forcecombo		Force to use combo box
1280
     *  @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')))
1281
     *	@return	 int					<0 if KO, Nb of contact in list if OK
1282
     */
1283
    function selectcontacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array())
1284
    {
1285
        global $conf,$langs;
1286
1287
        $langs->load('companies');
1288
1289
        $out='';
1290
1291
        // On recherche les societes
1292
        $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste";
1293
        if ($showsoc > 0) $sql.= " , s.nom as company";
1294
        $sql.= " FROM ".MAIN_DB_PREFIX ."socpeople as sp";
1295
        if ($showsoc > 0) $sql.= " LEFT OUTER JOIN  ".MAIN_DB_PREFIX ."societe as s ON s.rowid=sp.fk_soc";
1296
        $sql.= " WHERE sp.entity IN (".getEntity('societe').")";
1297
        if ($socid > 0) $sql.= " AND sp.fk_soc=".$socid;
1298
        if (! empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND sp.statut <> 0";
1299
        $sql.= " ORDER BY sp.lastname ASC";
1300
1301
        dol_syslog(get_class($this)."::select_contacts", LOG_DEBUG);
1302
        $resql=$this->db->query($sql);
1303
        if ($resql)
1304
        {
1305
            $num=$this->db->num_rows($resql);
1306
1307
            if ($conf->use_javascript_ajax && ! $forcecombo && ! $options_only)
1308
            {
1309
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1310
            	$comboenhancement = ajax_combobox($htmlname, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT);
1311
            	$out.= $comboenhancement;
1312
            }
1313
1314
            if ($htmlname != 'none' || $options_only) $out.= '<select class="flat'.($moreclass?' '.$moreclass:'').'" id="'.$htmlname.'" name="'.$htmlname.'">';
1315
            if ($showempty == 1) $out.= '<option value="0"'.($selected=='0'?' selected':'').'></option>';
1316
            if ($showempty == 2) $out.= '<option value="0"'.($selected=='0'?' selected':'').'>'.$langs->trans("Internal").'</option>';
1317
            $num = $this->db->num_rows($resql);
1318
            $i = 0;
1319
            if ($num)
1320
            {
1321
                include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
1322
                $contactstatic=new Contact($this->db);
1323
1324
                while ($i < $num)
1325
                {
1326
                    $obj = $this->db->fetch_object($resql);
1327
1328
                    $contactstatic->id=$obj->rowid;
1329
                    $contactstatic->lastname=$obj->lastname;
1330
                    $contactstatic->firstname=$obj->firstname;
1331
					if ($obj->statut == 1){
1332
                    if ($htmlname != 'none')
1333
                    {
1334
                        $disabled=0;
1335
                        if (is_array($exclude) && count($exclude) && in_array($obj->rowid,$exclude)) $disabled=1;
1336
                        if (is_array($limitto) && count($limitto) && ! in_array($obj->rowid,$limitto)) $disabled=1;
1337
                        if ($selected && $selected == $obj->rowid)
1338
                        {
1339
                            $out.= '<option value="'.$obj->rowid.'"';
1340
                            if ($disabled) $out.= ' disabled';
1341
                            $out.= ' selected>';
1342
                            $out.= $contactstatic->getFullName($langs);
1343
                            if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')';
1344
                            if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')';
1345
                            $out.= '</option>';
1346
                        }
1347
                        else
1348
                        {
1349
                            $out.= '<option value="'.$obj->rowid.'"';
1350
                            if ($disabled) $out.= ' disabled';
1351
                            $out.= '>';
1352
                            $out.= $contactstatic->getFullName($langs);
1353
                            if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')';
1354
                            if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')';
1355
                            $out.= '</option>';
1356
                        }
1357
                    }
1358
                    else
1359
					{
1360
                        if ($selected == $obj->rowid)
1361
                        {
1362
                            $out.= $contactstatic->getFullName($langs);
1363
                            if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')';
1364
                            if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')';
1365
                        }
1366
                    }
1367
				}
1368
                    $i++;
1369
                }
1370
            }
1371
            else
1372
			{
1373
            	$out.= '<option value="-1"'.($showempty==2?'':' selected').' disabled>'.$langs->trans($socid?"NoContactDefinedForThirdParty":"NoContactDefined").'</option>';
1374
            }
1375
            if ($htmlname != 'none' || $options_only)
1376
            {
1377
                $out.= '</select>';
1378
            }
1379
1380
            $this->num = $num;
1381
            return $out;
1382
        }
1383
        else
1384
        {
1385
            dol_print_error($this->db);
1386
            return -1;
1387
        }
1388
    }
1389
1390
    /**
1391
     *	Return select list of users
1392
     *
1393
     *  @param	string	$selected       Id user preselected
1394
     *  @param  string	$htmlname       Field name in form
1395
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
1396
     *  @param  array	$exclude        Array list of users id to exclude
1397
     * 	@param	int		$disabled		If select list must be disabled
1398
     *  @param  array	$include        Array list of users id to include
1399
     * 	@param	int		$enableonly		Array list of users id to be enabled. All other must be disabled
1400
     *  @param	int		$force_entity	0 or Id of environment to force
1401
     * 	@return	void
1402
     *  @deprecated		Use select_dolusers instead
1403
     *  @see select_dolusers()
1404
     */
1405
    function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude=null,$disabled=0,$include='',$enableonly='',$force_entity=0)
1406
    {
1407
        print $this->select_dolusers($selected,$htmlname,$show_empty,$exclude,$disabled,$include,$enableonly,$force_entity);
1408
    }
1409
1410
    /**
1411
     *	Return select list of users
1412
     *
1413
     *  @param	string	$selected       User id or user object of user preselected. If -1, we use id of current user.
1414
     *  @param  string	$htmlname       Field name in form
1415
     *  @param  int		$show_empty     0=list with no empty value, 1=add also an empty value into list
1416
     *  @param  array	$exclude        Array list of users id to exclude
1417
     * 	@param	int		$disabled		If select list must be disabled
1418
     *  @param  array|string	$include        Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me
1419
     * 	@param	array	$enableonly		Array list of users id to be enabled. If defined, it means that other must be disabled
1420
     *  @param	int		$force_entity	0 or Id of environment to force
1421
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1422
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1423
     *  @param	string	$morefilter		Add more filters into sql request
1424
     *  @param	integer	$show_every		0=default list, 1=add also a value "Everybody" at beginning of list
1425
     *  @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.
1426
     *  @param	string	$morecss		More css
1427
     *  @param  int     $noactive       Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on).
1428
     * 	@return	string					HTML select string
1429
     *  @see select_dolgroups
1430
     */
1431
    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)
1432
    {
1433
        global $conf,$user,$langs;
1434
1435
        // If no preselected user defined, we take current user
1436
        if ((is_numeric($selected) && ($selected < -2 || empty($selected))) && empty($conf->global->SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE)) $selected=$user->id;
1437
1438
        $excludeUsers=null;
1439
        $includeUsers=null;
1440
1441
        // Permettre l'exclusion d'utilisateurs
1442
        if (is_array($exclude))	$excludeUsers = implode(",",$exclude);
1443
        // Permettre l'inclusion d'utilisateurs
1444
        if (is_array($include))	$includeUsers = implode(",",$include);
1445
		else if ($include == 'hierarchy')
1446
		{
1447
			// Build list includeUsers to have only hierarchy
1448
			$includeUsers = implode(",",$user->getAllChildIds(0));
1449
		}
1450
		else if ($include == 'hierarchyme')
1451
		{
1452
		    // Build list includeUsers to have only hierarchy and current user
1453
		    $includeUsers = implode(",",$user->getAllChildIds(1));
1454
		}
1455
1456
        $out='';
1457
1458
        // On recherche les utilisateurs
1459
        $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity";
1460
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
1461
        {
1462
            $sql.= ", e.label";
1463
        }
1464
        $sql.= " FROM ".MAIN_DB_PREFIX ."user as u";
1465
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
1466
        {
1467
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX ."entity as e ON e.rowid=u.entity";
1468
            if ($force_entity) $sql.= " WHERE u.entity IN (0,".$force_entity.")";
1469
            else $sql.= " WHERE u.entity IS NOT NULL";
1470
        }
1471
        else
1472
       {
1473
        	if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
1474
        	{
1475
        		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug";
1476
        		$sql.= " ON ug.fk_user = u.rowid";
1477
        		$sql.= " WHERE ug.entity = ".$conf->entity;
1478
        	}
1479
        	else
1480
        	{
1481
        		$sql.= " WHERE u.entity IN (0,".$conf->entity.")";
1482
        	}
1483
        }
1484
        if (! empty($user->societe_id)) $sql.= " AND u.fk_soc = ".$user->societe_id;
1485
        if (is_array($exclude) && $excludeUsers) $sql.= " AND u.rowid NOT IN (".$excludeUsers.")";
1486
        if ($includeUsers) $sql.= " AND u.rowid IN (".$includeUsers.")";
1487
        if (! empty($conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive) $sql.= " AND u.statut <> 0";
1488
        if (! empty($morefilter)) $sql.=" ".$morefilter;
1489
1490
        if(empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)){
1491
            $sql.= " ORDER BY u.firstname ASC";
1492
        }else{
1493
            $sql.= " ORDER BY u.lastname ASC";
1494
        }
1495
1496
1497
        dol_syslog(get_class($this)."::select_dolusers", LOG_DEBUG);
1498
        $resql=$this->db->query($sql);
1499
        if ($resql)
1500
        {
1501
            $num = $this->db->num_rows($resql);
1502
            $i = 0;
1503
            if ($num)
1504
            {
1505
           		// Enhance with select2
1506
		        if ($conf->use_javascript_ajax)
1507
		        {
1508
		            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1509
		            $comboenhancement = ajax_combobox($htmlname);
1510
		            $out.=$comboenhancement;
1511
		        }
1512
1513
		        // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined
1514
                $out.= '<select class="flat'.($morecss?' minwidth100 '.$morecss:' minwidth200').'" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>';
1515
                if ($show_empty) $out.= '<option value="-1"'.((empty($selected) || $selected==-1)?' selected':'').'>&nbsp;</option>'."\n";
1516
				if ($show_every) $out.= '<option value="-2"'.(($selected==-2)?' selected':'').'>-- '.$langs->trans("Everybody").' --</option>'."\n";
1517
1518
                $userstatic=new User($this->db);
1519
1520
                while ($i < $num)
1521
                {
1522
                    $obj = $this->db->fetch_object($resql);
1523
1524
                    $userstatic->id=$obj->rowid;
1525
                    $userstatic->lastname=$obj->lastname;
1526
                    $userstatic->firstname=$obj->firstname;
1527
1528
                    $disableline='';
1529
                    if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=($enableonlytext?$enableonlytext:'1');
1530
1531
                    if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid))
1532
                    {
1533
                        $out.= '<option value="'.$obj->rowid.'"';
1534
                        if ($disableline) $out.= ' disabled';
1535
                        $out.= ' selected>';
1536
                    }
1537
                    else
1538
                    {
1539
                        $out.= '<option value="'.$obj->rowid.'"';
1540
                        if ($disableline) $out.= ' disabled';
1541
                        $out.= '>';
1542
                    }
1543
1544
                    $fullNameMode = 0; //Lastname + firstname
1545
                    if(empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)){
1546
                        $fullNameMode = 1; //firstname + lastname
1547
                    }
1548
                    $out.= $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength);
1549
1550
                    // Complete name with more info
1551
                    $moreinfo=0;
1552
                    if (! empty($conf->global->MAIN_SHOW_LOGIN))
1553
                    {
1554
                    	$out.= ($moreinfo?' - ':' (').$obj->login;
1555
                    	$moreinfo++;
1556
                    }
1557
                    if ($showstatus >= 0)
1558
                    {
1559
                    	if ($obj->statut == 1 && $showstatus == 1)
1560
                    	{
1561
                    		$out.=($moreinfo?' - ':' (').$langs->trans('Enabled');
1562
                    		$moreinfo++;
1563
                    	}
1564
						if ($obj->statut == 0)
1565
						{
1566
							$out.=($moreinfo?' - ':' (').$langs->trans('Disabled');
1567
							$moreinfo++;
1568
						}
1569
					}
1570
                    if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity)
1571
                    {
1572
                        if ($obj->admin && ! $obj->entity)
1573
                        {
1574
                        	$out.=($moreinfo?' - ':' (').$langs->trans("AllEntities");
1575
                        	$moreinfo++;
1576
                        }
1577
                        else
1578
                     {
1579
                        	$out.=($moreinfo?' - ':' (').($obj->label?$obj->label:$langs->trans("EntityNameNotDefined"));
1580
                        	$moreinfo++;
1581
                     	}
1582
                    }
1583
					$out.=($moreinfo?')':'');
1584
					if ($disableline && $disableline != '1')
1585
					{
1586
						$out.=' - '.$disableline;	// This is text from $enableonlytext parameter
1587
					}
1588
                    $out.= '</option>';
1589
1590
                    $i++;
1591
                }
1592
            }
1593
            else
1594
            {
1595
                $out.= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'" disabled>';
1596
                $out.= '<option value="">'.$langs->trans("None").'</option>';
1597
            }
1598
            $out.= '</select>';
1599
        }
1600
        else
1601
        {
1602
            dol_print_error($this->db);
1603
        }
1604
1605
        return $out;
1606
    }
1607
1608
1609
    /**
1610
     *	Return select list of users. Selected users are stored into session.
1611
     *  List of users are provided into $_SESSION['assignedtouser'].
1612
     *
1613
     *  @param  string	$action         Value for $action
1614
     *  @param  string	$htmlname       Field name in form
1615
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
1616
     *  @param  array	$exclude        Array list of users id to exclude
1617
     * 	@param	int		$disabled		If select list must be disabled
1618
     *  @param  array	$include        Array list of users id to include or 'hierarchy' to have only supervised users
1619
     * 	@param	array	$enableonly		Array list of users id to be enabled. All other must be disabled
1620
     *  @param	int		$force_entity	0 or Id of environment to force
1621
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1622
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1623
     *  @param	string	$morefilter		Add more filters into sql request
1624
     * 	@return	string					HTML select string
1625
     *  @see select_dolgroups
1626
     */
1627
    function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='')
1628
    {
1629
        global $conf,$user,$langs;
1630
1631
        $userstatic=new User($this->db);
1632
		$out='';
1633
1634
        // Method with no ajax
1635
        //$out.='<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
1636
        if ($action == 'view')
1637
        {
1638
			$out.='';
1639
        }
1640
		else
1641
		{
1642
			$out.='<input type="hidden" class="removedassignedhidden" name="removedassigned" value="">';
1643
			$out.='<script type="text/javascript" language="javascript">jQuery(document).ready(function () {    jQuery(".removedassigned").click(function() {        jQuery(".removedassignedhidden").val(jQuery(this).val());    });})</script>';
1644
			$out.=$this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter);
1645
			$out.=' <input type="submit" class="button valignmiddle" name="'.$action.'assignedtouser" value="'.dol_escape_htmltag($langs->trans("Add")).'">';
1646
		}
1647
		$assignedtouser=array();
1648
		if (!empty($_SESSION['assignedtouser']))
1649
		{
1650
			$assignedtouser=json_decode($_SESSION['assignedtouser'], true);
1651
		}
1652
		$nbassignetouser=count($assignedtouser);
1653
1654
		if ($nbassignetouser && $action != 'view') $out.='<br>';
1655
		if ($nbassignetouser) $out.='<div class="myavailability">';
1656
		$i=0; $ownerid=0;
1657
		foreach($assignedtouser as $key => $value)
1658
		{
1659
			if ($value['id'] == $ownerid) continue;
1660
			$userstatic->fetch($value['id']);
1661
			$out.=$userstatic->getNomUrl(-1);
1662
			if ($i == 0) { $ownerid = $value['id']; $out.=' ('.$langs->trans("Owner").')'; }
1663
			if ($nbassignetouser > 1 && $action != 'view') $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.'">';
1664
			//$out.=' '.($value['mandatory']?$langs->trans("Mandatory"):$langs->trans("Optional"));
1665
			//$out.=' '.($value['transparency']?$langs->trans("Busy"):$langs->trans("NotBusy"));
1666
			$out.='<br>';
1667
			$i++;
1668
		}
1669
		if ($nbassignetouser) $out.='</div>';
1670
1671
		//$out.='</form>';
1672
        return $out;
1673
    }
1674
1675
1676
    /**
1677
     *  Return list of products for customer in Ajax if Ajax activated or go to select_produits_list
1678
     *
1679
     *  @param		int			$selected				Preselected products
1680
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
1681
     *  @param		int			$filtertype				Filter on product type (''=nofilter, 0=product, 1=service)
1682
     *  @param		int			$limit					Limit on number of returned lines
1683
     *  @param		int			$price_level			Level of price to show
1684
     *  @param		int			$status					-1=Return all products, 0=Products not on sell, 1=Products on sell
1685
     *  @param		int			$finished				2=all, 1=finished, 0=raw material
1686
     *  @param		string		$selected_input_value	Value of preselected input text (for use with ajax)
1687
     *  @param		int			$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
1688
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
1689
     *  @param      int			$socid					Thirdparty Id (to get also price dedicated to this customer)
1690
     *  @param		string		$showempty				'' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
1691
     * 	@param		int			$forcecombo				Force to use combo box
1692
     *  @param      string      $morecss                Add more css on select
1693
     *  @param      int         $hidepriceinlabel       1=Hide prices in label
1694
     *  @param      string      $warehouseStatus        warehouse status filter, following comma separated filter options can be used
1695
     *										            'warehouseopen' = select products from open warehouses,
1696
	 *										            'warehouseclosed' = select products from closed warehouses,
1697
	 *										            'warehouseinternal' = select products from warehouses for internal correct/transfer only
1698
     *  @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...])
1699
     *  @return		void
1700
     */
1701
    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())
1702
    {
1703
        global $langs,$conf;
1704
1705
        $price_level = (! empty($price_level) ? $price_level : 0);
1706
1707
        if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
1708
        {
1709
        	$placeholder='';
1710
1711
            if ($selected && empty($selected_input_value))
1712
            {
1713
                require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1714
                $producttmpselect = new Product($this->db);
1715
                $producttmpselect->fetch($selected);
1716
                $selected_input_value=$producttmpselect->ref;
1717
                unset($producttmpselect);
1718
            }
1719
            // mode=1 means customers products
1720
            $urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished.'&hidepriceinlabel='.$hidepriceinlabel.'&warehousestatus='.$warehouseStatus;
1721
            //Price by customer
1722
            if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1723
            	$urloption.='&socid='.$socid;
1724
            }
1725
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
1726
1727
			if (!empty($conf->variants->enabled)) {
1728
				?>
1729
				<script>
1730
1731
					selected = <?php echo json_encode($selected_combinations) ?>;
1732
					combvalues = {};
1733
1734
					jQuery(document).ready(function () {
1735
1736
						jQuery("input[name='prod_entry_mode']").change(function () {
1737
							if (jQuery(this).val() == 'free') {
1738
								jQuery('div#attributes_box').empty();
1739
							}
1740
						});
1741
1742
						jQuery("input#<?php echo $htmlname ?>").change(function () {
1743
1744
							if (!jQuery(this).val()) {
1745
								jQuery('div#attributes_box').empty();
1746
								return;
1747
							}
1748
1749
							jQuery.getJSON("<?php echo dol_buildpath('/variants/ajax/getCombinations.php', 2) ?>", {
1750
								id: jQuery(this).val()
1751
							}, function (data) {
1752
								jQuery('div#attributes_box').empty();
1753
1754
								jQuery.each(data, function (key, val) {
1755
1756
									combvalues[val.id] = val.values;
1757
1758
									var span = jQuery(document.createElement('div')).css({
1759
										'display': 'table-row'
1760
									});
1761
1762
									span.append(
1763
										jQuery(document.createElement('div')).text(val.label).css({
1764
											'font-weight': 'bold',
1765
											'display': 'table-cell',
1766
											'text-align': 'right'
1767
										})
1768
									);
1769
1770
									var html = jQuery(document.createElement('select')).attr('name', 'combinations[' + val.id + ']').css({
1771
										'margin-left': '15px',
1772
										'white-space': 'pre'
1773
									}).append(
1774
										jQuery(document.createElement('option')).val('')
1775
									);
1776
1777
									jQuery.each(combvalues[val.id], function (key, val) {
1778
										var tag = jQuery(document.createElement('option')).val(val.id).html(val.value);
1779
1780
										if (selected[val.fk_product_attribute] == val.id) {
1781
											tag.attr('selected', 'selected');
1782
										}
1783
1784
										html.append(tag);
1785
									});
1786
1787
									span.append(html);
1788
									jQuery('div#attributes_box').append(span);
1789
								});
1790
							})
1791
						});
1792
1793
						<?php if ($selected): ?>
1794
						jQuery("input#<?php echo $htmlname ?>").change();
1795
						<?php endif ?>
1796
					});
1797
				</script>
1798
                <?php
1799
            }
1800
            if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : ';
1801
            else if ($hidelabel > 1) {
1802
            	if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"';
1803
            	else $placeholder=' title="'.$langs->trans("RefOrLabel").'"';
1804
            	if ($hidelabel == 2) {
1805
            		print img_picto($langs->trans("Search"), 'search');
1806
            	}
1807
            }
1808
            print '<input type="text" class="minwidth100" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />';
1809
            if ($hidelabel == 3) {
1810
            	print img_picto($langs->trans("Search"), 'search');
1811
            }
1812
        }
1813
        else
1814
		{
1815
            print $this->select_produits_list($selected,$htmlname,$filtertype,$limit,$price_level,'',$status,$finished,0,$socid,$showempty,$forcecombo,$morecss,$hidepriceinlabel, $warehouseStatus);
1816
        }
1817
    }
1818
1819
    /**
1820
     *	Return list of products for a customer
1821
     *
1822
     *	@param      int		$selected           Preselected product
1823
     *	@param      string	$htmlname           Name of select html
1824
     *  @param		string	$filtertype         Filter on product type (''=nofilter, 0=product, 1=service)
1825
     *	@param      int		$limit              Limit on number of returned lines
1826
     *	@param      int		$price_level        Level of price to show
1827
     * 	@param      string	$filterkey          Filter on product
1828
     *	@param		int		$status             -1=Return all products, 0=Products not on sell, 1=Products on sell
1829
     *  @param      int		$finished           Filter on finished field: 2=No filter
1830
     *  @param      int		$outputmode         0=HTML select string, 1=Array
1831
     *  @param      int		$socid     		    Thirdparty Id (to get also price dedicated to this customer)
1832
     *  @param		string	$showempty		    '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
1833
     * 	@param		int		$forcecombo		    Force to use combo box
1834
     *  @param      string  $morecss            Add more css on select
1835
     *  @param      int     $hidepriceinlabel   1=Hide prices in label
1836
     *  @param      string  $warehouseStatus    warehouse status filter, following comma separated filter options can be used
1837
     *										    'warehouseopen' = select products from open warehouses,
1838
	 *										    'warehouseclosed' = select products from closed warehouses,
1839
	 *										    'warehouseinternal' = select products from warehouses for internal correct/transfer only
1840
     *  @return     array    				    Array of keys for json
1841
     */
1842
    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='')
1843
    {
1844
        global $langs,$conf,$user,$db;
1845
1846
        $out='';
1847
        $outarray=array();
1848
1849
        $warehouseStatusArray = array();
1850
        if (! empty($warehouseStatus))
1851
        {
1852
            require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1853
            if (preg_match('/warehouseclosed/', $warehouseStatus))
1854
            {
1855
                $warehouseStatusArray[] = Entrepot::STATUS_CLOSED;
1856
            }
1857
            if (preg_match('/warehouseopen/', $warehouseStatus))
1858
            {
1859
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_ALL;
1860
            }
1861
            if (preg_match('/warehouseinternal/', $warehouseStatus))
1862
            {
1863
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_INTERNAL;
1864
            }
1865
        }
1866
1867
        $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";
1868
        (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock";
1869
1870
        $sql = "SELECT ";
1871
        $sql.= $selectFields . $selectFieldsGrouped;
1872
        //Price by customer
1873
        if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1874
        	$sql.=' ,pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
1875
        	$sql.=' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
1876
            $selectFields.= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx";
1877
        }
1878
1879
        // Multilang : we add translation
1880
        if (! empty($conf->global->MAIN_MULTILANGS))
1881
        {
1882
            $sql.= ", pl.label as label_translated";
1883
            $selectFields.= ", label_translated";
1884
        }
1885
		// Price by quantity
1886
		if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
1887
		{
1888
			$sql.= ", (SELECT pp.rowid FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
1889
			if ($price_level >= 1 && !empty($conf->global->PRODUIT_MULTIPRICES)) $sql.= " AND price_level=".$price_level;
1890
			$sql.= " ORDER BY date_price";
1891
			$sql.= " DESC LIMIT 1) as price_rowid";
1892
			$sql.= ", (SELECT pp.price_by_qty FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
1893
			if ($price_level >= 1 && !empty($conf->global->PRODUIT_MULTIPRICES)) $sql.= " AND price_level=".$price_level;
1894
			$sql.= " ORDER BY date_price";
1895
			$sql.= " DESC LIMIT 1) as price_by_qty";
1896
            $selectFields.= ", price_rowid, price_by_qty";
1897
		}
1898
        $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
1899
        if (count($warehouseStatusArray))
1900
        {
1901
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_product = p.rowid";
1902
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e on ps.fk_entrepot = e.rowid";
1903
        }
1904
1905
        //Price by customer
1906
        if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1907
        	$sql.=" LEFT JOIN  ".MAIN_DB_PREFIX."product_customer_price as pcp ON pcp.fk_soc=".$socid." AND pcp.fk_product=p.rowid";
1908
        }
1909
        // Multilang : we add translation
1910
        if (! empty($conf->global->MAIN_MULTILANGS))
1911
        {
1912
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='". $langs->getDefaultLang() ."'";
1913
        }
1914
1915
        if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
1916
            $sql .= " LEFT JOIN llx_product_attribute_combination pac ON pac.fk_product_child = p.rowid";
1917
        }
1918
1919
        $sql.= ' WHERE p.entity IN ('.getEntity('product').')';
1920
        if (count($warehouseStatusArray))
1921
        {
1922
            $sql.= ' AND (p.fk_product_type = 1 OR e.statut IN ('.$this->db->escape(implode(',',$warehouseStatusArray)).'))';
1923
        }
1924
1925
        if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
1926
            $sql .= " AND pac.rowid IS NULL";
1927
        }
1928
1929
        if ($finished == 0)
1930
        {
1931
            $sql.= " AND p.finished = ".$finished;
1932
        }
1933
        elseif ($finished == 1)
1934
        {
1935
            $sql.= " AND p.finished = ".$finished;
1936
            if ($status >= 0)  $sql.= " AND p.tosell = ".$status;
1937
        }
1938
        elseif ($status >= 0)
1939
        {
1940
            $sql.= " AND p.tosell = ".$status;
1941
        }
1942
        if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$filtertype;
1943
        // Add criteria on ref/label
1944
        if ($filterkey != '')
1945
        {
1946
        	$sql.=' AND (';
1947
        	$prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':'';	// Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
1948
            // For natural search
1949
            $scrit = explode(' ', $filterkey);
1950
            $i=0;
1951
            if (count($scrit) > 1) $sql.="(";
1952
            foreach ($scrit as $crit)
1953
            {
1954
            	if ($i > 0) $sql.=" AND ";
1955
                $sql.="(p.ref LIKE '".$db->escape($prefix.$crit)."%' OR p.label LIKE '".$db->escape($prefix.$crit)."%'";
1956
                if (! empty($conf->global->MAIN_MULTILANGS)) $sql.=" OR pl.label LIKE '".$db->escape($prefix.$crit)."%'";
1957
                $sql.=")";
1958
                $i++;
1959
            }
1960
            if (count($scrit) > 1) $sql.=")";
1961
          	if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$db->escape($prefix.$filterkey)."%'";
1962
        	$sql.=')';
1963
        }
1964
        if (count($warehouseStatusArray))
1965
        {
1966
            $sql.= ' GROUP BY'.$selectFields;
1967
        }
1968
        $sql.= $db->order("p.ref");
1969
        $sql.= $db->plimit($limit, 0);
1970
1971
        // Build output string
1972
        dol_syslog(get_class($this)."::select_produits_list search product", LOG_DEBUG);
1973
        $result=$this->db->query($sql);
1974
        if ($result)
1975
        {
1976
            require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1977
            require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
1978
            $num = $this->db->num_rows($result);
1979
1980
            $events=null;
1981
1982
            if ($conf->use_javascript_ajax && ! $forcecombo)
1983
            {
1984
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1985
            	$comboenhancement =ajax_combobox($htmlname, $events, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT);
1986
            	$out.= $comboenhancement;
1987
            }
1988
1989
            $out.='<select class="flat'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" id="'.$htmlname.'">';
1990
1991
            $textifempty='';
1992
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
1993
            //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
1994
            if (! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
1995
            {
1996
                if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty);
1997
                else $textifempty.=$langs->trans("All");
1998
            }
1999
            if ($showempty) $out.='<option value="0" selected>'.$textifempty.'</option>';
2000
2001
            $i = 0;
2002
            while ($num && $i < $num)
2003
            {
2004
            	$opt = '';
2005
				$optJson = array();
2006
				$objp = $this->db->fetch_object($result);
2007
2008
				if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1)
2009
				{ // Price by quantity will return many prices for the same product
2010
					$sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise";
2011
					$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
2012
					$sql.= " WHERE fk_product_price=".$objp->price_rowid;
2013
					$sql.= " ORDER BY quantity ASC";
2014
2015
					dol_syslog(get_class($this)."::select_produits_list search price by qty", LOG_DEBUG);
2016
					$result2 = $this->db->query($sql);
2017
					if ($result2)
2018
					{
2019
						$nb_prices = $this->db->num_rows($result2);
2020
						$j = 0;
2021
						while ($nb_prices && $j < $nb_prices) {
2022
							$objp2 = $this->db->fetch_object($result2);
2023
2024
							$objp->quantity = $objp2->quantity;
2025
							$objp->price = $objp2->price;
2026
							$objp->unitprice = $objp2->unitprice;
2027
							$objp->remise_percent = $objp2->remise_percent;
2028
							$objp->remise = $objp2->remise;
2029
							$objp->price_by_qty_rowid = $objp2->rowid;
2030
2031
							$this->constructProductListOption($objp, $opt, $optJson, 0, $selected, $hidepriceinlabel);
2032
2033
							$j++;
2034
2035
							// Add new entry
2036
							// "key" value of json key array is used by jQuery automatically as selected value
2037
							// "label" value of json key array is used by jQuery automatically as text for combo box
2038
							$out.=$opt;
2039
							array_push($outarray, $optJson);
2040
						}
2041
					}
2042
				}
2043
				else
2044
				{
2045
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_price_expression)) {
2046
                        $price_product = new Product($this->db);
2047
                        $price_product->fetch($objp->rowid, '', '', 1);
2048
                        $priceparser = new PriceParser($this->db);
2049
                        $price_result = $priceparser->parseProduct($price_product);
2050
                        if ($price_result >= 0) {
2051
                            $objp->price = $price_result;
2052
                            $objp->unitprice = $price_result;
2053
                            //Calculate the VAT
2054
                            $objp->price_ttc = price2num($objp->price) * (1 + ($objp->tva_tx / 100));
2055
                            $objp->price_ttc = price2num($objp->price_ttc,'MU');
2056
                        }
2057
                    }
2058
					$this->constructProductListOption($objp, $opt, $optJson, $price_level, $selected, $hidepriceinlabel);
2059
					// Add new entry
2060
					// "key" value of json key array is used by jQuery automatically as selected value
2061
					// "label" value of json key array is used by jQuery automatically as text for combo box
2062
					$out.=$opt;
2063
					array_push($outarray, $optJson);
2064
				}
2065
2066
                $i++;
2067
            }
2068
2069
            $out.='</select>';
2070
2071
            $this->db->free($result);
2072
2073
            if (empty($outputmode)) return $out;
2074
            return $outarray;
2075
        }
2076
        else
2077
		{
2078
            dol_print_error($db);
2079
        }
2080
    }
2081
2082
    /**
2083
     * constructProductListOption
2084
     *
2085
     * @param 	resultset	$objp			    Resultset of fetch
2086
     * @param 	string		$opt			    Option (var used for returned value in string option format)
2087
     * @param 	string		$optJson		    Option (var used for returned value in json format)
2088
     * @param 	int			$price_level	    Price level
2089
     * @param 	string		$selected		    Preselected value
2090
     * @param   int         $hidepriceinlabel   Hide price in label
2091
     * @return	void
2092
     */
2093
	private function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel=0)
2094
	{
2095
		global $langs,$conf,$user,$db;
2096
2097
        $outkey='';
2098
        $outval='';
2099
        $outref='';
2100
        $outlabel='';
2101
        $outdesc='';
2102
        $outbarcode='';
2103
        $outtype='';
2104
        $outprice_ht='';
2105
        $outprice_ttc='';
2106
        $outpricebasetype='';
2107
        $outtva_tx='';
2108
		$outqty=1;
2109
		$outdiscount=0;
2110
2111
		$maxlengtharticle=(empty($conf->global->PRODUCT_MAX_LENGTH_COMBO)?48:$conf->global->PRODUCT_MAX_LENGTH_COMBO);
2112
2113
        $label=$objp->label;
2114
        if (! empty($objp->label_translated)) $label=$objp->label_translated;
2115
        if (! empty($filterkey) && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1);
0 ignored issues
show
Bug introduced by
The variable $filterkey seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
2116
2117
        $outkey=$objp->rowid;
2118
        $outref=$objp->ref;
2119
        $outlabel=$objp->label;
2120
        $outdesc=$objp->description;
2121
        $outbarcode=$objp->barcode;
2122
2123
        $outtype=$objp->fk_product_type;
2124
        $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):'';
2125
        $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):'';
2126
2127
        $opt = '<option value="'.$objp->rowid.'"';
2128
        $opt.= ($objp->rowid == $selected)?' selected':'';
2129
		$opt.= (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0)?' pbq="'.$objp->price_by_qty_rowid.'"':'';
2130
        if (! empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock))
2131
        {
2132
			if ($objp->stock > 0) $opt.= ' class="product_line_stock_ok"';
2133
			else if ($objp->stock <= 0) $opt.= ' class="product_line_stock_too_low"';
2134
        }
2135
        $opt.= '>';
2136
        $opt.= $objp->ref;
2137
        if ($outbarcode) $opt.=' ('.$outbarcode.')';
2138
        $opt.=' - '.dol_trunc($label,$maxlengtharticle);
2139
2140
        $objRef = $objp->ref;
2141
        if (! empty($filterkey) && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1);
2142
        $outval.=$objRef;
2143
        if ($outbarcode) $outval.=' ('.$outbarcode.')';
2144
        $outval.=' - '.dol_trunc($label,$maxlengtharticle);
2145
2146
        $found=0;
2147
2148
        // Multiprice
2149
        if (empty($hidepriceinlabel) && $price_level >= 1 && $conf->global->PRODUIT_MULTIPRICES)		// If we need a particular price level (from 1 to 6)
2150
        {
2151
            $sql = "SELECT price, price_ttc, price_base_type, tva_tx";
2152
            $sql.= " FROM ".MAIN_DB_PREFIX."product_price";
2153
            $sql.= " WHERE fk_product='".$objp->rowid."'";
2154
            $sql.= " AND entity IN (".getEntity('productprice').")";
2155
            $sql.= " AND price_level=".$price_level;
2156
            $sql.= " ORDER BY date_price DESC, rowid DESC"; // Warning DESC must be both on date_price and rowid.
2157
            $sql.= " LIMIT 1";
2158
2159
            dol_syslog(get_class($this).'::constructProductListOption search price for level '.$price_level.'', LOG_DEBUG);
2160
            $result2 = $this->db->query($sql);
2161
            if ($result2)
2162
            {
2163
                $objp2 = $this->db->fetch_object($result2);
2164
                if ($objp2)
2165
                {
2166
                    $found=1;
2167
                    if ($objp2->price_base_type == 'HT')
2168
                    {
2169
                        $opt.= ' - '.price($objp2->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT");
2170
                        $outval.= ' - '.price($objp2->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT");
2171
                    }
2172
                    else
2173
                    {
2174
                        $opt.= ' - '.price($objp2->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC");
2175
                        $outval.= ' - '.price($objp2->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC");
2176
                    }
2177
                    $outprice_ht=price($objp2->price);
2178
                    $outprice_ttc=price($objp2->price_ttc);
2179
                    $outpricebasetype=$objp2->price_base_type;
2180
                    $outtva_tx=$objp2->tva_tx;
2181
                }
2182
            }
2183
            else
2184
            {
2185
                dol_print_error($this->db);
2186
            }
2187
        }
2188
2189
		// Price by quantity
2190
		if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1 && ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
2191
		{
2192
			$found = 1;
2193
			$outqty=$objp->quantity;
2194
			$outdiscount=$objp->remise_percent;
2195
			if ($objp->quantity == 1)
2196
			{
2197
				$opt.= ' - '.price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/";
2198
				$outval.= ' - '.price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/";
2199
				$opt.= $langs->trans("Unit");	// Do not use strtolower because it breaks utf8 encoding
2200
				$outval.=$langs->transnoentities("Unit");
2201
			}
2202
			else
2203
			{
2204
				$opt.= ' - '.price($objp->price,1,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2205
				$outval.= ' - '.price($objp->price,0,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2206
				$opt.= $langs->trans("Units");	// Do not use strtolower because it breaks utf8 encoding
2207
				$outval.=$langs->transnoentities("Units");
2208
			}
2209
2210
			$outprice_ht=price($objp->unitprice);
2211
            $outprice_ttc=price($objp->unitprice * (1 + ($objp->tva_tx / 100)));
2212
            $outpricebasetype=$objp->price_base_type;
2213
            $outtva_tx=$objp->tva_tx;
2214
		}
2215
		if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1)
2216
		{
2217
			$opt.=" (".price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2218
			$outval.=" (".price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/".$langs->transnoentities("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2219
		}
2220
		if (empty($hidepriceinlabel) && !empty($objp->remise_percent) && $objp->remise_percent >= 1)
2221
		{
2222
			$opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %';
2223
			$outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %';
2224
		}
2225
2226
		// Price by customer
2227
		if (empty($hidepriceinlabel) && !empty($conf->global->PRODUIT_CUSTOMER_PRICES))
2228
		{
2229
			if (!empty($objp->idprodcustprice))
2230
			{
2231
				$found = 1;
2232
2233
				if ($objp->custprice_base_type == 'HT')
2234
				{
2235
					$opt.= ' - '.price($objp->custprice,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT");
2236
					$outval.= ' - '.price($objp->custprice,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT");
2237
				}
2238
				else
2239
				{
2240
					$opt.= ' - '.price($objp->custprice_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC");
2241
					$outval.= ' - '.price($objp->custprice_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC");
2242
				}
2243
2244
				$outprice_ht=price($objp->custprice);
2245
				$outprice_ttc=price($objp->custprice_ttc);
2246
				$outpricebasetype=$objp->custprice_base_type;
2247
				$outtva_tx=$objp->custtva_tx;
2248
			}
2249
		}
2250
2251
        // If level no defined or multiprice not found, we used the default price
2252
        if (empty($hidepriceinlabel) && ! $found)
2253
        {
2254
            if ($objp->price_base_type == 'HT')
2255
            {
2256
                $opt.= ' - '.price($objp->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT");
2257
                $outval.= ' - '.price($objp->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT");
2258
            }
2259
            else
2260
            {
2261
                $opt.= ' - '.price($objp->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC");
2262
                $outval.= ' - '.price($objp->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC");
2263
            }
2264
            $outprice_ht=price($objp->price);
2265
            $outprice_ttc=price($objp->price_ttc);
2266
            $outpricebasetype=$objp->price_base_type;
2267
            $outtva_tx=$objp->tva_tx;
2268
        }
2269
2270
        if (! empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0)
2271
        {
2272
            $opt.= ' - '.$langs->trans("Stock").':'.$objp->stock;
2273
2274
            if ($objp->stock > 0) {
2275
            	$outval.= ' - <span class="product_line_stock_ok">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>';
2276
            }elseif ($objp->stock <= 0) {
2277
            	$outval.= ' - <span class="product_line_stock_too_low">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>';
2278
            }
2279
        }
2280
2281
        if ($outdurationvalue && $outdurationunit)
2282
        {
2283
            $da=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("Day"),"w"=>$langs->trans("Week"),"m"=>$langs->trans("Month"),"y"=>$langs->trans("Year"));
2284
            if (isset($da[$outdurationunit]))
2285
            {
2286
                $key = $da[$outdurationunit].($outdurationvalue > 1?'s':'');
2287
                $opt.= ' - '.$outdurationvalue.' '.$langs->trans($key);
2288
                $outval.=' - '.$outdurationvalue.' '.$langs->transnoentities($key);
2289
            }
2290
        }
2291
2292
        $opt.= "</option>\n";
2293
		$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);
2294
	}
2295
2296
    /**
2297
     *	Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list)
2298
     *
2299
     *	@param	int		$socid			Id third party
2300
     *	@param  string	$selected       Preselected product
2301
     *	@param  string	$htmlname       Name of HTML Select
2302
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2303
     *	@param  string	$filtre			For a SQL filter
2304
     *	@param	array	$ajaxoptions	Options for ajax_autocompleter
2305
	 *  @param	int		$hidelabel		Hide label (0=no, 1=yes)
2306
	 *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2307
     *	@return	void
2308
     */
2309
    function select_produits_fournisseurs($socid, $selected='', $htmlname='productid', $filtertype='', $filtre='', $ajaxoptions=array(), $hidelabel=0, $alsoproductwithnosupplierprice=0)
2310
    {
2311
        global $langs,$conf;
2312
        global $price_level, $status, $finished;
2313
2314
        $selected_input_value='';
2315
        if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
2316
        {
2317
            if ($selected > 0)
2318
            {
2319
                require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
2320
                $producttmpselect = new Product($this->db);
2321
                $producttmpselect->fetch($selected);
2322
                $selected_input_value=$producttmpselect->ref;
2323
                unset($producttmpselect);
2324
            }
2325
2326
			// mode=2 means suppliers products
2327
            $urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished.'&alsoproductwithnosupplierprice='.$alsoproductwithnosupplierprice;
2328
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
2329
            print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'">';
2330
        }
2331
        else
2332
        {
2333
        	print $this->select_produits_fournisseurs_list($socid,$selected,$htmlname,$filtertype,$filtre,'',-1,0,0,$alsoproductwithnosupplierprice);
2334
        }
2335
    }
2336
2337
    /**
2338
     *	Return list of suppliers products
2339
     *
2340
     *	@param	int		$socid   		Id societe fournisseur (0 pour aucun filtre)
2341
     *	@param  int		$selected       Produit pre-selectionne
2342
     *	@param  string	$htmlname       Nom de la zone select
2343
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2344
     *	@param  string	$filtre         Pour filtre sql
2345
     *	@param  string	$filterkey      Filtre des produits
2346
     *  @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)
2347
     *  @param  int		$outputmode     0=HTML select string, 1=Array
2348
     *  @param  int     $limit          Limit of line number
2349
	 *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2350
     *  @return array           		Array of keys for json
2351
     */
2352
    function select_produits_fournisseurs_list($socid,$selected='',$htmlname='productid',$filtertype='',$filtre='',$filterkey='',$statut=-1,$outputmode=0,$limit=100,$alsoproductwithnosupplierprice=0)
2353
    {
2354
        global $langs,$conf,$db;
2355
2356
        $out='';
2357
        $outarray=array();
2358
2359
        $langs->load('stocks');
2360
2361
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,";
2362
        $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
2363
        $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
2364
        $sql.= " pfp.supplier_reputation";
2365
        $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
2366
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2367
        if ($socid) $sql.= " AND pfp.fk_soc = ".$socid;
2368
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid";
2369
        $sql.= " WHERE p.entity IN (".getEntity('product').")";
2370
        $sql.= " AND p.tobuy = 1";
2371
        if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$this->db->escape($filtertype);
2372
        if (! empty($filtre)) $sql.=" ".$filtre;
2373
        // Add criteria on ref/label
2374
        if ($filterkey != '')
2375
        {
2376
        	$sql.=' AND (';
2377
        	$prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':'';	// Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
2378
        	// For natural search
2379
        	$scrit = explode(' ', $filterkey);
2380
        	$i=0;
2381
        	if (count($scrit) > 1) $sql.="(";
2382
        	foreach ($scrit as $crit)
2383
        	{
2384
        		if ($i > 0) $sql.=" AND ";
2385
        		$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)."%')";
2386
        		$i++;
2387
        	}
2388
        	if (count($scrit) > 1) $sql.=")";
2389
        	if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'";
2390
        	$sql.=')';
2391
        }
2392
        $sql.= " ORDER BY pfp.ref_fourn DESC, pfp.quantity ASC";
2393
        $sql.= $db->plimit($limit, 0);
2394
2395
        // Build output string
2396
2397
        dol_syslog(get_class($this)."::select_produits_fournisseurs_list", LOG_DEBUG);
2398
        $result=$this->db->query($sql);
2399
        if ($result)
2400
        {
2401
            require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
2402
2403
            $num = $this->db->num_rows($result);
2404
2405
            //$out.='<select class="flat" id="select'.$htmlname.'" name="'.$htmlname.'">';	// remove select to have id same with combo and ajax
2406
            $out.='<select class="flat maxwidthonsmartphone" id="'.$htmlname.'" name="'.$htmlname.'">';
2407
            if (! $selected) $out.='<option value="0" selected>&nbsp;</option>';
2408
            else $out.='<option value="0">&nbsp;</option>';
2409
2410
            $i = 0;
2411
            while ($i < $num)
2412
            {
2413
                $objp = $this->db->fetch_object($result);
2414
2415
                $outkey=$objp->idprodfournprice;                                                    // id in table of price
2416
                if (! $outkey && $alsoproductwithnosupplierprice) $outkey='idprod_'.$objp->rowid;   // id of product
2417
2418
                $outref=$objp->ref;
2419
                $outval='';
2420
                $outqty=1;
2421
				$outdiscount=0;
2422
                $outtype=$objp->fk_product_type;
2423
                $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):'';
2424
                $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):'';
2425
2426
                $opt = '<option value="'.$outkey.'"';
2427
                if ($selected && $selected == $objp->idprodfournprice) $opt.= ' selected';
2428
                if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt.=' disabled';
2429
                $opt.= '>';
2430
2431
                $objRef = $objp->ref;
2432
                if ($filterkey && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1);
2433
                $objRefFourn = $objp->ref_fourn;
2434
                if ($filterkey && $filterkey != '') $objRefFourn=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRefFourn,1);
2435
                $label = $objp->label;
2436
                if ($filterkey && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1);
2437
2438
                $opt.=$objp->ref;
2439
                if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2440
                	$opt.=' ('.$objp->ref_fourn.')';
2441
                $opt.=' - ';
2442
                $outval.=$objRef;
2443
                if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2444
                	$outval.=' ('.$objRefFourn.')';
2445
                $outval.=' - ';
2446
                $opt.=dol_trunc($label, 72).' - ';
2447
                $outval.=dol_trunc($label, 72).' - ';
2448
2449
                if (! empty($objp->idprodfournprice))
2450
                {
2451
                    $outqty=$objp->quantity;
2452
					$outdiscount=$objp->remise_percent;
2453
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2454
                        $prod_supplier = new ProductFournisseur($this->db);
2455
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2456
                        $prod_supplier->id = $objp->fk_product;
2457
                        $prod_supplier->fourn_qty = $objp->quantity;
2458
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2459
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2460
                        $priceparser = new PriceParser($this->db);
2461
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2462
                        if ($price_result >= 0) {
2463
                            $objp->fprice = $price_result;
2464
                            if ($objp->quantity >= 1)
2465
                            {
2466
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2467
                            }
2468
                        }
2469
                    }
2470
                    if ($objp->quantity == 1)
2471
                    {
2472
	                    $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/";
2473
                    	$outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/";
2474
                    	$opt.= $langs->trans("Unit");	// Do not use strtolower because it breaks utf8 encoding
2475
                        $outval.=$langs->transnoentities("Unit");
2476
                    }
2477
                    else
2478
                    {
2479
    	                $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2480
	                    $outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2481
                    	$opt.= ' '.$langs->trans("Units");	// Do not use strtolower because it breaks utf8 encoding
2482
                        $outval.= ' '.$langs->transnoentities("Units");
2483
                    }
2484
2485
                    if ($objp->quantity >= 1)
2486
                    {
2487
                        $opt.=" (".price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2488
                        $outval.=" (".price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/".$langs->transnoentities("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2489
                    }
2490
					if ($objp->remise_percent >= 1)
2491
                    {
2492
                        $opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %';
2493
                        $outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %';
2494
                    }
2495
                    if ($objp->duration)
2496
                    {
2497
                        $opt .= " - ".$objp->duration;
2498
                        $outval.=" - ".$objp->duration;
2499
                    }
2500
                    if (! $socid)
2501
                    {
2502
                        $opt .= " - ".dol_trunc($objp->name,8);
2503
                        $outval.=" - ".dol_trunc($objp->name,8);
2504
                    }
2505
                    if ($objp->supplier_reputation)
2506
                    {
2507
            			//TODO dictionary
2508
            			$reputations=array(''=>$langs->trans('Standard'),'FAVORITE'=>$langs->trans('Favorite'),'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier'));
2509
2510
                        $opt .= " - ".$reputations[$objp->supplier_reputation];
2511
                        $outval.=" - ".$reputations[$objp->supplier_reputation];
2512
                    }
2513
                }
2514
                else
2515
                {
2516
                    if (empty($alsoproductwithnosupplierprice))     // No supplier price defined for couple product/supplier
2517
                    {
2518
                        $opt.= $langs->trans("NoPriceDefinedForThisSupplier");
2519
                        $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier");
2520
                    }
2521
                    else                                            // No supplier price defined for product, even on other suppliers
2522
                    {
2523
                        $opt.= $langs->trans("NoPriceDefinedForThisSupplier");
2524
                        $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier");
2525
                    }
2526
                }
2527
                $opt .= "</option>\n";
2528
2529
2530
                // Add new entry
2531
                // "key" value of json key array is used by jQuery automatically as selected value
2532
                // "label" value of json key array is used by jQuery automatically as text for combo box
2533
                $out.=$opt;
2534
                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)));
2535
				// Exemple of var_dump $outarray
2536
				// array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp"
2537
				//           ["label"]=>string(76) "ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)"
2538
				//      	 ["qty"]=>string(1) "1" ["discount"]=>string(1) "0" ["disabled"]=>bool(false)
2539
                //}
2540
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2541
                //$outval=array('label'=>'ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/ Unité (20,00 Euros/unité)');
2542
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2543
2544
                $i++;
2545
            }
2546
            $out.='</select>';
2547
2548
            $this->db->free($result);
2549
2550
            if (empty($outputmode)) return $out;
2551
            return $outarray;
2552
        }
2553
        else
2554
        {
2555
            dol_print_error($this->db);
2556
        }
2557
    }
2558
2559
    /**
2560
     *	Return list of suppliers prices for a product
2561
     *
2562
     *  @param	    int		$productid       	Id of product
2563
     *  @param      string	$htmlname        	Name of HTML field
2564
     *  @param      int		$selected_supplier  Pre-selected supplier if more than 1 result
2565
     *  @return	    void
2566
     */
2567
    function select_product_fourn_price($productid, $htmlname='productfournpriceid', $selected_supplier='')
2568
    {
2569
        global $langs,$conf;
2570
2571
        $langs->load('stocks');
2572
2573
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,";
2574
        $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice,";
2575
        $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name";
2576
        $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
2577
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2578
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid";
2579
        $sql.= " WHERE p.entity IN (".getEntity('productprice').")";
2580
        $sql.= " AND p.tobuy = 1";
2581
        $sql.= " AND s.fournisseur = 1";
2582
        $sql.= " AND p.rowid = ".$productid;
2583
        $sql.= " ORDER BY s.nom, pfp.ref_fourn DESC";
2584
2585
        dol_syslog(get_class($this)."::select_product_fourn_price", LOG_DEBUG);
2586
        $result=$this->db->query($sql);
2587
2588
        if ($result)
2589
        {
2590
            $num = $this->db->num_rows($result);
2591
2592
            $form = '<select class="flat" name="'.$htmlname.'">';
2593
2594
            if (! $num)
2595
            {
2596
                $form.= '<option value="0">-- '.$langs->trans("NoSupplierPriceDefinedForThisProduct").' --</option>';
2597
            }
2598
            else
2599
            {
2600
                require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
2601
                $form.= '<option value="0">&nbsp;</option>';
2602
2603
                $i = 0;
2604
                while ($i < $num)
2605
                {
2606
                    $objp = $this->db->fetch_object($result);
2607
2608
                    $opt = '<option value="'.$objp->idprodfournprice.'"';
2609
                    //if there is only one supplier, preselect it
2610
                    if($num == 1 || ($selected_supplier > 0 && $objp->fk_soc == $selected_supplier)) {
2611
                        $opt .= ' selected';
2612
                    }
2613
                    $opt.= '>'.$objp->name.' - '.$objp->ref_fourn.' - ';
2614
2615
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2616
                        $prod_supplier = new ProductFournisseur($this->db);
2617
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2618
                        $prod_supplier->id = $productid;
2619
                        $prod_supplier->fourn_qty = $objp->quantity;
2620
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2621
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2622
                        $priceparser = new PriceParser($this->db);
2623
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2624
                        if ($price_result >= 0) {
2625
                            $objp->fprice = $price_result;
2626
                            if ($objp->quantity >= 1)
2627
                            {
2628
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2629
                            }
2630
                        }
2631
                    }
2632
                    if ($objp->quantity == 1)
2633
                    {
2634
                        $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/";
2635
                    }
2636
2637
                    $opt.= $objp->quantity.' ';
2638
2639
                    if ($objp->quantity == 1)
2640
                    {
2641
                        $opt.= $langs->trans("Unit");
2642
                    }
2643
                    else
2644
                    {
2645
                        $opt.= $langs->trans("Units");
2646
                    }
2647
                    if ($objp->quantity > 1)
2648
                    {
2649
                        $opt.=" - ";
2650
                        $opt.= price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit");
2651
                    }
2652
                    if ($objp->duration) $opt .= " - ".$objp->duration;
2653
                    $opt .= "</option>\n";
2654
2655
                    $form.= $opt;
2656
                    $i++;
2657
                }
2658
            }
2659
2660
            $form.= '</select>';
2661
            $this->db->free($result);
2662
            return $form;
2663
        }
2664
        else
2665
        {
2666
            dol_print_error($this->db);
2667
        }
2668
    }
2669
2670
    /**
2671
     *    Return list of delivery address
2672
     *
2673
     *    @param    string	$selected          	Id contact pre-selectionn
2674
     *    @param    int		$socid				Id of company
2675
     *    @param    string	$htmlname          	Name of HTML field
2676
     *    @param    int		$showempty         	Add an empty field
2677
     *    @return	integer|null
2678
     */
2679
    function select_address($selected, $socid, $htmlname='address_id',$showempty=0)
2680
    {
2681
        // On recherche les utilisateurs
2682
        $sql = "SELECT a.rowid, a.label";
2683
        $sql .= " FROM ".MAIN_DB_PREFIX ."societe_address as a";
2684
        $sql .= " WHERE a.fk_soc = ".$socid;
2685
        $sql .= " ORDER BY a.label ASC";
2686
2687
        dol_syslog(get_class($this)."::select_address", LOG_DEBUG);
2688
        $resql=$this->db->query($sql);
2689
        if ($resql)
2690
        {
2691
            print '<select class="flat" name="'.$htmlname.'">';
2692
            if ($showempty) print '<option value="0">&nbsp;</option>';
2693
            $num = $this->db->num_rows($resql);
2694
            $i = 0;
2695
            if ($num)
2696
            {
2697
                while ($i < $num)
2698
                {
2699
                    $obj = $this->db->fetch_object($resql);
2700
2701
                    if ($selected && $selected == $obj->rowid)
2702
                    {
2703
                        print '<option value="'.$obj->rowid.'" selected>'.$obj->label.'</option>';
2704
                    }
2705
                    else
2706
                    {
2707
                        print '<option value="'.$obj->rowid.'">'.$obj->label.'</option>';
2708
                    }
2709
                    $i++;
2710
                }
2711
            }
2712
            print '</select>';
2713
            return $num;
2714
        }
2715
        else
2716
        {
2717
            dol_print_error($this->db);
2718
        }
2719
    }
2720
2721
2722
    /**
2723
     *      Load into cache list of payment terms
2724
     *
2725
     *      @return     int             Nb of lines loaded, <0 if KO
2726
     */
2727
    function load_cache_conditions_paiements()
2728
    {
2729
        global $langs;
2730
2731
        $num = count($this->cache_conditions_paiements);
2732
        if ($num > 0) return 0;    // Cache already loaded
2733
2734
        dol_syslog(__METHOD__, LOG_DEBUG);
2735
2736
        $sql = "SELECT rowid, code, libelle as label";
2737
        $sql.= " FROM ".MAIN_DB_PREFIX.'c_payment_term';
2738
        $sql.= " WHERE active > 0";
2739
        $sql.= " ORDER BY sortorder";
2740
2741
        $resql = $this->db->query($sql);
2742
        if ($resql)
2743
        {
2744
            $num = $this->db->num_rows($resql);
2745
            $i = 0;
2746
            while ($i < $num)
2747
            {
2748
                $obj = $this->db->fetch_object($resql);
2749
2750
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2751
                $label=($langs->trans("PaymentConditionShort".$obj->code)!=("PaymentConditionShort".$obj->code)?$langs->trans("PaymentConditionShort".$obj->code):($obj->label!='-'?$obj->label:''));
2752
                $this->cache_conditions_paiements[$obj->rowid]['code'] =$obj->code;
2753
                $this->cache_conditions_paiements[$obj->rowid]['label']=$label;
2754
                $i++;
2755
            }
2756
2757
			//$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label', 'asc', 0, 0, 1);		// We use the field sortorder of table
2758
2759
            return $num;
2760
        }
2761
        else
2762
		{
2763
            dol_print_error($this->db);
2764
            return -1;
2765
        }
2766
    }
2767
2768
    /**
2769
     *      Charge dans cache la liste des délais de livraison possibles
2770
     *
2771
     *      @return     int             Nb of lines loaded, <0 if KO
2772
     */
2773
    function load_cache_availability()
2774
    {
2775
        global $langs;
2776
2777
        $num = count($this->cache_availability);
2778
        if ($num > 0) return 0;    // Cache already loaded
2779
2780
        dol_syslog(__METHOD__, LOG_DEBUG);
2781
2782
		$langs->load('propal');
2783
2784
        $sql = "SELECT rowid, code, label";
2785
        $sql.= " FROM ".MAIN_DB_PREFIX.'c_availability';
2786
        $sql.= " WHERE active > 0";
2787
2788
        $resql = $this->db->query($sql);
2789
        if ($resql)
2790
        {
2791
            $num = $this->db->num_rows($resql);
2792
            $i = 0;
2793
            while ($i < $num)
2794
            {
2795
                $obj = $this->db->fetch_object($resql);
2796
2797
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2798
                $label=($langs->trans("AvailabilityType".$obj->code)!=("AvailabilityType".$obj->code)?$langs->trans("AvailabilityType".$obj->code):($obj->label!='-'?$obj->label:''));
2799
                $this->cache_availability[$obj->rowid]['code'] =$obj->code;
2800
                $this->cache_availability[$obj->rowid]['label']=$label;
2801
                $i++;
2802
            }
2803
2804
            $this->cache_availability = dol_sort_array($this->cache_availability, 'label', 'asc', 0, 0, 1);
2805
2806
            return $num;
2807
        }
2808
        else
2809
		{
2810
            dol_print_error($this->db);
2811
            return -1;
2812
        }
2813
    }
2814
2815
    /**
2816
     *      Retourne la liste des types de delais de livraison possibles
2817
     *
2818
     *      @param	int		$selected        Id du type de delais pre-selectionne
2819
     *      @param  string	$htmlname        Nom de la zone select
2820
     *      @param  string	$filtertype      To add a filter
2821
     *		@param	int		$addempty		Add empty entry
2822
     *		@return	void
2823
     */
2824
    function selectAvailabilityDelay($selected='',$htmlname='availid',$filtertype='',$addempty=0)
2825
    {
2826
        global $langs,$user;
2827
2828
        $this->load_cache_availability();
2829
2830
        dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
2831
2832
        print '<select class="flat" name="'.$htmlname.'">';
2833
        if ($addempty) print '<option value="0">&nbsp;</option>';
2834
        foreach($this->cache_availability as $id => $arrayavailability)
2835
        {
2836
            if ($selected == $id)
2837
            {
2838
                print '<option value="'.$id.'" selected>';
2839
            }
2840
            else
2841
            {
2842
                print '<option value="'.$id.'">';
2843
            }
2844
            print $arrayavailability['label'];
2845
            print '</option>';
2846
        }
2847
        print '</select>';
2848
        if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
2849
    }
2850
2851
    /**
2852
     *      Load into cache cache_demand_reason, array of input reasons
2853
     *
2854
     *      @return     int             Nb of lines loaded, <0 if KO
2855
     */
2856
    function loadCacheInputReason()
2857
    {
2858
        global $langs;
2859
2860
        $num = count($this->cache_demand_reason);
2861
        if ($num > 0) return 0;    // Cache already loaded
2862
2863
        $sql = "SELECT rowid, code, label";
2864
        $sql.= " FROM ".MAIN_DB_PREFIX.'c_input_reason';
2865
        $sql.= " WHERE active > 0";
2866
2867
        $resql = $this->db->query($sql);
2868
        if ($resql)
2869
        {
2870
            $num = $this->db->num_rows($resql);
2871
            $i = 0;
2872
            $tmparray=array();
2873
            while ($i < $num)
2874
            {
2875
                $obj = $this->db->fetch_object($resql);
2876
2877
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2878
                $label=($langs->trans("DemandReasonType".$obj->code)!=("DemandReasonType".$obj->code)?$langs->trans("DemandReasonType".$obj->code):($obj->label!='-'?$obj->label:''));
2879
                $tmparray[$obj->rowid]['id']   =$obj->rowid;
2880
                $tmparray[$obj->rowid]['code'] =$obj->code;
2881
                $tmparray[$obj->rowid]['label']=$label;
2882
                $i++;
2883
            }
2884
2885
            $this->cache_demand_reason=dol_sort_array($tmparray, 'label', 'asc', 0, 0, 1);
2886
2887
            unset($tmparray);
2888
            return $num;
2889
        }
2890
        else
2891
		{
2892
            dol_print_error($this->db);
2893
            return -1;
2894
        }
2895
    }
2896
2897
    /**
2898
	 *	Return list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
2899
	 *  List found into table c_input_reason loaded by loadCacheInputReason
2900
     *
2901
     *  @param	int		$selected        Id or code of type origin to select by default
2902
     *  @param  string	$htmlname        Nom de la zone select
2903
     *  @param  string	$exclude         To exclude a code value (Example: SRC_PROP)
2904
     *	@param	int		$addempty		 Add an empty entry
2905
     *	@return	void
2906
     */
2907
    function selectInputReason($selected='',$htmlname='demandreasonid',$exclude='',$addempty=0)
2908
    {
2909
        global $langs,$user;
2910
2911
        $this->loadCacheInputReason();
2912
2913
        print '<select class="flat" name="'.$htmlname.'">';
2914
        if ($addempty) print '<option value="0"'.(empty($selected)?' selected':'').'>&nbsp;</option>';
2915
        foreach($this->cache_demand_reason as $id => $arraydemandreason)
2916
        {
2917
            if ($arraydemandreason['code']==$exclude) continue;
2918
2919
            if ($selected && ($selected == $arraydemandreason['id'] || $selected == $arraydemandreason['code']))
2920
            {
2921
                print '<option value="'.$arraydemandreason['id'].'" selected>';
2922
            }
2923
            else
2924
            {
2925
                print '<option value="'.$arraydemandreason['id'].'">';
2926
            }
2927
            print $arraydemandreason['label'];
2928
            print '</option>';
2929
        }
2930
        print '</select>';
2931
        if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
2932
    }
2933
2934
    /**
2935
     *      Charge dans cache la liste des types de paiements possibles
2936
     *
2937
     *      @return     int                 Nb of lines loaded, <0 if KO
2938
     */
2939
    function load_cache_types_paiements()
2940
    {
2941
        global $langs;
2942
2943
        $num=count($this->cache_types_paiements);
2944
        if ($num > 0) return $num;    // Cache already loaded
2945
2946
        dol_syslog(__METHOD__, LOG_DEBUG);
2947
2948
        $this->cache_types_paiements = array();
2949
2950
        $sql = "SELECT id, code, libelle as label, type, active";
2951
        $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement";
2952
        //if ($active >= 0) $sql.= " WHERE active = ".$active;
2953
2954
        $resql = $this->db->query($sql);
2955
        if ($resql)
2956
        {
2957
            $num = $this->db->num_rows($resql);
2958
            $i = 0;
2959
            while ($i < $num)
2960
            {
2961
                $obj = $this->db->fetch_object($resql);
2962
2963
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2964
                $label=($langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code)!=("PaymentTypeShort".$obj->code)?$langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code):($obj->label!='-'?$obj->label:''));
2965
                $this->cache_types_paiements[$obj->id]['id'] =$obj->id;
2966
                $this->cache_types_paiements[$obj->id]['code'] =$obj->code;
2967
                $this->cache_types_paiements[$obj->id]['label']=$label;
2968
                $this->cache_types_paiements[$obj->id]['type'] =$obj->type;
2969
                $this->cache_types_paiements[$obj->id]['active'] =$obj->active;
2970
                $i++;
2971
            }
2972
2973
            $this->cache_types_paiements = dol_sort_array($this->cache_types_paiements, 'label', 'asc', 0, 0, 1);
2974
2975
            return $num;
2976
        }
2977
        else
2978
		{
2979
            dol_print_error($this->db);
2980
            return -1;
2981
        }
2982
    }
2983
2984
2985
    /**
2986
     *      Return list of payment modes.
2987
     *      Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want.
2988
     *      See instead to force the default value by the caller.
2989
     *
2990
     *      @param	int  	$selected       Id of payment term to preselect by default
2991
     *      @param  string	$htmlname       Nom de la zone select
2992
     *      @param  int 	$filtertype     Not used
2993
     *		@param	int		$addempty		Add an empty entry
2994
     * 		@param	int		$noadmininfo	0=Add admin info, 1=Disable admin info
2995
     * 		@param	string	$morecss		Add more CSS on select tag
2996
     *		@return	void
2997
     */
2998
    function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0, $noinfoadmin=0, $morecss='')
2999
    {
3000
        global $langs, $user, $conf;
3001
3002
        dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
3003
3004
        $this->load_cache_conditions_paiements();
3005
3006
        // Set default value if not already set by caller
3007
        if (empty($selected) && ! empty($conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID)) $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID;
3008
3009
        print '<select id="'.$htmlname.'" class="flat selectpaymentterms'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'">';
3010
        if ($addempty) print '<option value="0">&nbsp;</option>';
3011
        foreach($this->cache_conditions_paiements as $id => $arrayconditions)
3012
        {
3013
            if ($selected == $id)
3014
            {
3015
                print '<option value="'.$id.'" selected>';
3016
            }
3017
            else
3018
            {
3019
                print '<option value="'.$id.'">';
3020
            }
3021
            print $arrayconditions['label'];
3022
            print '</option>';
3023
        }
3024
        print '</select>';
3025
        if ($user->admin && empty($noinfoadmin)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
3026
    }
3027
3028
3029
    /**
3030
     *      Return list of payment methods
3031
     *
3032
     *      @param	string	$selected       Id du mode de paiement pre-selectionne
3033
     *      @param  string	$htmlname       Nom de la zone select
3034
     *      @param  string	$filtertype     To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz))
3035
     *      @param  int		$format         0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code
3036
     *      @param  int		$empty			1=peut etre vide, 0 sinon
3037
     * 		@param	int		$noadmininfo	0=Add admin info, 1=Disable admin info
3038
     *      @param  int		$maxlength      Max length of label
3039
     *      @param  int     $active         Active or not, -1 = all
3040
     *      @param  string  $morecss        Add more CSS on select tag
3041
     * 		@return	void
3042
     */
3043
    function select_types_paiements($selected='', $htmlname='paiementtype', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $active=1, $morecss='')
3044
    {
3045
        global $langs,$user;
3046
3047
        dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
3048
3049
        $filterarray=array();
3050
        if ($filtertype == 'CRDT')  	$filterarray=array(0,2,3);
3051
        elseif ($filtertype == 'DBIT') 	$filterarray=array(1,2,3);
3052
        elseif ($filtertype != '' && $filtertype != '-1') $filterarray=explode(',',$filtertype);
3053
3054
        $this->load_cache_types_paiements();
3055
3056
        print '<select id="select'.$htmlname.'" class="flat selectpaymenttypes'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'">';
3057
        if ($empty) print '<option value="">&nbsp;</option>';
3058
        foreach($this->cache_types_paiements as $id => $arraytypes)
3059
        {
3060
            // If not good status
3061
            if ($active >= 0 && $arraytypes['active'] != $active) continue;
3062
3063
            // On passe si on a demande de filtrer sur des modes de paiments particuliers
3064
            if (count($filterarray) && ! in_array($arraytypes['type'],$filterarray)) continue;
3065
3066
            // We discard empty line if showempty is on because an empty line has already been output.
3067
            if ($empty && empty($arraytypes['code'])) continue;
3068
3069
            if ($format == 0) print '<option value="'.$id.'"';
3070
            if ($format == 1) print '<option value="'.$arraytypes['code'].'"';
3071
            if ($format == 2) print '<option value="'.$arraytypes['code'].'"';
3072
            if ($format == 3) print '<option value="'.$id.'"';
3073
            // Si selected est text, on compare avec code, sinon avec id
3074
            if (preg_match('/[a-z]/i', $selected) && $selected == $arraytypes['code']) print ' selected';
3075
            elseif ($selected == $id) print ' selected';
3076
            print '>';
3077
            if ($format == 0) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']);
3078
            if ($format == 1) $value=$arraytypes['code'];
3079
            if ($format == 2) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']);
3080
            if ($format == 3) $value=$arraytypes['code'];
3081
            print $value?$value:'&nbsp;';
0 ignored issues
show
Bug introduced by
The variable $value does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
3082
            print '</option>';
3083
        }
3084
        print '</select>';
3085
        if ($user->admin && ! $noadmininfo) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
3086
    }
3087
3088
3089
    /**
3090
     *  Selection HT or TTC
3091
     *
3092
     *  @param	string	$selected       Id pre-selectionne
3093
     *  @param  string	$htmlname       Nom de la zone select
3094
     * 	@return	string					Code of HTML select to chose tax or not
3095
     */
3096
    function selectPriceBaseType($selected='',$htmlname='price_base_type')
3097
    {
3098
        global $langs;
3099
3100
        $return='';
3101
3102
        $return.= '<select class="flat" name="'.$htmlname.'">';
3103
        $options = array(
3104
			'HT'=>$langs->trans("HT"),
3105
			'TTC'=>$langs->trans("TTC")
3106
        );
3107
        foreach($options as $id => $value)
3108
        {
3109
            if ($selected == $id)
3110
            {
3111
                $return.= '<option value="'.$id.'" selected>'.$value;
3112
            }
3113
            else
3114
            {
3115
                $return.= '<option value="'.$id.'">'.$value;
3116
            }
3117
            $return.= '</option>';
3118
        }
3119
        $return.= '</select>';
3120
3121
        return $return;
3122
    }
3123
3124
    /**
3125
     *  Return a HTML select list of shipping mode
3126
     *
3127
     *  @param	string	$selected          Id shipping mode pre-selected
3128
     *  @param  string	$htmlname          Name of select zone
3129
     *  @param  string	$filtre            To filter list
3130
     *  @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.
3131
     *  @param  string	$moreattrib        To add more attribute on select
3132
     * 	@return	void
3133
     */
3134
    function selectShippingMethod($selected='',$htmlname='shipping_method_id',$filtre='',$useempty=0,$moreattrib='')
3135
    {
3136
        global $langs, $conf, $user;
3137
3138
        $langs->load("admin");
3139
        $langs->load("deliveries");
3140
3141
        $sql = "SELECT rowid, code, libelle as label";
3142
        $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode";
3143
        $sql.= " WHERE active > 0";
3144
        if ($filtre) $sql.=" AND ".$filtre;
3145
        $sql.= " ORDER BY libelle ASC";
3146
3147
        dol_syslog(get_class($this)."::selectShippingMode", LOG_DEBUG);
3148
        $result = $this->db->query($sql);
3149
        if ($result) {
3150
            $num = $this->db->num_rows($result);
3151
            $i = 0;
3152
            if ($num) {
3153
                print '<select id="select'.$htmlname.'" class="flat selectshippingmethod" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>';
3154
                if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
3155
                    print '<option value="-1">&nbsp;</option>';
3156
                }
3157
                while ($i < $num) {
3158
                    $obj = $this->db->fetch_object($result);
3159
                    if ($selected == $obj->rowid) {
3160
                        print '<option value="'.$obj->rowid.'" selected>';
3161
                    } else {
3162
                        print '<option value="'.$obj->rowid.'">';
3163
                    }
3164
                    print ($langs->trans("SendingMethod".strtoupper($obj->code)) != "SendingMethod".strtoupper($obj->code)) ? $langs->trans("SendingMethod".strtoupper($obj->code)) : $obj->label;
3165
                    print '</option>';
3166
                    $i++;
3167
                }
3168
                print "</select>";
3169
                if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
3170
            } else {
3171
                print $langs->trans("NoShippingMethodDefined");
3172
            }
3173
        } else {
3174
            dol_print_error($this->db);
3175
        }
3176
    }
3177
3178
    /**
3179
     *    Display form to select shipping mode
3180
     *
3181
     *    @param	string	$page        Page
3182
     *    @param    int		$selected    Id of shipping mode
3183
     *    @param    string	$htmlname    Name of select html field
3184
     *    @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.
3185
     *    @return	void
3186
     */
3187
    function formSelectShippingMethod($page, $selected='', $htmlname='shipping_method_id', $addempty=0)
3188
    {
3189
        global $langs, $db;
3190
3191
        $langs->load("deliveries");
3192
3193
        if ($htmlname != "none") {
3194
            print '<form method="POST" action="'.$page.'">';
3195
            print '<input type="hidden" name="action" value="setshippingmethod">';
3196
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3197
            $this->selectShippingMethod($selected, $htmlname, '', $addempty);
3198
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3199
            print '</form>';
3200
        } else {
3201
            if ($selected) {
3202
                $code=$langs->getLabelFromKey($db, $selected, 'c_shipment_mode', 'rowid', 'code');
3203
                print $langs->trans("SendingMethod".strtoupper($code));
3204
            } else {
3205
                print "&nbsp;";
3206
            }
3207
        }
3208
    }
3209
3210
	/**
3211
	 * Creates HTML last in cycle situation invoices selector
3212
	 *
3213
	 * @param     string  $selected   		Preselected ID
3214
	 * @param     int     $socid      		Company ID
3215
	 *
3216
	 * @return    string                     HTML select
3217
	 */
3218
	function selectSituationInvoices($selected = '', $socid = 0)
3219
	{
3220
		global $langs;
3221
3222
		$langs->load('bills');
3223
3224
		$opt = '<option value ="" selected></option>';
3225
		$sql = 'SELECT rowid, facnumber, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1';
3226
		$sql.= ' ORDER by situation_cycle_ref, situation_counter desc';
3227
		$resql = $this->db->query($sql);
3228
		if ($resql && $this->db->num_rows($resql) > 0) {
3229
			// Last seen cycle
3230
			$ref = 0;
3231
			while ($res = $this->db->fetch_array($resql, MYSQL_NUM)) {
3232
				//Same company ?
3233
				if ($socid == $res[5]) {
3234
					//Same cycle ?
3235
					if ($res[2] != $ref) {
3236
						// Just seen this cycle
3237
						$ref = $res[2];
3238
						//not final ?
3239
						if ($res[4] != 1) {
3240
							//Not prov?
3241
							if (substr($res[1], 1, 4) != 'PROV') {
3242
								if ($selected == $res[0]) {
3243
									$opt .= '<option value="' . $res[0] . '" selected>' . $res[1] . '</option>';
3244
								} else {
3245
									$opt .= '<option value="' . $res[0] . '">' . $res[1] . '</option>';
3246
								}
3247
							}
3248
						}
3249
					}
3250
				}
3251
			}
3252
		}
3253
		else
3254
		{
3255
				dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR);
3256
		}
3257
		if ($opt == '<option value ="" selected></option>')
3258
		{
3259
			$opt = '<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>';
3260
		}
3261
		return $opt;
3262
	}
3263
3264
    /**
3265
     *      Creates HTML units selector (code => label)
3266
     *
3267
     *      @param	string	$selected       Preselected Unit ID
3268
     *      @param  string	$htmlname       Select name
3269
     *      @param	int		$showempty		Add a nempty line
3270
     * 		@return	string                  HTML select
3271
     */
3272
    function selectUnits($selected = '', $htmlname = 'units', $showempty=0)
3273
    {
3274
        global $langs;
3275
3276
        $langs->load('products');
3277
3278
        $return= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'">';
3279
3280
        $sql = 'SELECT rowid, label from '.MAIN_DB_PREFIX.'c_units';
3281
        $sql.= ' WHERE active > 0';
3282
3283
        $resql = $this->db->query($sql);
3284
        if($resql && $this->db->num_rows($resql) > 0)
3285
        {
3286
	        if ($showempty) $return .= '<option value="none"></option>';
3287
3288
            while($res = $this->db->fetch_object($resql))
3289
            {
3290
                if ($selected == $res->rowid)
3291
                {
3292
                    $return.='<option value="'.$res->rowid.'" selected>'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>';
3293
                }
3294
                else
3295
                {
3296
                    $return.='<option value="'.$res->rowid.'">'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>';
3297
                }
3298
            }
3299
            $return.='</select>';
3300
        }
3301
        return $return;
3302
    }
3303
3304
    /**
3305
     *  Return a HTML select list of bank accounts
3306
     *
3307
     *  @param	string	$selected          Id account pre-selected
3308
     *  @param  string	$htmlname          Name of select zone
3309
     *  @param  int		$statut            Status of searched accounts (0=open, 1=closed, 2=both)
3310
     *  @param  string	$filtre            To filter list
3311
     *  @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.
3312
     *  @param  string	$moreattrib        To add more attribute on select
3313
     * 	@return	void
3314
     */
3315
    function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='')
3316
    {
3317
        global $langs, $conf;
3318
3319
        $langs->load("admin");
3320
3321
        $sql = "SELECT rowid, label, bank, clos as status";
3322
        $sql.= " FROM ".MAIN_DB_PREFIX."bank_account";
3323
        $sql.= " WHERE entity IN (".getEntity('bank_account').")";
3324
        if ($statut != 2) $sql.= " AND clos = '".$statut."'";
3325
        if ($filtre) $sql.=" AND ".$filtre;
3326
        $sql.= " ORDER BY label";
3327
3328
        dol_syslog(get_class($this)."::select_comptes", LOG_DEBUG);
3329
        $result = $this->db->query($sql);
3330
        if ($result)
3331
        {
3332
            $num = $this->db->num_rows($result);
3333
            $i = 0;
3334
            if ($num)
3335
            {
3336
                print '<select id="select'.$htmlname.'" class="flat selectbankaccount" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>';
3337
                if ($useempty == 1 || ($useempty == 2 && $num > 1))
3338
                {
3339
                    print '<option value="-1">&nbsp;</option>';
3340
                }
3341
3342
                while ($i < $num)
3343
                {
3344
                    $obj = $this->db->fetch_object($result);
3345
                    if ($selected == $obj->rowid)
3346
                    {
3347
                        print '<option value="'.$obj->rowid.'" selected>';
3348
                    }
3349
                    else
3350
                    {
3351
                        print '<option value="'.$obj->rowid.'">';
3352
                    }
3353
                    print trim($obj->label);
3354
                    if ($statut == 2 && $obj->status == 1) print ' ('.$langs->trans("Closed").')';
3355
                    print '</option>';
3356
                    $i++;
3357
                }
3358
                print "</select>";
3359
            }
3360
            else
3361
            {
3362
                print $langs->trans("NoActiveBankAccountDefined");
3363
            }
3364
        }
3365
        else {
3366
            dol_print_error($this->db);
3367
        }
3368
    }
3369
3370
    /**
3371
     *    Display form to select bank account
3372
     *
3373
     *    @param	string	$page        Page
3374
     *    @param    int		$selected    Id of bank account
3375
     *    @param    string	$htmlname    Name of select html field
3376
     *    @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.
3377
     *    @return	void
3378
     */
3379
    function formSelectAccount($page, $selected='', $htmlname='fk_account', $addempty=0)
3380
    {
3381
        global $langs;
3382
        if ($htmlname != "none") {
3383
            print '<form method="POST" action="'.$page.'">';
3384
            print '<input type="hidden" name="action" value="setbankaccount">';
3385
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3386
            $this->select_comptes($selected, $htmlname, 0, '', $addempty);
3387
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3388
            print '</form>';
3389
        } else {
3390
3391
        	$langs->load('banks');
3392
3393
            if ($selected) {
3394
                require_once DOL_DOCUMENT_ROOT .'/compta/bank/class/account.class.php';
3395
                $bankstatic=new Account($this->db);
3396
                $bankstatic->fetch($selected);
3397
                print $bankstatic->getNomUrl(1);
3398
            } else {
3399
                print "&nbsp;";
3400
            }
3401
        }
3402
    }
3403
3404
    /**
3405
     *    Return list of categories having choosed type
3406
     *
3407
     *    @param	string|int	$type				Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated.
3408
     *    @param    string		$selected    		Id of category preselected or 'auto' (autoselect category if there is only one element)
3409
     *    @param    string		$htmlname			HTML field name
3410
     *    @param    int			$maxlength      	Maximum length for labels
3411
     *    @param    int			$excludeafterid 	Exclude all categories after this leaf in category tree.
3412
     *    @param	int			$outputmode			0=HTML select string, 1=Array
3413
     *    @return	string
3414
     *    @see select_categories
3415
     */
3416
    function select_all_categories($type, $selected='', $htmlname="parent", $maxlength=64, $excludeafterid=0, $outputmode=0)
3417
    {
3418
        global $conf, $langs;
3419
        $langs->load("categories");
3420
3421
		include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
3422
3423
		// For backward compatibility
3424
		if (is_numeric($type))
3425
		{
3426
		    dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING);
3427
		}
3428
3429
		if ($type === Categorie::TYPE_BANK_LINE)
3430
		{
3431
		    // TODO Move this into common category feature
3432
		    $categids=array();
3433
		    $sql = "SELECT c.label, c.rowid";
3434
		    $sql.= " FROM ".MAIN_DB_PREFIX."bank_categ as c";
3435
		    $sql.= " WHERE entity = ".$conf->entity;
3436
		    $sql.= " ORDER BY c.label";
3437
		    $result = $this->db->query($sql);
3438
		    if ($result)
3439
		    {
3440
		        $num = $this->db->num_rows($result);
3441
		        $i = 0;
3442
		        while ($i < $num)
3443
		        {
3444
		            $objp = $this->db->fetch_object($result);
3445
		            if ($objp) $cate_arbo[$objp->rowid]=array('id'=>$objp->rowid, 'fulllabel'=>$objp->label);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$cate_arbo was never initialized. Although not strictly required by PHP, it is generally a good practice to add $cate_arbo = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
3446
		            $i++;
3447
		        }
3448
		        $this->db->free($result);
3449
		    }
3450
		    else dol_print_error($this->db);
3451
		}
3452
		else
3453
		{
3454
            $cat = new Categorie($this->db);
3455
            $cate_arbo = $cat->get_full_arbo($type, $excludeafterid);
3456
		}
3457
3458
        $output = '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">';
3459
		$outarray=array();
3460
        if (is_array($cate_arbo))
3461
        {
3462
            if (! count($cate_arbo)) $output.= '<option value="-1" disabled>'.$langs->trans("NoCategoriesDefined").'</option>';
3463
            else
3464
            {
3465
                $output.= '<option value="-1">&nbsp;</option>';
3466
                foreach($cate_arbo as $key => $value)
3467
                {
3468
                    if ($cate_arbo[$key]['id'] == $selected || ($selected == 'auto' && count($cate_arbo) == 1))
0 ignored issues
show
Bug introduced by
The variable $cate_arbo does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
3469
                    {
3470
                        $add = 'selected ';
3471
                    }
3472
                    else
3473
                    {
3474
                        $add = '';
3475
                    }
3476
                    $output.= '<option '.$add.'value="'.$cate_arbo[$key]['id'].'">'.dol_trunc($cate_arbo[$key]['fulllabel'],$maxlength,'middle').'</option>';
3477
3478
					$outarray[$cate_arbo[$key]['id']] = $cate_arbo[$key]['fulllabel'];
3479
                }
3480
            }
3481
        }
3482
        $output.= '</select>';
3483
        $output.= "\n";
3484
3485
		if ($outputmode) return $outarray;
3486
		return $output;
3487
    }
3488
3489
    /**
3490
     *     Show a confirmation HTML form or AJAX popup
3491
     *
3492
     *     @param	string		$page        	   	Url of page to call if confirmation is OK
3493
     *     @param	string		$title       	   	Title
3494
     *     @param	string		$question    	   	Question
3495
     *     @param 	string		$action      	   	Action
3496
     *	   @param	array		$formquestion	   	An array with forms complementary inputs
3497
     * 	   @param	string		$selectedchoice		"" or "no" or "yes"
3498
     * 	   @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
3499
     *     @param	int			$height          	Force height of box
3500
     *     @param	int			$width				Force width of box
3501
     *     @return 	void
3502
     *     @deprecated
3503
     *     @see formconfirm()
3504
     */
3505
    function form_confirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=170, $width=500)
3506
    {
3507
        print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width);
3508
    }
3509
3510
    /**
3511
     *     Show a confirmation HTML form or AJAX popup.
3512
     *     Easiest way to use this is with useajax=1.
3513
     *     If you use useajax='xxx', you must also add jquery code to trigger opening of box (with correct parameters)
3514
     *     just after calling this method. For example:
3515
     *       print '<script type="text/javascript">'."\n";
3516
     *       print 'jQuery(document).ready(function() {'."\n";
3517
     *       print 'jQuery(".xxxlink").click(function(e) { jQuery("#aparamid").val(jQuery(this).attr("rel")); jQuery("#dialog-confirm-xxx").dialog("open"); return false; });'."\n";
3518
     *       print '});'."\n";
3519
     *       print '</script>'."\n";
3520
     *
3521
     *     @param  	string		$page        	   	Url of page to call if confirmation is OK
3522
     *     @param	string		$title       	   	Title
3523
     *     @param	string		$question    	   	Question
3524
     *     @param 	string		$action      	   	Action
3525
     *	   @param  	array		$formquestion	   	An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , ))
3526
     * 	   @param  	string		$selectedchoice  	"" or "no" or "yes"
3527
     * 	   @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
3528
     *     @param  	int			$height          	Force height of box
3529
     *     @param	int			$width				Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones.
3530
     *     @return 	string      	    			HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form
3531
     */
3532
    function formconfirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=200, $width=500)
3533
    {
3534
        global $langs,$conf;
3535
        global $useglobalvars;
3536
3537
        $more='';
3538
        $formconfirm='';
3539
        $inputok=array();
3540
        $inputko=array();
3541
3542
        // Clean parameters
3543
        $newselectedchoice=empty($selectedchoice)?"no":$selectedchoice;
3544
        if ($conf->browser->layout == 'phone') $width='95%';
3545
3546
        if (is_array($formquestion) && ! empty($formquestion))
3547
        {
3548
        	// First add hidden fields and value
3549
        	foreach ($formquestion as $key => $input)
3550
            {
3551
                if (is_array($input) && ! empty($input))
3552
                {
3553
                	if ($input['type'] == 'hidden')
3554
                    {
3555
                        $more.='<input type="hidden" id="'.$input['name'].'" name="'.$input['name'].'" value="'.dol_escape_htmltag($input['value']).'">'."\n";
3556
                    }
3557
                }
3558
            }
3559
3560
        	// Now add questions
3561
            $more.='<table class="paddingtopbottomonly" width="100%">'."\n";
3562
            $more.='<tr><td colspan="3">'.(! empty($formquestion['text'])?$formquestion['text']:'').'</td></tr>'."\n";
3563
            foreach ($formquestion as $key => $input)
3564
            {
3565
                if (is_array($input) && ! empty($input))
3566
                {
3567
                	$size=(! empty($input['size'])?' size="'.$input['size'].'"':'');
3568
3569
                    if ($input['type'] == 'text')
3570
                    {
3571
                        $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="text" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n";
3572
                    }
3573
                    else if ($input['type'] == 'password')
3574
                    {
3575
                        $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="password" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n";
3576
                    }
3577
                    else if ($input['type'] == 'select')
3578
                    {
3579
                        $more.='<tr><td>';
3580
                        if (! empty($input['label'])) $more.=$input['label'].'</td><td valign="top" colspan="2" align="left">';
3581
                        $more.=$this->selectarray($input['name'],$input['values'],$input['default'],1);
3582
                        $more.='</td></tr>'."\n";
3583
                    }
3584
                    else if ($input['type'] == 'checkbox')
3585
                    {
3586
                        $more.='<tr>';
3587
                        $more.='<td>'.$input['label'].' </td><td align="left">';
3588
                        $more.='<input type="checkbox" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"';
3589
                        if (! is_bool($input['value']) && $input['value'] != 'false') $more.=' checked';
3590
                        if (is_bool($input['value']) && $input['value']) $more.=' checked';
3591
                        if (isset($input['disabled'])) $more.=' disabled';
3592
                        $more.=' /></td>';
3593
                        $more.='<td align="left">&nbsp;</td>';
3594
                        $more.='</tr>'."\n";
3595
                    }
3596
                    else if ($input['type'] == 'radio')
3597
                    {
3598
                        $i=0;
3599
                        foreach($input['values'] as $selkey => $selval)
3600
                        {
3601
                            $more.='<tr>';
3602
                            if ($i==0) $more.='<td class="tdtop">'.$input['label'].'</td>';
3603
                            else $more.='<td>&nbsp;</td>';
3604
                            $more.='<td width="20"><input type="radio" class="flat" id="'.$input['name'].'" name="'.$input['name'].'" value="'.$selkey.'"';
3605
                            if ($input['disabled']) $more.=' disabled';
3606
                            $more.=' /></td>';
3607
                            $more.='<td align="left">';
3608
                            $more.=$selval;
3609
                            $more.='</td></tr>'."\n";
3610
                            $i++;
3611
                        }
3612
                    }
3613
					else if ($input['type'] == 'date')
3614
					{
3615
						$more.='<tr><td>'.$input['label'].'</td>';
3616
						$more.='<td colspan="2" align="left">';
3617
						$more.=$this->select_date($input['value'],$input['name'],0,0,0,'',1,0,1);
3618
						$more.='</td></tr>'."\n";
3619
						$formquestion[] = array('name'=>$input['name'].'day');
3620
						$formquestion[] = array('name'=>$input['name'].'month');
3621
						$formquestion[] = array('name'=>$input['name'].'year');
3622
						$formquestion[] = array('name'=>$input['name'].'hour');
3623
						$formquestion[] = array('name'=>$input['name'].'min');
3624
					}
3625
                    else if ($input['type'] == 'other')
3626
                    {
3627
                        $more.='<tr><td>';
3628
                        if (! empty($input['label'])) $more.=$input['label'].'</td><td colspan="2" align="left">';
3629
                        $more.=$input['value'];
3630
                        $more.='</td></tr>'."\n";
3631
                    }
3632
                }
3633
            }
3634
            $more.='</table>'."\n";
3635
        }
3636
3637
		// JQUI method dialog is broken with jmobile, we use standard HTML.
3638
		// 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
3639
		// See page product/card.php for example
3640
        if (! empty($conf->dol_use_jmobile)) $useajax=0;
3641
		if (empty($conf->use_javascript_ajax)) $useajax=0;
3642
3643
        if ($useajax)
3644
        {
3645
            $autoOpen=true;
3646
            $dialogconfirm='dialog-confirm';
3647
            $button='';
3648
            if (! is_numeric($useajax))
3649
            {
3650
                $button=$useajax;
3651
                $useajax=1;
3652
                $autoOpen=false;
3653
                $dialogconfirm.='-'.$button;
3654
            }
3655
            $pageyes=$page.(preg_match('/\?/',$page)?'&':'?').'action='.$action.'&confirm=yes';
3656
            $pageno=($useajax == 2 ? $page.(preg_match('/\?/',$page)?'&':'?').'confirm=no':'');
3657
            // Add input fields into list of fields to read during submit (inputok and inputko)
3658
            if (is_array($formquestion))
3659
            {
3660
                foreach ($formquestion as $key => $input)
3661
                {
3662
                	//print "xx ".$key." rr ".is_array($input)."<br>\n";
3663
                    if (is_array($input) && isset($input['name'])) array_push($inputok,$input['name']);
3664
                    if (isset($input['inputko']) && $input['inputko'] == 1) array_push($inputko,$input['name']);
3665
                }
3666
            }
3667
			// Show JQuery confirm box. Note that global var $useglobalvars is used inside this template
3668
            $formconfirm.= '<div id="'.$dialogconfirm.'" title="'.dol_escape_htmltag($title).'" style="display: none;">';
3669
            if (! empty($more)) {
3670
            	$formconfirm.= '<div class="confirmquestions">'.$more.'</div>';
3671
            }
3672
            $formconfirm.= ($question ? '<div class="confirmmessage">'.img_help('','').' '.$question . '</div>': '');
3673
            $formconfirm.= '</div>'."\n";
3674
3675
            $formconfirm.= "\n<!-- begin ajax form_confirm page=".$page." -->\n";
3676
            $formconfirm.= '<script type="text/javascript">'."\n";
3677
            $formconfirm.= 'jQuery(document).ready(function() {
3678
            $(function() {
3679
            	$( "#'.$dialogconfirm.'" ).dialog(
3680
            	{
3681
                    autoOpen: '.($autoOpen ? "true" : "false").',';
3682
            		if ($newselectedchoice == 'no')
3683
            		{
3684
						$formconfirm.='
3685
						open: function() {
3686
            				$(this).parent().find("button.ui-button:eq(2)").focus();
3687
						},';
3688
            		}
3689
        			$formconfirm.='
3690
                    resizable: false,
3691
                    height: "'.$height.'",
3692
                    width: "'.$width.'",
3693
                    modal: true,
3694
                    closeOnEscape: false,
3695
                    buttons: {
3696
                        "'.dol_escape_js($langs->transnoentities("Yes")).'": function() {
3697
                        	var options="";
3698
                        	var inputok = '.json_encode($inputok).';
3699
                         	var pageyes = "'.dol_escape_js(! empty($pageyes)?$pageyes:'').'";
3700
                         	if (inputok.length>0) {
3701
                         		$.each(inputok, function(i, inputname) {
3702
                         			var more = "";
3703
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3704
                         		    if ($("#" + inputname).attr("type") == "radio") { more = ":checked"; }
3705
                         			var inputvalue = $("#" + inputname + more).val();
3706
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3707
                         			options += "&" + inputname + "=" + inputvalue;
3708
                         		});
3709
                         	}
3710
                         	var urljump = pageyes + (pageyes.indexOf("?") < 0 ? "?" : "") + options;
3711
                         	//alert(urljump);
3712
            				if (pageyes.length > 0) { location.href = urljump; }
3713
                            $(this).dialog("close");
3714
                        },
3715
                        "'.dol_escape_js($langs->transnoentities("No")).'": function() {
3716
                        	var options = "";
3717
                         	var inputko = '.json_encode($inputko).';
3718
                         	var pageno="'.dol_escape_js(! empty($pageno)?$pageno:'').'";
3719
                         	if (inputko.length>0) {
3720
                         		$.each(inputko, function(i, inputname) {
3721
                         			var more = "";
3722
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3723
                         			var inputvalue = $("#" + inputname + more).val();
3724
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3725
                         			options += "&" + inputname + "=" + inputvalue;
3726
                         		});
3727
                         	}
3728
                         	var urljump=pageno + (pageno.indexOf("?") < 0 ? "?" : "") + options;
3729
                         	//alert(urljump);
3730
            				if (pageno.length > 0) { location.href = urljump; }
3731
                            $(this).dialog("close");
3732
                        }
3733
                    }
3734
                }
3735
                );
3736
3737
            	var button = "'.$button.'";
3738
            	if (button.length > 0) {
3739
                	$( "#" + button ).click(function() {
3740
                		$("#'.$dialogconfirm.'").dialog("open");
3741
        			});
3742
                }
3743
            });
3744
            });
3745
            </script>';
3746
            $formconfirm.= "<!-- end ajax form_confirm -->\n";
3747
        }
3748
        else
3749
        {
3750
        	$formconfirm.= "\n<!-- begin form_confirm page=".$page." -->\n";
3751
3752
            $formconfirm.= '<form method="POST" action="'.$page.'" class="notoptoleftroright">'."\n";
3753
            $formconfirm.= '<input type="hidden" name="action" value="'.$action.'">'."\n";
3754
            $formconfirm.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'."\n";
3755
3756
            $formconfirm.= '<table width="100%" class="valid">'."\n";
3757
3758
            // Line title
3759
            $formconfirm.= '<tr class="validtitre"><td class="validtitre" colspan="3">'.img_picto('','recent').' '.$title.'</td></tr>'."\n";
3760
3761
            // Line form fields
3762
            if ($more)
3763
            {
3764
                $formconfirm.='<tr class="valid"><td class="valid" colspan="3">'."\n";
3765
                $formconfirm.=$more;
3766
                $formconfirm.='</td></tr>'."\n";
3767
            }
3768
3769
            // Line with question
3770
            $formconfirm.= '<tr class="valid">';
3771
            $formconfirm.= '<td class="valid">'.$question.'</td>';
3772
            $formconfirm.= '<td class="valid">';
3773
            $formconfirm.= $this->selectyesno("confirm",$newselectedchoice);
3774
            $formconfirm.= '</td>';
3775
            $formconfirm.= '<td class="valid" align="center"><input class="button valignmiddle" type="submit" value="'.$langs->trans("Validate").'"></td>';
3776
            $formconfirm.= '</tr>'."\n";
3777
3778
            $formconfirm.= '</table>'."\n";
3779
3780
            $formconfirm.= "</form>\n";
3781
            $formconfirm.= '<br>';
3782
3783
            $formconfirm.= "<!-- end form_confirm -->\n";
3784
        }
3785
3786
        return $formconfirm;
3787
    }
3788
3789
3790
    /**
3791
     *    Show a form to select a project
3792
     *
3793
     *    @param	int		$page        		Page
3794
     *    @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)
3795
     *    @param    int		$selected    		Id pre-selected project
3796
     *    @param    string	$htmlname    		Name of select field
3797
     *    @param	int		$discard_closed		Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable)
3798
     *    @param	int		$maxlength			Max length
3799
     *    @param	int		$forcefocus			Force focus on field (works with javascript only)
3800
     *    @param    int     $nooutput           No print is done. String is returned.
3801
     *    @return	string                      Return html content
3802
     */
3803
    function form_project($page, $socid, $selected='', $htmlname='projectid', $discard_closed=0, $maxlength=20, $forcefocus=0, $nooutput=0)
3804
    {
3805
        global $langs;
3806
3807
        require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
3808
        require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
3809
3810
        $out='';
3811
3812
        $formproject=new FormProjets($this->db);
3813
3814
        $langs->load("project");
3815
        if ($htmlname != "none")
3816
        {
3817
            $out.="\n";
3818
            $out.='<form method="post" action="'.$page.'">';
3819
            $out.='<input type="hidden" name="action" value="classin">';
3820
            $out.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3821
            $out.=$formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0, '', 1);
3822
            $out.='<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
3823
            $out.='</form>';
3824
        }
3825
        else
3826
        {
3827
            if ($selected)
3828
            {
3829
                $projet = new Project($this->db);
3830
                $projet->fetch($selected);
3831
                //print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>';
3832
                $out.=$projet->getNomUrl(0,'',1);
3833
            }
3834
            else
3835
            {
3836
                $out.="&nbsp;";
3837
            }
3838
        }
3839
3840
        if (empty($nooutput))
3841
        {
3842
            print $out;
3843
            return '';
3844
        }
3845
        return $out;
3846
    }
3847
3848
    /**
3849
     *	Show a form to select payment conditions
3850
     *
3851
     *  @param	int		$page        	Page
3852
     *  @param  string	$selected    	Id condition pre-selectionne
3853
     *  @param  string	$htmlname    	Name of select html field
3854
     *	@param	int		$addempty		Add empty entry
3855
     *  @return	void
3856
     */
3857
    function form_conditions_reglement($page, $selected='', $htmlname='cond_reglement_id', $addempty=0)
3858
    {
3859
        global $langs;
3860
        if ($htmlname != "none")
3861
        {
3862
            print '<form method="post" action="'.$page.'">';
3863
            print '<input type="hidden" name="action" value="setconditions">';
3864
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3865
            $this->select_conditions_paiements($selected,$htmlname,-1,$addempty);
3866
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3867
            print '</form>';
3868
        }
3869
        else
3870
        {
3871
            if ($selected)
3872
            {
3873
                $this->load_cache_conditions_paiements();
3874
                print $this->cache_conditions_paiements[$selected]['label'];
3875
            } else {
3876
                print "&nbsp;";
3877
            }
3878
        }
3879
    }
3880
3881
    /**
3882
     *  Show a form to select a delivery delay
3883
     *
3884
     *  @param  int		$page        	Page
3885
     *  @param  string	$selected    	Id condition pre-selectionne
3886
     *  @param  string	$htmlname    	Name of select html field
3887
     *	@param	int		$addempty		Ajoute entree vide
3888
     *  @return	void
3889
     */
3890
    function form_availability($page, $selected='', $htmlname='availability', $addempty=0)
3891
    {
3892
        global $langs;
3893
        if ($htmlname != "none")
3894
        {
3895
            print '<form method="post" action="'.$page.'">';
3896
            print '<input type="hidden" name="action" value="setavailability">';
3897
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3898
            $this->selectAvailabilityDelay($selected,$htmlname,-1,$addempty);
3899
            print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
3900
            print '</form>';
3901
        }
3902
        else
3903
        {
3904
            if ($selected)
3905
            {
3906
                $this->load_cache_availability();
3907
                print $this->cache_availability[$selected]['label'];
3908
            } else {
3909
                print "&nbsp;";
3910
            }
3911
        }
3912
    }
3913
3914
    /**
3915
	 *	Output HTML form to select list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
3916
	 *  List found into table c_input_reason loaded by loadCacheInputReason
3917
     *
3918
     *  @param  string	$page        	Page
3919
     *  @param  string	$selected    	Id condition pre-selectionne
3920
     *  @param  string	$htmlname    	Name of select html field
3921
     *	@param	int		$addempty		Add empty entry
3922
     *  @return	void
3923
     */
3924
    function formInputReason($page, $selected='', $htmlname='demandreason', $addempty=0)
3925
    {
3926
        global $langs;
3927
        if ($htmlname != "none")
3928
        {
3929
            print '<form method="post" action="'.$page.'">';
3930
            print '<input type="hidden" name="action" value="setdemandreason">';
3931
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3932
            $this->selectInputReason($selected,$htmlname,-1,$addempty);
3933
            print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
3934
            print '</form>';
3935
        }
3936
        else
3937
        {
3938
            if ($selected)
3939
            {
3940
                $this->loadCacheInputReason();
3941
                foreach ($this->cache_demand_reason as $key => $val)
3942
                {
3943
                    if ($val['id'] == $selected)
3944
                    {
3945
                        print $val['label'];
3946
                        break;
3947
                    }
3948
                }
3949
            } else {
3950
                print "&nbsp;";
3951
            }
3952
        }
3953
    }
3954
3955
    /**
3956
     *    Show a form + html select a date
3957
     *
3958
     *    @param	string		$page        	Page
3959
     *    @param	string		$selected    	Date preselected
3960
     *    @param    string		$htmlname    	Html name of date input fields or 'none'
3961
     *    @param    int			$displayhour 	Display hour selector
3962
     *    @param    int			$displaymin		Display minutes selector
3963
     *    @param	int			$nooutput		1=No print output, return string
3964
     *    @return	string
3965
     *    @see		select_date
3966
     */
3967
    function form_date($page, $selected, $htmlname, $displayhour=0, $displaymin=0, $nooutput=0)
3968
    {
3969
        global $langs;
3970
3971
        $ret='';
3972
3973
        if ($htmlname != "none")
3974
        {
3975
            $ret.='<form method="post" action="'.$page.'" name="form'.$htmlname.'">';
3976
            $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">';
3977
            $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3978
            $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
3979
            $ret.='<tr><td>';
3980
            $ret.=$this->select_date($selected,$htmlname,$displayhour,$displaymin,1,'form'.$htmlname,1,0,1);
3981
            $ret.='</td>';
3982
            $ret.='<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
3983
            $ret.='</tr></table></form>';
3984
        }
3985
        else
3986
        {
3987
        	if ($displayhour) $ret.=dol_print_date($selected,'dayhour');
3988
        	else $ret.=dol_print_date($selected,'day');
3989
        }
3990
3991
        if (empty($nooutput)) print $ret;
3992
        return $ret;
3993
    }
3994
3995
3996
    /**
3997
     *  Show a select form to choose a user
3998
     *
3999
     *  @param	string	$page        	Page
4000
     *  @param  string	$selected    	Id of user preselected
4001
     *  @param  string	$htmlname    	Name of input html field. If 'none', we just output the user link.
4002
     *  @param  array	$exclude		List of users id to exclude
4003
     *  @param  array	$include        List of users id to include
4004
     *  @return	void
4005
     */
4006
    function form_users($page, $selected='', $htmlname='userid', $exclude='', $include='')
4007
    {
4008
        global $langs;
4009
4010
        if ($htmlname != "none")
4011
        {
4012
            print '<form method="POST" action="'.$page.'" name="form'.$htmlname.'">';
4013
            print '<input type="hidden" name="action" value="set'.$htmlname.'">';
4014
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4015
            print $this->select_dolusers($selected,$htmlname,1,$exclude,0,$include);
4016
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4017
            print '</form>';
4018
        }
4019
        else
4020
		{
4021
            if ($selected)
4022
            {
4023
                require_once DOL_DOCUMENT_ROOT .'/user/class/user.class.php';
4024
                $theuser=new User($this->db);
4025
                $theuser->fetch($selected);
4026
                print $theuser->getNomUrl(1);
4027
            } else {
4028
                print "&nbsp;";
4029
            }
4030
        }
4031
    }
4032
4033
4034
    /**
4035
     *    Show form with payment mode
4036
     *
4037
     *    @param	string	$page        	Page
4038
     *    @param    int		$selected    	Id mode pre-selectionne
4039
     *    @param    string	$htmlname    	Name of select html field
4040
     *    @param  	string	$filtertype		To filter on field type in llx_c_paiement (array('code'=>xx,'label'=>zz))
4041
     *    @param    int     $active         Active or not, -1 = all
4042
     *    @return	void
4043
     */
4044
    function form_modes_reglement($page, $selected='', $htmlname='mode_reglement_id', $filtertype='', $active=1)
4045
    {
4046
        global $langs;
4047
        if ($htmlname != "none")
4048
        {
4049
            print '<form method="POST" action="'.$page.'">';
4050
            print '<input type="hidden" name="action" value="setmode">';
4051
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4052
            $this->select_types_paiements($selected,$htmlname,$filtertype,0,0,0,0,$active);
4053
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4054
            print '</form>';
4055
        }
4056
        else
4057
        {
4058
            if ($selected)
4059
            {
4060
                $this->load_cache_types_paiements();
4061
                print $this->cache_types_paiements[$selected]['label'];
4062
            } else {
4063
                print "&nbsp;";
4064
            }
4065
        }
4066
    }
4067
4068
	/**
4069
     *    Show form with multicurrency code
4070
     *
4071
     *    @param	string	$page        	Page
4072
     *    @param    string	$selected    	code pre-selectionne
4073
     *    @param    string	$htmlname    	Name of select html field
4074
     *    @return	void
4075
     */
4076
    function form_multicurrency_code($page, $selected='', $htmlname='multicurrency_code')
4077
    {
4078
        global $langs;
4079
        if ($htmlname != "none")
4080
        {
4081
            print '<form method="POST" action="'.$page.'">';
4082
            print '<input type="hidden" name="action" value="setmulticurrencycode">';
4083
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4084
            print $this->selectMultiCurrency($selected, $htmlname, 0);
4085
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4086
            print '</form>';
4087
        }
4088
        else
4089
        {
4090
        	dol_include_once('/core/lib/company.lib.php');
4091
        	print !empty($selected) ? currency_name($selected,1) : '&nbsp;';
4092
        }
4093
    }
4094
4095
	/**
4096
     *    Show form with multicurrency rate
4097
     *
4098
     *    @param	string	$page        	Page
4099
     *    @param    double	$rate	    	Current rate
4100
     *    @param    string	$htmlname    	Name of select html field
4101
     *    @param    string  $currency       Currency code to explain the rate
4102
     *    @return	void
4103
     */
4104
    function form_multicurrency_rate($page, $rate='', $htmlname='multicurrency_tx', $currency='')
4105
    {
4106
        global $langs, $mysoc, $conf;
4107
4108
        if ($htmlname != "none")
4109
        {
4110
            print '<form method="POST" action="'.$page.'">';
4111
            print '<input type="hidden" name="action" value="setmulticurrencyrate">';
4112
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4113
            print '<input type="text" name="'.$htmlname.'" value="'.(!empty($rate) ? price($rate) : 1).'" size="10" /> ';
4114
			print '<select name="calculation_mode">';
4115
			print '<option value="1">'.$currency.' > '.$conf->currency.'</option>';
4116
			print '<option value="2">'.$conf->currency.' > '.$currency.'</option>';
4117
			print '</select> ';
4118
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4119
            print '</form>';
4120
        }
4121
        else
4122
        {
4123
        	if (! empty($rate))
4124
        	{
4125
        	    print price($rate, 1, $langs, 1, 0);
4126
        	    if ($currency && $rate != 1) print ' &nbsp; ('.price($rate, 1, $langs, 1, 0).' '.$currency.' = 1 '.$conf->currency.')';
4127
        	}
4128
        	else
4129
        	{
4130
        	    print 1;
4131
        	}
4132
        }
4133
    }
4134
4135
4136
    /**
4137
     *	Show a select box with available absolute discounts
4138
     *
4139
     *  @param  string	$page        	Page URL where form is shown
4140
     *  @param  int		$selected    	Value pre-selected
4141
     *	@param  string	$htmlname    	Name of SELECT component. If 'none', not changeable. Example 'remise_id'.
4142
     *	@param	int		$socid			Third party id
4143
     * 	@param	float	$amount			Total amount available
4144
     * 	@param	string	$filter			SQL filter on discounts
4145
     * 	@param	int		$maxvalue		Max value for lines that can be selected
4146
     *  @param  string	$more           More string to add
4147
     *  @param  int     $hidelist       1=Hide list
4148
     *  @return	void
4149
     */
4150
    function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0)
4151
    {
4152
        global $conf,$langs;
4153
        if ($htmlname != "none")
4154
        {
4155
            print '<form method="post" action="'.$page.'">';
4156
            print '<input type="hidden" name="action" value="setabsolutediscount">';
4157
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4158
            print '<div class="inline-block">';
4159
            if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
4160
            {
4161
                if (! $filter || $filter=="fk_facture_source IS NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));    // If we want deposit to be substracted to payments only and not to total of final invoice
4162
                else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
4163
            }
4164
            else
4165
            {
4166
                if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));
4167
                else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
4168
            }
4169
            if (empty($hidelist)) print ': ';
4170
            print '</div>';
4171
            if (empty($hidelist))
4172
            {
4173
                print '<div class="inline-block" style="padding-right: 10px">';
4174
                $newfilter='fk_facture IS NULL AND fk_facture_line IS NULL';	// Remises disponibles
4175
                if ($filter) $newfilter.=' AND ('.$filter.')';
4176
                $nbqualifiedlines=$this->select_remises($selected,$htmlname,$newfilter,$socid,$maxvalue);
4177
                if ($nbqualifiedlines > 0)
4178
                {
4179
                    print ' &nbsp; <input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("UseLine")).'"';
4180
                    if ($filter && $filter != "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')") print ' title="'.$langs->trans("UseCreditNoteInInvoicePayment").'"';
4181
                    print '>';
4182
                }
4183
                print '</div>';
4184
            }
4185
            if ($more)
4186
            {
4187
                print '<div class="inline-block">';
4188
                print $more;
4189
                print '</div>';
4190
            }
4191
            print '</form>';
4192
        }
4193
        else
4194
        {
4195
            if ($selected)
4196
            {
4197
                print $selected;
4198
            }
4199
            else
4200
            {
4201
                print "0";
4202
            }
4203
        }
4204
    }
4205
4206
4207
    /**
4208
     *    Show forms to select a contact
4209
     *
4210
     *    @param	string		$page        	Page
4211
     *    @param	Societe		$societe		Filter on third party
4212
     *    @param    int			$selected    	Id contact pre-selectionne
4213
     *    @param    string		$htmlname    	Name of HTML select. If 'none', we just show contact link.
4214
     *    @return	void
4215
     */
4216
    function form_contacts($page, $societe, $selected='', $htmlname='contactid')
4217
    {
4218
        global $langs, $conf;
4219
4220
        if ($htmlname != "none")
4221
        {
4222
            print '<form method="post" action="'.$page.'">';
4223
            print '<input type="hidden" name="action" value="set_contact">';
4224
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4225
            print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
4226
            print '<tr><td>';
4227
            $num=$this->select_contacts($societe->id, $selected, $htmlname);
4228
            if ($num==0)
4229
            {
4230
            	$addcontact = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress"));
4231
                print '<a href="'.DOL_URL_ROOT.'/contact/card.php?socid='.$societe->id.'&amp;action=create&amp;backtoreferer=1">'.$addcontact.'</a>';
4232
            }
4233
            print '</td>';
4234
            print '<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
4235
            print '</tr></table></form>';
4236
        }
4237
        else
4238
        {
4239
            if ($selected)
4240
            {
4241
                require_once DOL_DOCUMENT_ROOT .'/contact/class/contact.class.php';
4242
                $contact=new Contact($this->db);
4243
                $contact->fetch($selected);
4244
                print $contact->getFullName($langs);
4245
            } else {
4246
                print "&nbsp;";
4247
            }
4248
        }
4249
    }
4250
4251
    /**
4252
     *  Output html select to select thirdparty
4253
     *
4254
     *  @param	string	$page       	Page
4255
     *  @param  string	$selected   	Id preselected
4256
     *  @param  string	$htmlname		Name of HTML select
4257
     *  @param  string	$filter         optional filters criteras
4258
     *	@param	int		$showempty		Add an empty field
4259
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
4260
     * 	@param	int		$forcecombo		Force to use combo box
4261
     *  @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')))
4262
     *  @return	void
4263
     */
4264
    function form_thirdparty($page, $selected='', $htmlname='socid', $filter='',$showempty=0, $showtype=0, $forcecombo=0, $events=array())
4265
    {
4266
        global $langs;
4267
4268
        if ($htmlname != "none")
4269
        {
4270
            print '<form method="post" action="'.$page.'">';
4271
            print '<input type="hidden" name="action" value="set_thirdparty">';
4272
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4273
            print $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events);
4274
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4275
            print '</form>';
4276
        }
4277
        else
4278
        {
4279
            if ($selected)
4280
            {
4281
                require_once DOL_DOCUMENT_ROOT .'/societe/class/societe.class.php';
4282
                $soc = new Societe($this->db);
4283
                $soc->fetch($selected);
4284
                print $soc->getNomUrl($langs);
4285
            }
4286
            else
4287
            {
4288
                print "&nbsp;";
4289
            }
4290
        }
4291
    }
4292
4293
    /**
4294
     *    Retourne la liste des devises, dans la langue de l'utilisateur
4295
     *
4296
     *    @param	string	$selected    preselected currency code
4297
     *    @param    string	$htmlname    name of HTML select list
4298
     *    @return	void
4299
     */
4300
    function select_currency($selected='',$htmlname='currency_id')
4301
    {
4302
        print $this->selectCurrency($selected,$htmlname);
4303
    }
4304
4305
    /**
4306
     *  Retourne la liste des devises, dans la langue de l'utilisateur
4307
     *
4308
     *  @param	string	$selected    preselected currency code
4309
     *  @param  string	$htmlname    name of HTML select list
4310
     * 	@return	string
4311
     */
4312
	function selectCurrency($selected='',$htmlname='currency_id')
4313
	{
4314
		global $conf,$langs,$user;
4315
4316
		$langs->loadCacheCurrencies('');
4317
4318
		$out='';
4319
4320
		if ($selected=='euro' || $selected=='euros') $selected='EUR';   // Pour compatibilite
4321
4322
		$out.= '<select class="flat maxwidth200onsmartphone minwidth300" name="'.$htmlname.'" id="'.$htmlname.'">';
4323
		foreach ($langs->cache_currencies as $code_iso => $currency)
4324
		{
4325
			if ($selected && $selected == $code_iso)
4326
			{
4327
				$out.= '<option value="'.$code_iso.'" selected>';
4328
			}
4329
			else
4330
			{
4331
				$out.= '<option value="'.$code_iso.'">';
4332
			}
4333
			$out.= $currency['label'];
4334
			$out.= ' ('.$langs->getCurrencySymbol($code_iso).')';
4335
			$out.= '</option>';
4336
		}
4337
		$out.= '</select>';
4338
		if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
4339
4340
		// Make select dynamic
4341
		include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4342
		$out .= ajax_combobox($htmlname);
4343
4344
		return $out;
4345
	}
4346
4347
	/**
4348
     *	Return array of currencies in user language
4349
	 *
4350
     *  @param	string	$selected    preselected currency code
4351
     *  @param  string	$htmlname    name of HTML select list
4352
     *  @param  integer	$useempty    1=Add empty line
4353
     * 	@return	string
4354
     */
4355
    function selectMultiCurrency($selected='', $htmlname='multicurrency_code', $useempty=0)
4356
    {
4357
        global $db,$conf,$langs,$user;
4358
4359
        $langs->loadCacheCurrencies('');        // Load ->cache_currencies
4360
4361
		$TCurrency = array();
4362
4363
		$sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'multicurrency';
4364
		$sql.= " WHERE entity IN ('".getEntity('mutlicurrency', 0)."')";
4365
		$resql = $db->query($sql);
4366
		if ($resql)
4367
		{
4368
			while ($obj = $db->fetch_object($resql)) $TCurrency[$obj->code] = $obj->code;
4369
		}
4370
4371
		$out='';
4372
        $out.= '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">';
4373
		if ($useempty) $out .= '<option value=""></option>';
4374
		// If company current currency not in table, we add it into list. Should always be available.
4375
		if (! in_array($conf->currency, $TCurrency))
4376
		{
4377
		    $TCurrency[$conf->currency] = $conf->currency;
4378
		}
4379
		if (count($TCurrency) > 0)
4380
		{
4381
			foreach ($langs->cache_currencies as $code_iso => $currency)
4382
	        {
4383
	        	if (isset($TCurrency[$code_iso]))
4384
				{
4385
					if (!empty($selected) && $selected == $code_iso) $out.= '<option value="'.$code_iso.'" selected="selected">';
4386
		        	else $out.= '<option value="'.$code_iso.'">';
4387
4388
		        	$out.= $currency['label'];
4389
		        	$out.= ' ('.$langs->getCurrencySymbol($code_iso).')';
4390
		        	$out.= '</option>';
4391
				}
4392
	        }
4393
4394
		}
4395
4396
        $out.= '</select>';
4397
		// Make select dynamic
4398
		include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4399
		$out.= ajax_combobox($htmlname);
4400
4401
        return $out;
4402
    }
4403
4404
    /**
4405
     *	Load into the cache vat rates of a country
4406
     *
4407
     *	@param	string	$country_code		Country code with quotes ("'CA'", or "'CA,IN,...'")
4408
     *	@return	int							Nb of loaded lines, 0 if already loaded, <0 if KO
4409
     */
4410
    function load_cache_vatrates($country_code)
4411
    {
4412
    	global $langs;
4413
4414
    	$num = count($this->cache_vatrates);
4415
    	if ($num > 0) return $num;    // Cache already loaded
4416
4417
        dol_syslog(__METHOD__, LOG_DEBUG);
4418
4419
        $sql  = "SELECT DISTINCT t.rowid, t.code, t.taux, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.recuperableonly";
4420
    	$sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
4421
    	$sql.= " WHERE t.fk_pays = c.rowid";
4422
    	$sql.= " AND t.active > 0";
4423
    	$sql.= " AND c.code IN (".$country_code.")";
4424
    	$sql.= " ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC";
4425
4426
    	$resql=$this->db->query($sql);
4427
    	if ($resql)
4428
    	{
4429
    		$num = $this->db->num_rows($resql);
4430
    		if ($num)
4431
    		{
4432
    			for ($i = 0; $i < $num; $i++)
4433
    			{
4434
    				$obj = $this->db->fetch_object($resql);
4435
    				$this->cache_vatrates[$i]['rowid']	= $obj->rowid;
4436
    				$this->cache_vatrates[$i]['code']	= $obj->code;
4437
    				$this->cache_vatrates[$i]['txtva']	= $obj->taux;
4438
    				$this->cache_vatrates[$i]['nprtva']	= $obj->recuperableonly;
4439
    				$this->cache_vatrates[$i]['localtax1']	    = $obj->localtax1;
4440
    				$this->cache_vatrates[$i]['localtax1_type']	= $obj->localtax1_type;
4441
    				$this->cache_vatrates[$i]['localtax2']	    = $obj->localtax2;
4442
    				$this->cache_vatrates[$i]['localtax2_type']	= $obj->localtax1_type;
4443
4444
    				$this->cache_vatrates[$i]['label']	= $obj->taux.'%'.($obj->code?' ('.$obj->code.')':'');   // Label must contains only 0-9 , . % or *
4445
    				$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
4446
    				$positiverates='';
4447
    				if ($obj->taux) $positiverates.=($positiverates?'/':'').$obj->taux;
4448
    				if ($obj->localtax1) $positiverates.=($positiverates?'/':'').$obj->localtax1;
4449
    				if ($obj->localtax2) $positiverates.=($positiverates?'/':'').$obj->localtax2;
4450
    				if (empty($positiverates)) $positiverates='0';
4451
    				$this->cache_vatrates[$i]['labelpositiverates'] = $positiverates.($obj->code?' ('.$obj->code.')':'');	// Must never be used as key, only label
4452
    			}
4453
4454
    			return $num;
4455
    		}
4456
    		else
4457
    		{
4458
    			$this->error = '<font class="error">'.$langs->trans("ErrorNoVATRateDefinedForSellerCountry",$country_code).'</font>';
4459
    			return -1;
4460
    		}
4461
    	}
4462
    	else
4463
    	{
4464
    		$this->error = '<font class="error">'.$this->db->error().'</font>';
4465
    		return -2;
4466
    	}
4467
    }
4468
4469
    /**
4470
     *  Output an HTML select vat rate.
4471
     *  The name of this function should be selectVat. We keep bad name for compatibility purpose.
4472
     *
4473
     *  @param	string	      $htmlname           Name of HTML select field
4474
     *  @param  float|string  $selectedrate       Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing.
4475
     *  @param  Societe	      $societe_vendeuse   Thirdparty seller
4476
     *  @param  Societe	      $societe_acheteuse  Thirdparty buyer
4477
     *  @param  int		      $idprod             Id product. O if unknown of NA.
4478
     *  @param  int		      $info_bits          Miscellaneous information on line (1 for NPR)
4479
     *  @param  int|string    $type               ''=Unknown, 0=Product, 1=Service (Used if idprod not defined)
4480
     *                  		                  Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle.
4481
     *                  					      Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle.
4482
     *                  					      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.
4483
	 *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle.
4484
	 *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle.
4485
     *                  					      Sinon la TVA proposee par defaut=0. Fin de regle.
4486
     *  @param	bool	     $options_only		  Return HTML options lines only (for ajax treatment)
4487
     *  @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
4488
     *  @return	string
4489
     */
4490
    function load_tva($htmlname='tauxtva', $selectedrate='', $societe_vendeuse='', $societe_acheteuse='', $idprod=0, $info_bits=0, $type='', $options_only=false, $mode=0)
4491
    {
4492
        global $langs,$conf,$mysoc;
4493
4494
        $return='';
4495
4496
        // Define defaultnpr, defaultttx and defaultcode
4497
        $defaultnpr=($info_bits & 0x01);
4498
        $defaultnpr=(preg_match('/\*/',$selectedrate) ? 1 : $defaultnpr);
4499
        $defaulttx=str_replace('*','',$selectedrate);
4500
        $defaultcode='';
4501
        if (preg_match('/\((.*)\)/', $defaulttx, $reg))
4502
        {
4503
            $defaultcode=$reg[1];
4504
            $defaulttx=preg_replace('/\s*\(.*\)/','',$defaulttx);
4505
        }
4506
        //var_dump($selectedrate.'-'.$defaulttx.'-'.$defaultnpr.'-'.$defaultcode);
4507
4508
        // Check parameters
4509
        if (is_object($societe_vendeuse) && ! $societe_vendeuse->country_code)
4510
        {
4511
            if ($societe_vendeuse->id == $mysoc->id)
4512
            {
4513
                $return.= '<font class="error">'.$langs->trans("ErrorYourCountryIsNotDefined").'</div>';
4514
            }
4515
            else
4516
            {
4517
                $return.= '<font class="error">'.$langs->trans("ErrorSupplierCountryIsNotDefined").'</div>';
4518
            }
4519
            return $return;
4520
        }
4521
4522
        //var_dump($societe_acheteuse);
4523
        //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";
4524
        //exit;
4525
4526
        // Define list of countries to use to search VAT rates to show
4527
        // First we defined code_country to use to find list
4528
        if (is_object($societe_vendeuse))
4529
        {
4530
            $code_country="'".$societe_vendeuse->country_code."'";
4531
        }
4532
        else
4533
        {
4534
            $code_country="'".$mysoc->country_code."'";   // Pour compatibilite ascendente
4535
        }
4536
        if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC))    // If option to have vat for end customer for services is on
4537
        {
4538
            if (! $societe_vendeuse->isInEEC() && (! is_object($societe_acheteuse) || ($societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany())))
0 ignored issues
show
Bug introduced by
It seems like $societe_vendeuse is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
4539
            {
4540
                // We also add the buyer
4541
                if (is_numeric($type))
4542
                {
4543
                    if ($type == 1) // We know product is a service
4544
                    {
4545
                        $code_country.=",'".$societe_acheteuse->country_code."'";
4546
                    }
4547
                }
4548
                else if (! $idprod)  // We don't know type of product
4549
                {
4550
                    $code_country.=",'".$societe_acheteuse->country_code."'";
4551
                }
4552
                else
4553
                {
4554
                    $prodstatic=new Product($this->db);
4555
                    $prodstatic->fetch($idprod);
4556
                    if ($prodstatic->type == Product::TYPE_SERVICE)   // We know product is a service
4557
                    {
4558
                        $code_country.=",'".$societe_acheteuse->country_code."'";
4559
                    }
4560
                }
4561
            }
4562
        }
4563
4564
        // Now we get list
4565
        $num = $this->load_cache_vatrates($code_country);   // If no vat defined, return -1 with message into this->error
4566
4567
        if ($num > 0)
4568
        {
4569
        	// Definition du taux a pre-selectionner (si defaulttx non force et donc vaut -1 ou '')
4570
        	if ($defaulttx < 0 || dol_strlen($defaulttx) == 0)
4571
        	{
4572
        	    $tmpthirdparty=new Societe($this->db);
4573
        		$defaulttx=get_default_tva($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod);
0 ignored issues
show
Bug introduced by
It seems like $societe_vendeuse defined by parameter $societe_vendeuse on line 4490 can also be of type string; however, get_default_tva() does only seem to accept object<Societe>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
4574
        		$defaultnpr=get_default_npr($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod);
0 ignored issues
show
Bug introduced by
It seems like $societe_vendeuse defined by parameter $societe_vendeuse on line 4490 can also be of type string; however, get_default_npr() does only seem to accept object<Societe>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
4575
        		if (empty($defaulttx)) $defaultnpr=0;
4576
        	}
4577
4578
        	// Si taux par defaut n'a pu etre determine, on prend dernier de la liste.
4579
        	// Comme ils sont tries par ordre croissant, dernier = plus eleve = taux courant
4580
        	if ($defaulttx < 0 || dol_strlen($defaulttx) == 0)
4581
        	{
4582
        		if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) $defaulttx = $this->cache_vatrates[$num-1]['txtva'];
4583
        		else $defaulttx=($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS == 'none' ? '' : $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS);
4584
        	}
4585
4586
        	// Disabled if seller is not subject to VAT
4587
        	$disabled=false; $title='';
4588
        	if (is_object($societe_vendeuse) && $societe_vendeuse->id == $mysoc->id && $societe_vendeuse->tva_assuj == "0")
4589
        	{
4590
        		$title=' title="'.$langs->trans('VATIsNotUsed').'"';
4591
        		$disabled=true;
4592
        	}
4593
4594
        	if (! $options_only) $return.= '<select class="flat minwidth75imp" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').$title.'>';
4595
4596
        	$selectedfound=false;
4597
        	foreach ($this->cache_vatrates as $rate)
4598
        	{
4599
        		// Keep only 0 if seller is not subject to VAT
4600
        		if ($disabled && $rate['txtva'] != 0) continue;
4601
4602
        		// Define key to use into select list
4603
        		$key = $rate['txtva'];
4604
        		$key.= $rate['nprtva'] ? '*': '';
4605
        		if ($mode > 0 && $rate['code']) $key.=' ('.$rate['code'].')';
4606
        		if ($mode < 0) $key = $rate['rowid'];
4607
4608
        		$return.= '<option value="'.$key.'"';
4609
        		if (! $selectedfound)
4610
        		{
4611
            		if ($defaultcode) // If defaultcode is defined, we used it in priority to select combo option instead of using rate+npr flag
4612
            		{
4613
                        if ($defaultcode == $rate['code'])
4614
                        {
4615
                            $return.= ' selected';
4616
                            $selectedfound=true;
4617
                        }
4618
            		}
4619
            		elseif ($rate['txtva'] == $defaulttx && $rate['nprtva'] == $defaultnpr)
4620
               		{
4621
               		    $return.= ' selected';
4622
               		    $selectedfound=true;
4623
            		}
4624
        		}
4625
        		$return.= '>';
4626
        		//if (! empty($conf->global->MAIN_VAT_SHOW_POSITIVE_RATES))
4627
        		if ($mysoc->country_code == 'IN' || ! empty($conf->global->MAIN_VAT_LABEL_IS_POSITIVE_RATES))
4628
        		{
4629
        			$return.= $rate['labelpositiverates'];
4630
        		}
4631
        		else
4632
        		{
4633
        			$return.= vatrate($rate['label']);
4634
        		}
4635
        		//$return.=($rate['code']?' '.$rate['code']:'');
4636
        		$return.= (empty($rate['code']) && $rate['nprtva']) ? ' *': '';         // We show the *  (old behaviour only if new vat code is not used)
4637
4638
        		$return.= '</option>';
4639
        	}
4640
4641
        	if (! $options_only) $return.= '</select>';
4642
        }
4643
        else
4644
        {
4645
            $return.= $this->error;
4646
        }
4647
4648
        $this->num = $num;
4649
        return $return;
4650
    }
4651
4652
4653
    /**
4654
     *	Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
4655
     *  Fields are preselected with :
4656
     *            	- set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
4657
     *            	- local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
4658
     *            	- Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
4659
     *
4660
     *	@param	timestamp	$set_time 		Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date (emptydate must be 0).
4661
     *	@param	string		$prefix			Prefix for fields name
4662
     *	@param	int			$h				1=Show also hours
4663
     *	@param	int			$m				1=Show also minutes
4664
     *	@param	int			$empty			0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
4665
     *	@param	string		$form_name 		Not used
4666
     *	@param	int			$d				1=Show days, month, years
4667
     * 	@param	int			$addnowlink		Add a link "Now"
4668
     * 	@param	int			$nooutput		Do not output html string but return it
4669
     * 	@param 	int			$disabled		Disable input fields
4670
     *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
4671
     *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another select_date field.
4672
     *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
4673
     * 	@return	string|null						Nothing or string if nooutput is 1
4674
     *  @see	form_date
4675
     */
4676
    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='')
4677
    {
4678
        global $conf,$langs;
4679
4680
        $retstring='';
4681
4682
        if($prefix=='') $prefix='re';
4683
        if($h == '') $h=0;
4684
        if($m == '') $m=0;
4685
        $emptydate=0;
4686
        $emptyhours=0;
4687
    	if ($empty == 1) { $emptydate=1; $emptyhours=1; }
4688
    	if ($empty == 2) { $emptydate=0; $emptyhours=1; }
4689
		$orig_set_time=$set_time;
4690
4691
        if ($set_time === '' && $emptydate == 0)
4692
        {
4693
        	include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
4694
        	$set_time = dol_now('tzuser')-(getServerTimeZoneInt('now')*3600); // set_time must be relative to PHP server timezone
4695
        }
4696
4697
        // Analysis of the pre-selection date
4698
        if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/',$set_time,$reg))
4699
        {
4700
            // Date format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'
4701
            $syear	= (! empty($reg[1])?$reg[1]:'');
4702
            $smonth	= (! empty($reg[2])?$reg[2]:'');
4703
            $sday	= (! empty($reg[3])?$reg[3]:'');
4704
            $shour	= (! empty($reg[4])?$reg[4]:'');
4705
            $smin	= (! empty($reg[5])?$reg[5]:'');
4706
        }
4707
        elseif (strval($set_time) != '' && $set_time != -1)
4708
        {
4709
            // set_time est un timestamps (0 possible)
4710
            $syear = dol_print_date($set_time, "%Y");
4711
            $smonth = dol_print_date($set_time, "%m");
4712
            $sday = dol_print_date($set_time, "%d");
4713
            if ($orig_set_time != '')
4714
            {
4715
            	$shour = dol_print_date($set_time, "%H");
4716
            	$smin = dol_print_date($set_time, "%M");
4717
            }
4718
        }
4719
        else
4720
        {
4721
            // Date est '' ou vaut -1
4722
            $syear = '';
4723
            $smonth = '';
4724
            $sday = '';
4725
            $shour = !isset($conf->global->MAIN_DEFAULT_DATE_HOUR) ? '' : $conf->global->MAIN_DEFAULT_DATE_HOUR;
4726
            $smin = !isset($conf->global->MAIN_DEFAULT_DATE_MIN) ? '' : $conf->global->MAIN_DEFAULT_DATE_MIN;
4727
        }
4728
4729
        // You can set MAIN_POPUP_CALENDAR to 'eldy' or 'jquery'
4730
        $usecalendar='combo';
4731
        if (! empty($conf->use_javascript_ajax) && (empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR != "none")) $usecalendar=empty($conf->global->MAIN_POPUP_CALENDAR)?'jquery':$conf->global->MAIN_POPUP_CALENDAR;
4732
		//if (! empty($conf->browser->phone)) $usecalendar='combo';
4733
4734
        if ($d)
4735
        {
4736
            // Show date with popup
4737
            if ($usecalendar != 'combo')
4738
            {
4739
            	$formated_date='';
4740
                //print "e".$set_time." t ".$conf->format_date_short;
4741
                if (strval($set_time) != '' && $set_time != -1)
4742
                {
4743
                    //$formated_date=dol_print_date($set_time,$conf->format_date_short);
4744
                    $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShortInput"));  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
4745
                }
4746
4747
                // Calendrier popup version eldy
4748
                if ($usecalendar == "eldy")
4749
                {
4750
                    // Zone de saisie manuelle de la date
4751
                    $retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" class="maxwidth75" maxlength="11" value="'.$formated_date.'"';
4752
                    $retstring.=($disabled?' disabled':'');
4753
                    $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "';  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
4754
                    $retstring.='>';
4755
4756
                    // Icone calendrier
4757
                    if (! $disabled)
4758
                    {
4759
                        $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons"';
4760
                        $base=DOL_URL_ROOT.'/core/';
4761
                        $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');"';
4762
                        $retstring.='>'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').'</button>';
4763
                    }
4764
                    else $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>';
4765
4766
                    $retstring.='<input type="hidden" id="'.$prefix.'day"   name="'.$prefix.'day"   value="'.$sday.'">'."\n";
4767
                    $retstring.='<input type="hidden" id="'.$prefix.'month" name="'.$prefix.'month" value="'.$smonth.'">'."\n";
4768
                    $retstring.='<input type="hidden" id="'.$prefix.'year"  name="'.$prefix.'year"  value="'.$syear.'">'."\n";
4769
                }
4770
                elseif ($usecalendar == 'jquery')
4771
                {
4772
                	if (! $disabled)
4773
                	{
4774
                		$retstring.="<script type='text/javascript'>";
4775
                		$retstring.="$(function(){ $('#".$prefix."').datepicker({
4776
            				dateFormat: '".$langs->trans("FormatDateShortJQueryInput")."',
4777
                			autoclose: true,
4778
                			todayHighlight: true,";
4779
                		if (empty($conf->global->MAIN_POPUP_CALENDAR_ON_FOCUS))
4780
                		{
4781
                		$retstring.="
4782
                			showOn: 'button',
4783
							buttonImage: '".DOL_URL_ROOT."/theme/".$conf->theme."/img/object_calendarday.png',
4784
							buttonImageOnly: true";
4785
                		}
4786
                		$retstring.="
4787
                			}) });";
4788
                		$retstring.="</script>";
4789
                	}
4790
4791
                	// Zone de saisie manuelle de la date
4792
                	$retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" class="maxwidth75" maxlength="11" value="'.$formated_date.'"';
4793
                	$retstring.=($disabled?' disabled':'');
4794
                	$retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "';  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
4795
                	$retstring.='>';
4796
4797
                	// Icone calendrier
4798
                	if (! $disabled)
4799
                	{
4800
                		/* Not required. Managed by option buttonImage of jquery
4801
                		$retstring.=img_object($langs->trans("SelectDate"),'calendarday','id="'.$prefix.'id" class="datecallink"');
4802
                		$retstring.="<script type='text/javascript'>";
4803
                		$retstring.="jQuery(document).ready(function() {";
4804
                		$retstring.='	jQuery("#'.$prefix.'id").click(function() {';
4805
                		$retstring.="    	jQuery('#".$prefix."').focus();";
4806
                		$retstring.='    });';
4807
                		$retstring.='});';
4808
                		$retstring.="</script>";*/
4809
                	}
4810
                	else
4811
                	{
4812
                		$retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>';
4813
                	}
4814
4815
                	$retstring.='<input type="hidden" id="'.$prefix.'day"   name="'.$prefix.'day"   value="'.$sday.'">'."\n";
4816
                	$retstring.='<input type="hidden" id="'.$prefix.'month" name="'.$prefix.'month" value="'.$smonth.'">'."\n";
4817
                	$retstring.='<input type="hidden" id="'.$prefix.'year"  name="'.$prefix.'year"  value="'.$syear.'">'."\n";
4818
                }
4819
                else
4820
                {
4821
                    $retstring.="Bad value of MAIN_POPUP_CALENDAR";
4822
                }
4823
            }
4824
            // Show date with combo selects
4825
            else
4826
			{
4827
			    //$retstring.='<div class="inline-block">';
4828
                // Day
4829
                $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50imp" id="'.$prefix.'day" name="'.$prefix.'day">';
4830
4831
                if ($emptydate || $set_time == -1)
4832
                {
4833
                    $retstring.='<option value="0" selected>&nbsp;</option>';
4834
                }
4835
4836
                for ($day = 1 ; $day <= 31; $day++)
4837
                {
4838
                    $retstring.='<option value="'.$day.'"'.($day == $sday ? ' selected':'').'>'.$day.'</option>';
4839
                }
4840
4841
                $retstring.="</select>";
4842
4843
                $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'month" name="'.$prefix.'month">';
4844
                if ($emptydate || $set_time == -1)
4845
                {
4846
                    $retstring.='<option value="0" selected>&nbsp;</option>';
4847
                }
4848
4849
                // Month
4850
                for ($month = 1 ; $month <= 12 ; $month++)
4851
                {
4852
                    $retstring.='<option value="'.$month.'"'.($month == $smonth?' selected':'').'>';
4853
                    $retstring.=dol_print_date(mktime(12,0,0,$month,1,2000),"%b");
4854
                    $retstring.="</option>";
4855
                }
4856
                $retstring.="</select>";
4857
4858
                // Year
4859
                if ($emptydate || $set_time == -1)
4860
                {
4861
                    $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.'">';
4862
                }
4863
                else
4864
                {
4865
                    $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'year" name="'.$prefix.'year">';
4866
4867
                    for ($year = $syear - 10; $year < $syear + 10 ; $year++)
4868
                    {
4869
                        $retstring.='<option value="'.$year.'"'.($year == $syear ? ' selected':'').'>'.$year.'</option>';
4870
                    }
4871
                    $retstring.="</select>\n";
4872
                }
4873
                //$retstring.='</div>';
4874
            }
4875
        }
4876
4877
        if ($d && $h) $retstring.=($h==2?'<br>':' ');
4878
4879
        if ($h)
4880
        {
4881
            // Show hour
4882
            $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'hour':'').'" id="'.$prefix.'hour" name="'.$prefix.'hour">';
4883
            if ($emptyhours) $retstring.='<option value="-1">&nbsp;</option>';
4884
            for ($hour = 0; $hour < 24; $hour++)
4885
            {
4886
                if (strlen($hour) < 2) $hour = "0" . $hour;
4887
                $retstring.='<option value="'.$hour.'"'.(($hour == $shour)?' selected':'').'>'.$hour.(empty($conf->dol_optimize_smallscreen)?'':'H').'</option>';
0 ignored issues
show
Bug introduced by
The variable $shour does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
4888
            }
4889
            $retstring.='</select>';
4890
            if ($m && empty($conf->dol_optimize_smallscreen)) $retstring.=":";
4891
        }
4892
4893
        if ($m)
4894
        {
4895
            // Show minutes
4896
            $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'min':'').'" id="'.$prefix.'min" name="'.$prefix.'min">';
4897
            if ($emptyhours) $retstring.='<option value="-1">&nbsp;</option>';
4898
            for ($min = 0; $min < 60 ; $min++)
4899
            {
4900
                if (strlen($min) < 2) $min = "0" . $min;
4901
                $retstring.='<option value="'.$min.'"'.(($min == $smin)?' selected':'').'>'.$min.(empty($conf->dol_optimize_smallscreen)?'':'').'</option>';
0 ignored issues
show
Bug introduced by
The variable $smin does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
4902
            }
4903
            $retstring.='</select>';
4904
        }
4905
4906
        // Add a "Now" link
4907
        if ($conf->use_javascript_ajax && $addnowlink)
4908
        {
4909
            // Script which will be inserted in the onClick of the "Now" link
4910
            $reset_scripts = "";
4911
4912
            // Generate the date part, depending on the use or not of the javascript calendar
4913
            $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');';
4914
            $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');';
4915
            $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');';
4916
            $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');';
4917
            /*if ($usecalendar == "eldy")
4918
            {
4919
                $base=DOL_URL_ROOT.'/core/';
4920
                $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');';
4921
            }
4922
            else
4923
            {
4924
                $reset_scripts .= 'this.form.elements[\''.$prefix.'day\'].value=formatDate(new Date(), \'d\'); ';
4925
                $reset_scripts .= 'this.form.elements[\''.$prefix.'month\'].value=formatDate(new Date(), \'M\'); ';
4926
                $reset_scripts .= 'this.form.elements[\''.$prefix.'year\'].value=formatDate(new Date(), \'yyyy\'); ';
4927
            }*/
4928
            // Update the hour part
4929
            if ($h)
4930
            {
4931
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4932
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); ';
4933
                $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');';
4934
                if ($fullday) $reset_scripts .= ' } ';
4935
            }
4936
            // Update the minute part
4937
            if ($m)
4938
            {
4939
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4940
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); ';
4941
                $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');';
4942
                if ($fullday) $reset_scripts .= ' } ';
4943
            }
4944
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
4945
            if ($reset_scripts && empty($conf->dol_optimize_smallscreen))
4946
            {
4947
                $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonNow" type="button" name="_useless" value="now" onClick="'.$reset_scripts.'">';
4948
                $retstring.=$langs->trans("Now");
4949
                $retstring.='</button> ';
4950
            }
4951
        }
4952
4953
        // Add a "Plus one hour" link
4954
        if ($conf->use_javascript_ajax && $addplusone)
4955
        {
4956
            // Script which will be inserted in the onClick of the "Add plusone" link
4957
            $reset_scripts = "";
4958
4959
            // Generate the date part, depending on the use or not of the javascript calendar
4960
            $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');';
4961
            $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');';
4962
            $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');';
4963
            $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');';
4964
            // Update the hour part
4965
            if ($h)
4966
            {
4967
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4968
                $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');';
4969
                if ($fullday) $reset_scripts .= ' } ';
4970
            }
4971
            // Update the minute part
4972
            if ($m)
4973
            {
4974
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4975
                $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');';
4976
                if ($fullday) $reset_scripts .= ' } ';
4977
            }
4978
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
4979
            if ($reset_scripts && empty($conf->dol_optimize_smallscreen))
4980
            {
4981
                $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonPlusOne" type="button" name="_useless2" value="plusone" onClick="'.$reset_scripts.'">';
4982
                $retstring.=$langs->trans("DateStartPlusOne");
4983
                $retstring.='</button> ';
4984
            }
4985
        }
4986
4987
        // Add a "Plus one hour" link
4988
        if ($conf->use_javascript_ajax && $adddateof)
4989
        {
4990
            $tmparray=dol_getdate($adddateof);
4991
            $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>';
4992
        }
4993
4994
        if (! empty($nooutput)) return $retstring;
4995
4996
        print $retstring;
4997
        return;
4998
    }
4999
5000
    /**
5001
     *	Function to show a form to select a duration on a page
5002
     *
5003
     *	@param	string	$prefix   		Prefix for input fields
5004
     *	@param  int	$iSecond  		    Default preselected duration (number of seconds or '')
5005
     * 	@param	int	$disabled           Disable the combo box
5006
     * 	@param	string	$typehour		If 'select' then input hour and input min is a combo,
5007
     *						            if 'text' input hour is in text and input min is a text,
5008
     *						            if 'textselect' input hour is in text and input min is a combo
5009
     *  @param	integer	$minunderhours	If 1, show minutes selection under the hours
5010
     * 	@param	int	$nooutput		    Do not output html string but return it
5011
     *  @return	string|null
5012
     */
5013
    function select_duration($prefix, $iSecond='', $disabled=0, $typehour='select', $minunderhours=0, $nooutput=0)
5014
    {
5015
    	global $langs;
5016
5017
    	$retstring='';
5018
5019
    	$hourSelected=0; $minSelected=0;
5020
5021
    	// Hours
5022
        if ($iSecond != '')
5023
        {
5024
            require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
5025
5026
            $hourSelected = convertSecondToTime($iSecond,'allhour');
5027
            $minSelected = convertSecondToTime($iSecond,'min');
5028
        }
5029
5030
        if ($typehour=='select' )
5031
        {
5032
	        $retstring.='<select class="flat" name="'.$prefix.'hour"'.($disabled?' disabled':'').'>';
5033
	        for ($hour = 0; $hour < 25; $hour++)	// For a duration, we allow 24 hours
5034
	        {
5035
	            $retstring.='<option value="'.$hour.'"';
5036
	            if ($hourSelected == $hour)
5037
	            {
5038
	                $retstring.=" selected";
5039
	            }
5040
	            $retstring.=">".$hour."</option>";
5041
	        }
5042
	        $retstring.="</select>";
5043
        }
5044
        elseif ($typehour=='text' || $typehour=='textselect')
5045
        {
5046
        	$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):'').'">';
5047
        }
5048
        else return 'BadValueForParameterTypeHour';
5049
5050
        if ($typehour!='text') $retstring.=' '.$langs->trans('HourShort');
5051
        else $retstring.='<span class="hideonsmartphone">:</span>';
5052
5053
        // Minutes
5054
        if ($minunderhours) $retstring.='<br>';
5055
        else $retstring.='<span class="hideonsmartphone">&nbsp;</span>';
5056
5057
        if ($typehour=='select' || $typehour=='textselect')
5058
        {
5059
	        $retstring.='<select class="flat" name="'.$prefix.'min"'.($disabled?' disabled':'').'>';
5060
	        for ($min = 0; $min <= 55; $min=$min+5)
5061
	        {
5062
	            $retstring.='<option value="'.$min.'"';
5063
	            if ($minSelected == $min) $retstring.=' selected';
5064
	            $retstring.='>'.$min.'</option>';
5065
	        }
5066
	        $retstring.="</select>";
5067
        }
5068
        elseif ($typehour=='text' )
5069
        {
5070
        	$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):'').'">';
5071
        }
5072
5073
        if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort');
5074
5075
        //$retstring.="&nbsp;";
5076
5077
        if (! empty($nooutput)) return $retstring;
5078
5079
        print $retstring;
5080
        return;
5081
    }
5082
5083
5084
    /**
5085
     *	Return a HTML select string, built from an array of key+value.
5086
     *  Note: Do not apply langs->trans function on returned content, content may be entity encoded twice.
5087
     *
5088
     *	@param	string			$htmlname       Name of html select area. Must start with "multi" if this is a multiselect
5089
     *	@param	array			$array          Array (key => value)
5090
     *	@param	string|string[]	$id             Preselected key or preselected keys for multiselect
5091
     *	@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.
5092
     *	@param	int				$key_in_label   1 to show key into label with format "[key] value"
5093
     *	@param	int				$value_as_key   1 to use value as key
5094
     *	@param  string			$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
5095
     *	@param  int				$translate		1=Translate and encode value
5096
     * 	@param	int				$maxlen			Length maximum for labels
5097
     * 	@param	int				$disabled		Html select box is disabled
5098
     *  @param	string			$sort			'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order
5099
     *  @param	string			$morecss		Add more class to css styles
5100
     *  @param	int				$addjscombo		    Add js combo
5101
     *  @param  string          $moreparamonempty   Add more param on the empty option line. Not used if show_empty not set
5102
     *  @param  int             $disablebademail    Check if an email is found into value and if not disable and colorize entry
5103
     *  @param  int             $nohtmlescape       No html escaping.
5104
     * 	@return	string							    HTML select string.
5105
     *  @see multiselectarray
5106
     */
5107
    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)
5108
    {
5109
        global $conf, $langs;
5110
5111
        // Do we want a multiselect ?
5112
        //$jsbeautify = 0;
5113
        //if (preg_match('/^multi/',$htmlname)) $jsbeautify = 1;
5114
		$jsbeautify = 1;
5115
5116
        if ($value_as_key) $array=array_combine($array, $array);
5117
5118
        $out='';
5119
5120
        // Add code for jquery to use multiselect
5121
        if ($addjscombo && empty($conf->dol_use_jmobile) && $jsbeautify)
5122
        {
5123
        	$minLengthToAutocomplete=0;
5124
        	$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?(constant('REQUIRE_JQUERY_MULTISELECT')?constant('REQUIRE_JQUERY_MULTISELECT'):'select2'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
5125
5126
        	// Enhance with select2
5127
        	if ($conf->use_javascript_ajax)
5128
        	{
5129
        	    include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
5130
        	    $comboenhancement = ajax_combobox($htmlname);
5131
        	    $out.=$comboenhancement;
5132
        	}
5133
        }
5134
5135
        $out.='<select id="'.preg_replace('/^\./','',$htmlname).'" '.($disabled?'disabled ':'').'class="flat '.(preg_replace('/^\./','',$htmlname)).($morecss?' '.$morecss:'').'" name="'.preg_replace('/^\./','',$htmlname).'" '.($moreparam?$moreparam:'').'>';
5136
5137
        if ($show_empty)
5138
        {
5139
        	$textforempty=' ';
5140
        	if (! empty($conf->use_javascript_ajax)) $textforempty='&nbsp;';	// If we use ajaxcombo, we need &nbsp; here to avoid to have an empty element that is too small.
5141
            if (! is_numeric($show_empty)) $textforempty=$show_empty;
5142
        	$out.='<option class="optiongrey" '.($moreparamonempty?$moreparamonempty.' ':'').'value="'.($show_empty < 0 ? $show_empty : -1).'"'.($id == $show_empty ?' selected':'').'>'.$textforempty.'</option>'."\n";
5143
        }
5144
5145
        if (is_array($array))
5146
        {
5147
        	// Translate
5148
        	if ($translate)
5149
        	{
5150
	        	foreach($array as $key => $value)
5151
	        	{
5152
	        	    $array[$key]=$langs->trans($value);
5153
	        	}
5154
        	}
5155
5156
        	// Sort
5157
			if ($sort == 'ASC') asort($array);
5158
			elseif ($sort == 'DESC') arsort($array);
5159
5160
            foreach($array as $key => $value)
5161
            {
5162
                $disabled=''; $style='';
5163
                if (! empty($disablebademail))
5164
                {
5165
                    if (! preg_match('/&lt;.+@.+&gt;/', $value))
5166
                    {
5167
                        //$value=preg_replace('/'.preg_quote($a,'/').'/', $b, $value);
5168
                        $disabled=' disabled';
5169
                        $style=' class="warning"';
5170
                    }
5171
                }
5172
                $out.='<option value="'.$key.'"';
5173
                $out.=$style.$disabled;
5174
                if ($id != '' && $id == $key && ! $disabled) $out.=' selected';		// To preselect a value
5175
                $out.='>';
5176
5177
                if ($key_in_label)
5178
                {
5179
                    if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value));
5180
                    else $selectOptionValue = $key.' - '.($maxlen?dol_trunc($value,$maxlen):$value);
5181
                }
5182
                else
5183
                {
5184
                    if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value);
5185
                    else $selectOptionValue = $maxlen?dol_trunc($value,$maxlen):$value;
5186
                    if ($value == '' || $value == '-') $selectOptionValue='&nbsp;';
5187
                }
5188
                //var_dump($selectOptionValue);
5189
                $out.=$selectOptionValue;
5190
                $out.="</option>\n";
5191
            }
5192
        }
5193
5194
        $out.="</select>";
5195
        return $out;
5196
    }
5197
5198
5199
    /**
5200
     *	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.
5201
     *  Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice.
5202
     *
5203
     *	@param	string	$htmlname       		Name of html select area
5204
     *	@param	string	$url					Url. Must return a json_encode of array(key=>array('text'=>'A text', 'url'=>'An url'), ...)
5205
     *	@param	string	$id             		Preselected key
5206
     *	@param  string	$moreparam      		Add more parameters onto the select tag
5207
     *	@param  string	$moreparamtourl 		Add more parameters onto the Ajax called URL
5208
     * 	@param	int		$disabled				Html select box is disabled
5209
     *  @param	int		$minimumInputLength		Minimum Input Length
5210
     *  @param	string	$morecss				Add more class to css styles
5211
     *  @param  int     $callurlonselect        If set to 1, some code is added so an url return by the ajax is called when value is selected.
5212
     *  @param  string  $placeholder            String to use as placeholder
5213
     *  @param  integer $acceptdelayedhtml      1 if caller request 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)
5214
     * 	@return	string   						HTML select string
5215
     */
5216
    static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0)
5217
    {
5218
        global $langs;
5219
        global $delayedhtmlcontent;
5220
5221
    	$tmpplugin='select2';
5222
5223
    	$out='<input type="text" class="'.$htmlname.($morecss?' '.$morecss:'').'" '.($moreparam?$moreparam.' ':'').'name="'.$htmlname.'">';
5224
5225
    	// TODO Use an internal dolibarr component instead of select2
5226
    	$outdelayed='<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' -->
5227
	    	<script type="text/javascript">
5228
	    	$(document).ready(function () {
5229
5230
    	        '.($callurlonselect ? 'var saveRemoteData = [];':'').'
5231
5232
                $(".'.$htmlname.'").select2({
5233
			    	ajax: {
5234
				    	dir: "ltr",
5235
				    	url: "'.$url.'",
5236
				    	dataType: \'json\',
5237
				    	delay: 250,
5238
				    	data: function (searchTerm, pageNumber, context) {
5239
				    		return {
5240
						    	q: searchTerm, // search term
5241
				    			page: pageNumber
5242
				    		};
5243
			    		},
5244
			    		results: function (remoteData, pageNumber, query) {
5245
			    			console.log(remoteData);
5246
				    	    saveRemoteData = remoteData;
5247
				    	    /* format json result for select2 */
5248
				    	    result = []
5249
				    	    $.each( remoteData, function( key, value ) {
5250
				    	       result.push({id: key, text: value.text});
5251
                            });
5252
			    			//return {results:[{id:\'none\', text:\'aa\'}, {id:\'rrr\', text:\'Red\'},{id:\'bbb\', text:\'Search a into projects\'}], more:false}
5253
			    			return {results: result, more:false}
5254
    					},
5255
			    		/*processResults: function (data, page) {
5256
			    			// parse the results into the format expected by Select2.
5257
			    			// since we are using custom formatting functions we do not need to
5258
			    			// alter the remote JSON data
5259
			    			console.log(data);
5260
			    			return {
5261
			    				results: data.items
5262
			    			};
5263
			    		},*/
5264
			    		cache: true
5265
			    	},
5266
			        dropdownCssClass: "css-'.$htmlname.'",
5267
				    placeholder: "'.dol_escape_js($placeholder).'",
5268
			    	escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
5269
			    	minimumInputLength: '.$minimumInputLength.',
5270
			        formatResult: function(result, container, query, escapeMarkup) {
5271
                        return escapeMarkup(result.text);
5272
                    }
5273
			    });
5274
5275
                '.($callurlonselect ? '
5276
                $(".'.$htmlname.'").change(function() {
5277
			    	var selected = $(".'.$htmlname.'").select2("val");
5278
			        $(".'.$htmlname.'").select2("val","");  /* reset visible combo value */
5279
    			    $.each( saveRemoteData, function( key, value ) {
5280
    				        if (key == selected)
5281
    			            {
5282
    			                 console.log("Do a redirect into selectArrayAjax to "+value.url)
5283
    			                 location.assign(value.url);
5284
    			            }
5285
                    });
5286
    			});' : '' ) . '
5287
5288
    	   });
5289
	       </script>';
5290
5291
		if ($acceptdelayedhtml)
5292
		{
5293
		    $delayedhtmlcontent.=$outdelayed;
5294
		}
5295
		else
5296
		{
5297
		    $out.=$outdelayed;
5298
		}
5299
		return $out;
5300
    }
5301
5302
    /**
5303
     *	Show a multiselect form from an array.
5304
     *
5305
     *	@param	string	$htmlname		Name of select
5306
     *	@param	array	$array			Array with key+value
5307
     *	@param	array	$selected		Array with key+value preselected
5308
     *	@param	int		$key_in_label   1 pour afficher la key dans la valeur "[key] value"
5309
     *	@param	int		$value_as_key   1 to use value as key
5310
     *	@param  string	$morecss        Add more css style
5311
     *	@param  int		$translate		Translate and encode value
5312
     *  @param	int		$width			Force width of select box. May be used only when using jquery couch. Example: 250, 95%
5313
     *  @param	string	$moreattrib		Add more options on select component. Example: 'disabled'
5314
     *  @param	string	$elemtype		Type of element we show ('category', ...)
5315
     *	@return	string					HTML multiselect string
5316
     *  @see selectarray
5317
     */
5318
    static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $morecss='', $translate=0, $width=0, $moreattrib='',$elemtype='')
5319
    {
5320
    	global $conf, $langs;
5321
5322
    	$out = '';
5323
5324
    	// Add code for jquery to use multiselect
5325
    	if (! empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT'))
5326
    	{
5327
    		$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
5328
   			$out.='<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' -->
5329
    			<script type="text/javascript">
5330
	    			function formatResult(record) {'."\n";
5331
						if ($elemtype == 'category')
5332
						{
5333
							$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>\';
5334
								  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
5335
						}
5336
						else
5337
						{
5338
							$out.='return record.text;';
5339
						}
5340
			$out.= '	};
5341
    				function formatSelection(record) {'."\n";
5342
						if ($elemtype == 'category')
5343
						{
5344
							$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>\';
5345
								  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
5346
						}
5347
						else
5348
						{
5349
							$out.='return record.text;';
5350
						}
5351
			$out.= '	};
5352
	    			$(document).ready(function () {
5353
    					$(\'#'.$htmlname.'\').'.$tmpplugin.'({
5354
    						dir: \'ltr\',
5355
							// Specify format function for dropdown item
5356
							formatResult: formatResult,
5357
    					 	templateResult: formatResult,		/* For 4.0 */
5358
							// Specify format function for selected item
5359
							formatSelection: formatSelection,
5360
    					 	templateResult: formatSelection		/* For 4.0 */
5361
    					});
5362
    				});
5363
    			</script>';
5364
    	}
5365
5366
    	// Try also magic suggest
5367
5368
		$out .= '<select id="'.$htmlname.'" class="multiselect'.($morecss?' '.$morecss:'').'" multiple name="'.$htmlname.'[]"'.($moreattrib?' '.$moreattrib:'').($width?' style="width: '.(preg_match('/%/',$width)?$width:$width.'px').'"':'').'>'."\n";
5369
    	if (is_array($array) && ! empty($array))
5370
    	{
5371
    		if ($value_as_key) $array=array_combine($array, $array);
5372
5373
    		if (! empty($array))
5374
    		{
5375
    			foreach ($array as $key => $value)
5376
    			{
5377
    				$out.= '<option value="'.$key.'"';
5378
    				if (is_array($selected) && ! empty($selected) && in_array($key, $selected) && !empty($key))
5379
    				{
5380
    					$out.= ' selected';
5381
    				}
5382
    				$out.= '>';
5383
5384
    				$newval = ($translate ? $langs->trans($value) : $value);
5385
    				$newval = ($key_in_label ? $key.' - '.$newval : $newval);
5386
    				$out.= dol_htmlentitiesbr($newval);
5387
    				$out.= '</option>'."\n";
5388
    			}
5389
    		}
5390
    	}
5391
    	$out.= '</select>'."\n";
5392
5393
    	return $out;
5394
    }
5395
5396
5397
    /**
5398
     *	Show a multiselect form from an array.
5399
     *
5400
     *	@param	string	$htmlname		Name of select
5401
     *	@param	array	$array			Array with array of fields we could show. This array may be modified according to setup of user.
5402
     *  @param  string  $varpage        Id of context for page. Can be set with $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
5403
     *	@return	string					HTML multiselect string
5404
     *  @see selectarray
5405
     */
5406
    static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage)
5407
    {
5408
        global $conf,$langs,$user;
5409
5410
        if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return '';
5411
5412
        $tmpvar="MAIN_SELECTEDFIELDS_".$varpage;
5413
        if (! empty($user->conf->$tmpvar))
5414
        {
5415
            $tmparray=explode(',', $user->conf->$tmpvar);
5416
            foreach($array as $key => $val)
5417
            {
5418
                //var_dump($key);
5419
                //var_dump($tmparray);
5420
                if (in_array($key, $tmparray)) $array[$key]['checked']=1;
5421
                else $array[$key]['checked']=0;
5422
            }
5423
        }
5424
        //var_dump($array);
5425
5426
        $lis='';
5427
        $listcheckedstring='';
5428
5429
        foreach($array as $key => $val)
5430
        {
5431
           /* var_dump($val);
5432
            var_dump(array_key_exists('enabled', $val));
5433
            var_dump(!$val['enabled']);*/
5434
           if (array_key_exists('enabled', $val) && isset($val['enabled']) && ! $val['enabled'])
5435
           {
5436
               unset($array[$key]);     // We don't want this field
5437
               continue;
5438
           }
5439
           if ($val['label'])
5440
	       {
5441
	           $lis.='<li><input type="checkbox" value="'.$key.'"'.(empty($val['checked'])?'':' checked="checked"').'/>'.dol_escape_htmltag($langs->trans($val['label'])).'</li>';
5442
	           $listcheckedstring.=(empty($val['checked'])?'':$key.',');
5443
	       }
5444
        }
5445
5446
        $out ='<!-- Component multiSelectArrayWithCheckbox '.$htmlname.' -->
5447
5448
        <dl class="dropdown">
5449
            <dt>
5450
            <a href="#">
5451
              '.img_picto('','list').'
5452
            </a>
5453
            <input type="hidden" class="'.$htmlname.'" name="'.$htmlname.'" value="'.$listcheckedstring.'">
5454
            </dt>
5455
            <dd class="dropowndd">
5456
                <div class="multiselectcheckbox'.$htmlname.'">
5457
                    <ul class="ul'.$htmlname.'">
5458
                    '.$lis.'
5459
                    </ul>
5460
                </div>
5461
            </dd>
5462
        </dl>
5463
5464
        <script type="text/javascript">
5465
          jQuery(document).ready(function () {
5466
              $(\'.multiselectcheckbox'.$htmlname.' input[type="checkbox"]\').on(\'click\', function () {
5467
                  console.log("A new field was added/removed")
5468
                  $("input:hidden[name=formfilteraction]").val(\'listafterchangingselectedfields\')
5469
                  var title = $(this).val() + ",";
5470
                  if ($(this).is(\':checked\')) {
5471
                      $(\'.'.$htmlname.'\').val(title + $(\'.'.$htmlname.'\').val());
5472
                  }
5473
                  else {
5474
                      $(\'.'.$htmlname.'\').val( $(\'.'.$htmlname.'\').val().replace(title, \'\') )
5475
                  }
5476
                  // Now, we submit page
5477
                  $(this).parents(\'form:first\').submit();
5478
              });
5479
           });
5480
        </script>
5481
5482
        ';
5483
        return $out;
5484
    }
5485
5486
	/**
5487
	 * 	Render list of categories linked to object with id $id and type $type
5488
	 *
5489
	 * 	@param		int		$id				Id of object
5490
 	 * 	@param		string	$type			Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated.
5491
 	 *  @param		int		$rendermode		0=Default, use multiselect. 1=Emulate multiselect (recommended)
5492
	 * 	@return		string					String with categories
5493
	 */
5494
	function showCategories($id, $type, $rendermode=0)
5495
	{
5496
		global $db;
5497
5498
		include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
5499
5500
		$cat = new Categorie($db);
5501
		$categories = $cat->containing($id, $type);
5502
5503
		if ($rendermode == 1)
5504
		{
5505
			$toprint = array();
5506
			foreach($categories as $c)
5507
			{
5508
				$ways = $c->print_all_ways();       // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text
5509
				foreach($ways as $way)
5510
				{
5511
					$toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"'.($c->color?' style="background: #'.$c->color.';"':' style="background: #aaa"').'>'.img_object('','category').' '.$way.'</li>';
5512
				}
5513
			}
5514
			return '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
5515
		}
5516
5517
		if ($rendermode == 0)
5518
		{
5519
			$cate_arbo = $this->select_all_categories($type, '', 'parent', 64, 0, 1);
5520
			foreach($categories as $c) {
5521
				$arrayselected[] = $c->id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arrayselected was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arrayselected = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
5522
			}
5523
5524
			return $this->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%', 'disabled', 'category');
0 ignored issues
show
Bug introduced by
The variable $arrayselected does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
5525
		}
5526
5527
		return 'ErrorBadValueForParameterRenderMode';	// Should not happened
5528
	}
5529
5530
5531
    /**
5532
     *  Show linked object block.
5533
     *
5534
     *  @param	CommonObject	$object		      Object we want to show links to
5535
     *  @param  string          $morehtmlright    More html to show on right of title
5536
     *  @return	int							      <0 if KO, >=0 if OK
5537
     */
5538
    function showLinkedObjectBlock($object, $morehtmlright='')
5539
    {
5540
        global $conf,$langs,$hookmanager;
5541
        global $bc;
5542
5543
        $object->fetchObjectLinked();
5544
5545
        // Bypass the default method
5546
        $hookmanager->initHooks(array('commonobject'));
5547
        $parameters=array();
5548
        $reshook=$hookmanager->executeHooks('showLinkedObjectBlock',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
0 ignored issues
show
Bug introduced by
The variable $action does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
5549
5550
        if (empty($reshook))
5551
        {
5552
        	$nbofdifferenttypes = count($object->linkedObjects);
5553
5554
        	print '<br><!-- showLinkedObjectBlock -->';
5555
            print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '');
5556
5557
5558
    		print '<div class="div-table-responsive-no-min">';
5559
            print '<table class="noborder allwidth">';
5560
5561
            print '<tr class="liste_titre">';
5562
            print '<td>'.$langs->trans("Type").'</td>';
5563
            print '<td>'.$langs->trans("Ref").'</td>';
5564
            print '<td align="center"></td>';
5565
            print '<td align="center">'.$langs->trans("Date").'</td>';
5566
            print '<td align="right">'.$langs->trans("AmountHTShort").'</td>';
5567
            print '<td align="right">'.$langs->trans("Status").'</td>';
5568
            print '<td></td>';
5569
            print '</tr>';
5570
5571
            $nboftypesoutput=0;
5572
5573
        	foreach($object->linkedObjects as $objecttype => $objects)
5574
        	{
5575
        		$tplpath = $element = $subelement = $objecttype;
5576
5577
        		if ($objecttype != 'supplier_proposal' && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs))
5578
        		{
5579
        			$element = $regs[1];
5580
        			$subelement = $regs[2];
5581
        			$tplpath = $element.'/'.$subelement;
5582
        		}
5583
        		$tplname='linkedobjectblock';
5584
5585
        		// To work with non standard path
5586
        		if ($objecttype == 'facture')          {
5587
        			$tplpath = 'compta/'.$element;
5588
        			if (empty($conf->facture->enabled)) continue;	// Do not show if module disabled
5589
        		}
5590
        	    else if ($objecttype == 'facturerec')          {
5591
        			$tplpath = 'compta/facture';
5592
        			$tplname = 'linkedobjectblockForRec';
5593
        			if (empty($conf->facture->enabled)) continue;	// Do not show if module disabled
5594
        		}
5595
        		else if ($objecttype == 'propal')           {
5596
        			$tplpath = 'comm/'.$element;
5597
        			if (empty($conf->propal->enabled)) continue;	// Do not show if module disabled
5598
        		}
5599
        		else if ($objecttype == 'supplier_proposal')           {
5600
        			if (empty($conf->supplier_proposal->enabled)) continue;	// Do not show if module disabled
5601
        		}
5602
        		else if ($objecttype == 'shipping' || $objecttype == 'shipment') {
5603
        			$tplpath = 'expedition';
5604
        			if (empty($conf->expedition->enabled)) continue;	// Do not show if module disabled
5605
        		}
5606
        		else if ($objecttype == 'delivery')         {
5607
        			$tplpath = 'livraison';
5608
        			if (empty($conf->expedition->enabled)) continue;	// Do not show if module disabled
5609
        		}
5610
        		else if ($objecttype == 'invoice_supplier') {
5611
        			$tplpath = 'fourn/facture';
5612
        		}
5613
        		else if ($objecttype == 'order_supplier')   {
5614
        			$tplpath = 'fourn/commande';
5615
        		}
5616
        		else if ($objecttype == 'expensereport')   {
5617
        			$tplpath = 'expensereport';
5618
        		}
5619
        		else if ($objecttype == 'subscription')   {
5620
        		    $tplpath = 'adherents';
5621
        		}
5622
5623
                global $linkedObjectBlock;
5624
        		$linkedObjectBlock = $objects;
5625
5626
5627
        		// Output template part (modules that overwrite templates must declare this into descriptor)
5628
        		$dirtpls=array_merge($conf->modules_parts['tpl'],array('/'.$tplpath.'/tpl'));
5629
        		foreach($dirtpls as $reldir)
5630
        		{
5631
        		    if ($nboftypesoutput == ($nbofdifferenttypes - 1))    // No more type to show after
5632
        		    {
5633
        		        global $noMoreLinkedObjectBlockAfter;
5634
        		        $noMoreLinkedObjectBlockAfter=1;
5635
        		    }
5636
5637
                    $res=@include dol_buildpath($reldir.'/'.$tplname.'.tpl.php');
5638
        			if ($res)
5639
        			{
5640
        			    $nboftypesoutput++;
5641
        			    break;
5642
        			}
5643
        		}
5644
        	}
5645
5646
        	if (! $nboftypesoutput)
5647
        	{
5648
        	    print '<tr><td class="impair opacitymedium" colspan="7">'.$langs->trans("None").'</td></tr>';
5649
        	}
5650
5651
        	print '</table>';
5652
			print '</div>';
5653
5654
        	return $nbofdifferenttypes;
5655
        }
5656
    }
5657
5658
    /**
5659
     *  Show block with links to link to other objects.
5660
     *
5661
     *  @param	CommonObject	$object				Object we want to show links to
5662
     *  @param	array			$restrictlinksto	Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction.
5663
     *  @param	array			$excludelinksto		Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion.
5664
     *  @return	string								<0 if KO, >0 if OK
5665
     */
5666
    function showLinkToObjectBlock($object, $restrictlinksto=array(), $excludelinksto=array())
5667
    {
5668
        global $conf, $langs, $hookmanager;
5669
        global $bc;
5670
5671
		$linktoelem='';
5672
		$linktoelemlist='';
5673
5674
		if (! is_object($object->thirdparty)) $object->fetch_thirdparty();
5675
5676
		$possiblelinks=array();
5677
		if (is_object($object->thirdparty) && ! empty($object->thirdparty->id) && $object->thirdparty->id > 0)
5678
		{
5679
    		$listofidcompanytoscan=$object->thirdparty->id;
5680
    		if (($object->thirdparty->parent > 0) && ! empty($conf->global->THIRDPARTY_INCLUDE_PARENT_IN_LINKTO)) $listofidcompanytoscan.=','.$object->thirdparty->parent;
5681
			if (($object->fk_project > 0) && ! empty($conf->global->THIRDPARTY_INCLUDE_PROJECT_THIRDPARY_IN_LINKTO))
5682
			{
5683
				include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
5684
				$tmpproject=new Project($this->db);
5685
				$tmpproject->fetch($object->fk_project);
5686
				if ($tmpproject->socid > 0 && ($tmpproject->socid != $object->thirdparty->id)) $listofidcompanytoscan.=','.$tmpproject->socid;
5687
				unset($tmpproject);
5688
			}
5689
5690
    		$possiblelinks=array(
5691
    		    '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').')'),
5692
    		    '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').')'),
5693
    		    '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.facnumber as 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('facture').')'),
5694
    		    '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').')'),
5695
    		    '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').')'),
5696
    		    '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').')'),
5697
    		    'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->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').')'),
5698
    		    'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->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').')')
5699
    		);
5700
		}
5701
5702
		global $action;
5703
5704
		// Can complete the possiblelink array
5705
		$hookmanager->initHooks(array('commonobject'));
5706
		$parameters=array();
5707
		$reshook=$hookmanager->executeHooks('showLinkToObjectBlock',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
5708
		if (empty($reshook))
5709
		{
5710
		    if (is_array($hookmanager->resArray) && count($hookmanager->resArray))
5711
		    {
5712
		        $possiblelinks=array_merge($possiblelinks, $hookmanager->resArray);
5713
		    }
5714
		}
5715
		else if ($reshook > 0)
5716
		{
5717
		    if (is_array($hookmanager->resArray) && count($hookmanager->resArray))
5718
		    {
5719
                $possiblelinks=$hookmanager->resArray;
5720
		    }
5721
		}
5722
5723
		foreach($possiblelinks as $key => $possiblelink)
5724
		{
5725
			$num = 0;
5726
5727
			if (empty($possiblelink['enabled'])) continue;
5728
5729
			if (! empty($possiblelink['perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || ! in_array($key, $excludelinksto)))
5730
			{
5731
				print '<div id="'.$key.'list"'.(empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)?' style="display:none"':'').'>';
5732
				$sql = $possiblelink['sql'];
5733
5734
				$resqllist = $this->db->query($sql);
5735
				if ($resqllist)
5736
				{
5737
					$num = $this->db->num_rows($resqllist);
5738
					$i = 0;
5739
5740
					print '<br><form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formlinked'.$key.'">';
5741
					print '<input type="hidden" name="id" value="'.$object->id.'">';
5742
					print '<input type="hidden" name="action" value="addlink">';
5743
					print '<input type="hidden" name="addlink" value="'.$key.'">';
5744
					print '<table class="noborder">';
5745
					print '<tr class="liste_titre">';
5746
					print '<td class="nowrap"></td>';
5747
					print '<td align="center">' . $langs->trans("Ref") . '</td>';
5748
					print '<td align="left">' . $langs->trans("RefCustomer") . '</td>';
5749
					print '<td align="right">' . $langs->trans("AmountHTShort") . '</td>';
5750
					print '<td align="left">' . $langs->trans("Company") . '</td>';
5751
					print '</tr>';
5752
					while ($i < $num)
5753
					{
5754
						$objp = $this->db->fetch_object($resqlorderlist);
0 ignored issues
show
Bug introduced by
The variable $resqlorderlist does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
5755
5756
						$var = ! $var;
0 ignored issues
show
Bug introduced by
The variable $var does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
5757
						print '<tr ' . $bc [$var] . '>';
5758
						print '<td aling="left">';
5759
						print '<input type="radio" name="idtolinkto" value=' . $objp->rowid . '>';
5760
						print '</td>';
5761
						print '<td align="center">' . $objp->ref . '</td>';
5762
						print '<td>' . $objp->ref_client . '</td>';
5763
						print '<td align="right">' . price($objp->total_ht) . '</td>';
5764
						print '<td>' . $objp->name . '</td>';
5765
						print '</tr>';
5766
						$i++;
5767
					}
5768
					print '</table>';
5769
					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>';
5770
5771
					print '</form>';
5772
					$this->db->free($resqllist);
5773
				} else {
5774
					dol_print_error($this->db);
5775
				}
5776
				print '</div>';
5777
				if ($num > 0)
5778
				{
5779
				}
5780
5781
				//$linktoelem.=($linktoelem?' &nbsp; ':'');
5782
				if ($num > 0) $linktoelemlist.='<li><a href="#linkto'.$key.'" class="linkto dropdowncloseonclick" rel="'.$key.'">' . $langs->trans($possiblelink['label']) .' ('.$num.')</a></li>';
5783
				//else $linktoelem.=$langs->trans($possiblelink['label']);
5784
				else $linktoelemlist.='<li><span class="linktodisabled">' . $langs->trans($possiblelink['label']) . ' (0)</span></li>';
5785
			}
5786
		}
5787
5788
		if ($linktoelemlist)
5789
		{
5790
    		$linktoelem='
5791
    		<dl class="dropdown" id="linktoobjectname">
5792
    		<dt><a href="#linktoobjectname">'.$langs->trans("LinkTo").'...</a></dt>
5793
    		<dd>
5794
    		<div class="multiselectlinkto">
5795
    		<ul class="ulselectedfields">'.$linktoelemlist.'
5796
    		</ul>
5797
    		</div>
5798
    		</dd>
5799
    		</dl>';
5800
		}
5801
		else
5802
		{
5803
		    $linktoelem='';
5804
		}
5805
5806
		print '<!-- Add js to show linkto box -->
5807
				<script type="text/javascript" language="javascript">
5808
				jQuery(document).ready(function() {
5809
					jQuery(".linkto").click(function() {
5810
						console.log("We choose to show/hide link for rel="+jQuery(this).attr(\'rel\'));
5811
					    jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle();
5812
						jQuery(this).toggle();
5813
					});
5814
				});
5815
				</script>
5816
		';
5817
5818
		return $linktoelem;
5819
    }
5820
5821
    /**
5822
     *	Return an html string with a select combo box to choose yes or no
5823
     *
5824
     *	@param	string		$htmlname		Name of html select field
5825
     *	@param	string		$value			Pre-selected value
5826
     *	@param	int			$option			0 return yes/no, 1 return 1/0
5827
     *	@param	bool		$disabled		true or false
5828
     *  @param	int      	$useempty		1=Add empty line
5829
     *	@return	string						See option
5830
     */
5831
    function selectyesno($htmlname, $value='', $option=0, $disabled=false, $useempty='')
5832
    {
5833
        global $langs;
5834
5835
        $yes="yes"; $no="no";
5836
        if ($option)
5837
        {
5838
            $yes="1";
5839
            $no="0";
5840
        }
5841
5842
        $disabled = ($disabled ? ' disabled' : '');
5843
5844
        $resultyesno = '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'"'.$disabled.'>'."\n";
5845
        if ($useempty) $resultyesno .= '<option value="-1"'.(($value < 0)?' selected':'').'>&nbsp;</option>'."\n";
5846
        if (("$value" == 'yes') || ($value == 1))
5847
        {
5848
            $resultyesno .= '<option value="'.$yes.'" selected>'.$langs->trans("Yes").'</option>'."\n";
5849
            $resultyesno .= '<option value="'.$no.'">'.$langs->trans("No").'</option>'."\n";
5850
        }
5851
        else
5852
       {
5853
       		$selected=(($useempty && $value != '0' && $value != 'no')?'':' selected');
5854
            $resultyesno .= '<option value="'.$yes.'">'.$langs->trans("Yes").'</option>'."\n";
5855
            $resultyesno .= '<option value="'.$no.'"'.$selected.'>'.$langs->trans("No").'</option>'."\n";
5856
        }
5857
        $resultyesno .= '</select>'."\n";
5858
        return $resultyesno;
5859
    }
5860
5861
5862
5863
    /**
5864
     *  Return list of export templates
5865
     *
5866
     *  @param	string	$selected          Id modele pre-selectionne
5867
     *  @param  string	$htmlname          Name of HTML select
5868
     *  @param  string	$type              Type of searched templates
5869
     *  @param  int		$useempty          Affiche valeur vide dans liste
5870
     *  @return	void
5871
     */
5872
    function select_export_model($selected='',$htmlname='exportmodelid',$type='',$useempty=0)
5873
    {
5874
5875
        $sql = "SELECT rowid, label";
5876
        $sql.= " FROM ".MAIN_DB_PREFIX."export_model";
5877
        $sql.= " WHERE type = '".$type."'";
5878
        $sql.= " ORDER BY rowid";
5879
        $result = $this->db->query($sql);
5880
        if ($result)
5881
        {
5882
            print '<select class="flat" name="'.$htmlname.'">';
5883
            if ($useempty)
5884
            {
5885
                print '<option value="-1">&nbsp;</option>';
5886
            }
5887
5888
            $num = $this->db->num_rows($result);
5889
            $i = 0;
5890
            while ($i < $num)
5891
            {
5892
                $obj = $this->db->fetch_object($result);
5893
                if ($selected == $obj->rowid)
5894
                {
5895
                    print '<option value="'.$obj->rowid.'" selected>';
5896
                }
5897
                else
5898
                {
5899
                    print '<option value="'.$obj->rowid.'">';
5900
                }
5901
                print $obj->label;
5902
                print '</option>';
5903
                $i++;
5904
            }
5905
            print "</select>";
5906
        }
5907
        else {
5908
            dol_print_error($this->db);
5909
        }
5910
    }
5911
5912
    /**
5913
     *    Return a HTML area with the reference of object and a navigation bar for a business object
5914
     *    Note: To add a particular filter on select, you can have $object->next_prev_filter set to add SQL criterias.
5915
     *
5916
     *    @param	object	$object			Object to show.
5917
     *    @param	string	$paramid   		Name of parameter to use to name the id into the URL next/previous link.
5918
     *    @param	string	$morehtml  		More html content to output just before the nav bar.
5919
     *    @param	int		$shownav	  	Show Condition (navigation is shown if value is 1).
5920
     *    @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). Use 'none' to disable next/prev.
5921
     *    @param	string	$fieldref   	Name of field ref of object (object->ref) to show or 'none' to not show ref.
5922
     *    @param	string	$morehtmlref  	More html to show after ref.
5923
     *    @param	string	$moreparam  	More param to add in nav link url. Must start with '&...'.
5924
     *	  @param	int		$nodbprefix		Do not include DB prefix to forge table name.
5925
     *	  @param	string	$morehtmlleft	More html code to show before ref.
5926
     *	  @param	string	$morehtmlstatus	More html code to show under navigation arrows (status place).
5927
     *	  @param	string	$morehtmlright	More html code to show after ref.
5928
     * 	  @return	string    				Portion HTML with ref + navigation buttons
5929
     */
5930
	function showrefnav($object,$paramid,$morehtml='',$shownav=1,$fieldid='rowid',$fieldref='ref',$morehtmlref='',$moreparam='',$nodbprefix=0,$morehtmlleft='',$morehtmlstatus='',$morehtmlright='')
5931
	{
5932
		global $langs,$conf,$hookmanager;
5933
5934
		$ret='';
5935
        if (empty($fieldid))  $fieldid='rowid';
5936
        if (empty($fieldref)) $fieldref='ref';
5937
5938
        // Add where from hooks
5939
        if (is_object($hookmanager))
5940
        {
5941
            $parameters=array();
5942
            $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters, $object);    // Note that $action and $object may have been modified by hook
5943
            $object->next_prev_filter.=$hookmanager->resPrint;
5944
        }
5945
5946
        $previous_ref = $next_ref = '';
5947
        if ($shownav)
5948
        {
5949
	        //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam";
5950
	        $object->load_previous_next_ref((isset($object->next_prev_filter)?$object->next_prev_filter:''),$fieldid,$nodbprefix);
5951
5952
        	$navurl = $_SERVER["PHP_SELF"];
5953
	        // Special case for project/task page
5954
	        if ($paramid == 'project_ref')
5955
	        {
5956
	            $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document)\.php/','/tasks.php',$navurl);
5957
	            $paramid='ref';
5958
	        }
5959
	        $previous_ref = $object->ref_previous?'<a 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>';
5960
	        $next_ref     = $object->ref_next?'<a 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>';
5961
        }
5962
5963
        //print "xx".$previous_ref."x".$next_ref;
5964
        $ret.='<!-- Start banner content --><div style="vertical-align: middle">';
5965
5966
        // Right part of banner
5967
		if ($morehtmlright) $ret.='<div class="inline-block floatleft">'.$morehtmlright.'</div>';
5968
5969
		if ($previous_ref || $next_ref || $morehtml)
5970
		{
5971
			$ret.='<div class="pagination"><ul>';
5972
		}
5973
        if ($morehtml)
5974
        {
5975
            $ret.='<li class="noborder litext">'.$morehtml.'</li>';
5976
        }
5977
        if ($shownav && ($previous_ref || $next_ref))
5978
        {
5979
            $ret.='<li class="pagination">'.$previous_ref.'</li>';
5980
            $ret.='<li class="pagination">'.$next_ref.'</li>';
5981
        }
5982
        if ($previous_ref || $next_ref || $morehtml)
5983
        {
5984
            $ret.='</ul></div>';
5985
        }
5986
		if ($morehtmlstatus) $ret.='<div class="statusref">'.$morehtmlstatus.'</div>';
5987
5988
        // Left part of banner
5989
		if ($morehtmlleft)
5990
		{
5991
		    if ($conf->browser->layout == 'phone') $ret.='<div class="floatleft">'.$morehtmlleft.'</div>';    // class="center" to have photo in middle
5992
		    else $ret.='<div class="inline-block floatleft">'.$morehtmlleft.'</div>';
5993
		}
5994
5995
		//if ($conf->browser->layout == 'phone') $ret.='<div class="clearboth"></div>';
5996
		$ret.='<div class="inline-block floatleft valignmiddle refid'.(($shownav && ($previous_ref || $next_ref))?' refidpadding':'').'">';
5997
5998
		// For thirdparty, contact, user, member, the ref is the id, so we show something else
5999
		if ($object->element == 'societe')
6000
		{
6001
		    $ret.=dol_htmlentities($object->name);
6002
		}
6003
		else if (in_array($object->element, array('contact', 'user', 'usergroup', 'member')))
6004
		{
6005
		    $ret.=dol_htmlentities($object->getFullName($langs));
6006
		}
6007
		else if (in_array($object->element, array('action', 'agenda')))
6008
		{
6009
		    $ret.=$object->ref.'<br>'.$object->label;
6010
		}
6011
		else if (in_array($object->element, array('adherent_type')))
6012
		{
6013
			$ret.=$object->label;
6014
		}
6015
		else if ($object->element == 'ecm_directories')
6016
		{
6017
			$ret.='';
6018
		}
6019
		else if ($fieldref != 'none') $ret.=dol_htmlentities($object->$fieldref);
6020
6021
6022
		if ($morehtmlref)
6023
		{
6024
		    $ret.=' '.$morehtmlref;
6025
		}
6026
		$ret.='</div>';
6027
6028
		$ret.='</div><!-- End banner content -->';
6029
6030
        return $ret;
6031
    }
6032
6033
6034
    /**
6035
     *    	Return HTML code to output a barcode
6036
     *
6037
     *     	@param	Object	$object		Object containing data to retrieve file name
6038
     * 		@param	int		$width			Width of photo
6039
     * 	  	@return string    				HTML code to output barcode
6040
     */
6041
    function showbarcode(&$object,$width=100)
6042
    {
6043
        global $conf;
6044
6045
        //Check if barcode is filled in the card
6046
        if (empty($object->barcode)) return '';
6047
6048
        // Complete object if not complete
6049
        if (empty($object->barcode_type_code) || empty($object->barcode_type_coder))
6050
        {
6051
        	$result = $object->fetch_barcode();
6052
            //Check if fetch_barcode() failed
6053
        	if ($result < 1) return '<!-- ErrorFetchBarcode -->';
6054
        }
6055
6056
        // Barcode image
6057
        $url=DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&generator='.urlencode($object->barcode_type_coder).'&code='.urlencode($object->barcode).'&encoding='.urlencode($object->barcode_type_code);
6058
        $out ='<!-- url barcode = '.$url.' -->';
6059
        $out.='<img src="'.$url.'">';
6060
        return $out;
6061
    }
6062
6063
    /**
6064
     *    	Return HTML code to output a photo
6065
     *
6066
     *    	@param	string		$modulepart			Key to define module concerned ('societe', 'userphoto', 'memberphoto')
6067
     *     	@param  object		$object				Object containing data to retrieve file name
6068
     * 		@param	int			$width				Width of photo
6069
     * 		@param	int			$height				Height of photo (auto if 0)
6070
     * 		@param	int			$caneditfield		Add edit fields
6071
     * 		@param	string		$cssclass			CSS name to use on img for photo
6072
     * 		@param	string		$imagesize		    'mini', 'small' or '' (original)
6073
     *      @param  int         $addlinktofullsize  Add link to fullsize image
6074
     *      @param  int         $cache              1=Accept to use image in cache
6075
     * 	  	@return string    						HTML code to output photo
6076
     */
6077
    static function showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0)
6078
    {
6079
        global $conf,$langs;
6080
6081
        $entity = (! empty($object->entity) ? $object->entity : $conf->entity);
6082
        $id = (! empty($object->id) ? $object->id : $object->rowid);
6083
6084
        $ret='';$dir='';$file='';$originalfile='';$altfile='';$email='';
6085
        if ($modulepart=='societe')
6086
        {
6087
            $dir=$conf->societe->multidir_output[$entity];
6088
            if (! empty($object->logo))
6089
            {
6090
                if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_mini');             // getImageFileNameForSize include the thumbs
6091
                else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_small');
6092
                else $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo;
6093
                $originalfile=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo;
6094
            }
6095
            $email=$object->email;
6096
        }
6097
        else if ($modulepart=='contact')
6098
        {
6099
            $dir=$conf->societe->multidir_output[$entity].'/contact';
6100
            if (! empty($object->photo))
6101
            {
6102
                if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_mini');
6103
                else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_small');
6104
                else $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo;
6105
                $originalfile=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo;
6106
            }
6107
            $email=$object->email;
6108
        }
6109
        else if ($modulepart=='userphoto')
6110
        {
6111
            $dir=$conf->user->dir_output;
6112
            if (! empty($object->photo))
6113
            {
6114
                if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_mini');
6115
                else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_small');
6116
                else $file=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo;
6117
                $originalfile=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo;
6118
            }
6119
            if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
6120
            $email=$object->email;
6121
        }
6122
        else if ($modulepart=='memberphoto')
6123
        {
6124
            $dir=$conf->adherent->dir_output;
6125
            if (! empty($object->photo))
6126
            {
6127
                if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_mini');
6128
                else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_small');
6129
                else $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo;
6130
                $originalfile=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo;
6131
            }
6132
            if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
6133
            $email=$object->email;
6134
        }
6135
        else
6136
        {
6137
            // Generic case to show photos
6138
        	$dir=$conf->$modulepart->dir_output;
6139
        	if (! empty($object->photo))
6140
        	{
6141
                if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_mini');
6142
                else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_small');
6143
        	    else $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo;
6144
        	    $originalfile=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo;
6145
        	}
6146
        	if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
6147
        	$email=$object->email;
6148
        }
6149
6150
        if ($dir)
6151
        {
6152
            if ($file && file_exists($dir."/".$file))
6153
            {
6154
                if ($addlinktofullsize)
6155
                {
6156
                    $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity='.$entity);
6157
                    if ($urladvanced) $ret.='<a href="'.$urladvanced.'">';
6158
                    else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">';
6159
                }
6160
                $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.'">';
6161
                if ($addlinktofullsize) $ret.='</a>';
6162
            }
6163
            else if ($altfile && file_exists($dir."/".$altfile))
6164
            {
6165
                if ($addlinktofullsize)
6166
                {
6167
                    $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity='.$entity);
6168
                    if ($urladvanced) $ret.='<a href="'.$urladvanced.'">';
6169
                    else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">';
6170
                }
6171
                $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.'">';
6172
                if ($addlinktofullsize) $ret.='</a>';
6173
            }
6174
            else
6175
			{
6176
                $nophoto='/public/theme/common/nophoto.png';
6177
				if (in_array($modulepart,array('userphoto','contact')))	// For module that are "physical" users
6178
				{
6179
					$nophoto='/public/theme/common/user_anonymous.png';
6180
					if ($object->gender == 'man') $nophoto='/public/theme/common/user_man.png';
6181
					if ($object->gender == 'woman') $nophoto='/public/theme/common/user_woman.png';
6182
				}
6183
6184
				if (! empty($conf->gravatar->enabled) && $email)
6185
                {
6186
	                /**
6187
	                 * @see https://gravatar.com/site/implement/images/php/
6188
	                 */
6189
                    global $dolibarr_main_url_root;
6190
                    $ret.='<!-- Put link to gravatar -->';
6191
                    //$defaultimg=urlencode(dol_buildpath($nophoto,3));
6192
                    $defaultimg='mm';
6193
                    $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
6194
                }
6195
                else
6196
				{
6197
                    $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="No photo" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.$nophoto.'">';
6198
                }
6199
            }
6200
6201
            if ($caneditfield)
6202
            {
6203
                if ($object->photo) $ret.="<br>\n";
6204
                $ret.='<table class="nobordernopadding centpercent">';
6205
                if ($object->photo) $ret.='<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> '.$langs->trans("Delete").'<br><br></td></tr>';
6206
                $ret.='<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"></td></tr>';
6207
                $ret.='</table>';
6208
            }
6209
6210
        }
6211
        else dol_print_error('','Call of showphoto with wrong parameters modulepart='.$modulepart);
6212
6213
        return $ret;
6214
    }
6215
6216
    /**
6217
     *	Return select list of groups
6218
     *
6219
     *  @param	string	$selected       Id group preselected
6220
     *  @param  string	$htmlname       Field name in form
6221
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
6222
     *  @param  string	$exclude        Array list of groups id to exclude
6223
     * 	@param	int		$disabled		If select list must be disabled
6224
     *  @param  string	$include        Array list of groups id to include
6225
     * 	@param	int		$enableonly		Array list of groups id to be enabled. All other must be disabled
6226
     * 	@param	int		$force_entity	0 or Id of environment to force
6227
     *  @return	string
6228
     *  @see select_dolusers
6229
     */
6230
    function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0)
6231
    {
6232
        global $conf,$user,$langs;
6233
6234
        // Permettre l'exclusion de groupes
6235
        if (is_array($exclude))	$excludeGroups = implode("','",$exclude);
6236
        // Permettre l'inclusion de groupes
6237
        if (is_array($include))	$includeGroups = implode("','",$include);
6238
6239
        $out='';
6240
6241
        // On recherche les groupes
6242
        $sql = "SELECT ug.rowid, ug.nom as name";
6243
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
6244
        {
6245
            $sql.= ", e.label";
6246
        }
6247
        $sql.= " FROM ".MAIN_DB_PREFIX."usergroup as ug ";
6248
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
6249
        {
6250
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entity as e ON e.rowid=ug.entity";
6251
            if ($force_entity) $sql.= " WHERE ug.entity IN (0,".$force_entity.")";
6252
            else $sql.= " WHERE ug.entity IS NOT NULL";
6253
        }
6254
        else
6255
        {
6256
            $sql.= " WHERE ug.entity IN (0,".$conf->entity.")";
6257
        }
6258
        if (is_array($exclude) && $excludeGroups) $sql.= " AND ug.rowid NOT IN ('".$excludeGroups."')";
0 ignored issues
show
Bug introduced by
The variable $excludeGroups does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
6259
        if (is_array($include) && $includeGroups) $sql.= " AND ug.rowid IN ('".$includeGroups."')";
0 ignored issues
show
Bug introduced by
The variable $includeGroups does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
6260
        $sql.= " ORDER BY ug.nom ASC";
6261
6262
        dol_syslog(get_class($this)."::select_dolgroups", LOG_DEBUG);
6263
        $resql=$this->db->query($sql);
6264
        if ($resql)
6265
        {
6266
    		// Enhance with select2
6267
	        if ($conf->use_javascript_ajax)
6268
	        {
6269
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
6270
	           	$comboenhancement = ajax_combobox($htmlname);
6271
                $out.= $comboenhancement;
6272
            }
6273
6274
            $out.= '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>';
6275
6276
        	$num = $this->db->num_rows($resql);
6277
            $i = 0;
6278
            if ($num)
6279
            {
6280
                if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'>&nbsp;</option>'."\n";
6281
6282
                while ($i < $num)
6283
                {
6284
                    $obj = $this->db->fetch_object($resql);
6285
                    $disableline=0;
6286
                    if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=1;
6287
6288
                    $out.= '<option value="'.$obj->rowid.'"';
6289
                    if ($disableline) $out.= ' disabled';
6290
                    if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid))
6291
                    {
6292
                        $out.= ' selected';
6293
                    }
6294
                    $out.= '>';
6295
6296
                    $out.= $obj->name;
6297
                    if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1)
6298
                    {
6299
                        $out.= " (".$obj->label.")";
6300
                    }
6301
6302
                    $out.= '</option>';
6303
                    $i++;
6304
                }
6305
            }
6306
            else
6307
            {
6308
                if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'></option>'."\n";
6309
                $out.= '<option value="" disabled>'.$langs->trans("NoUserGroupDefined").'</option>';
6310
            }
6311
            $out.= '</select>';
6312
        }
6313
        else
6314
        {
6315
            dol_print_error($this->db);
6316
        }
6317
6318
        return $out;
6319
    }
6320
6321
6322
    /**
6323
     *	Return HTML to show the search and clear seach button
6324
     *
6325
     *  @return	string
6326
     */
6327
    function showFilterButtons()
6328
    {
6329
        global $conf, $langs;
6330
6331
        $out='<div class="nowrap">';
6332
        $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")).'">';
6333
        $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")).'">';
6334
        $out.='</div>';
6335
6336
        return $out;
6337
    }
6338
6339
    /**
6340
     *	Return HTML to show the search and clear seach button
6341
     *
6342
     *  @param  string  $cssclass                  CSS class
6343
     *  @param  int     $calljsfunction            0=default. 1=call function initCheckForSelect() after changing status of checkboxes
6344
     *  @return	string
6345
     */
6346
    function showCheckAddButtons($cssclass='checkforaction', $calljsfunction=0)
6347
    {
6348
        global $conf, $langs;
6349
6350
        $out='';
6351
        if (! empty($conf->use_javascript_ajax)) $out.='<div class="inline-block checkallactions"><input type="checkbox" id="checkallactions" name="checkallactions" class="checkallactions"></div>';
6352
        $out.='<script type="text/javascript">
6353
            $(document).ready(function() {
6354
            	$("#checkallactions").click(function() {
6355
                    if($(this).is(\':checked\')){
6356
                        console.log("We check all");
6357
                		$(".'.$cssclass.'").prop(\'checked\', true);
6358
                    }
6359
                    else
6360
                    {
6361
                        console.log("We uncheck all");
6362
                		$(".'.$cssclass.'").prop(\'checked\', false);
6363
                    }'."\n";
6364
        if ($calljsfunction) $out.='if (typeof initCheckForSelect == \'function\') { initCheckForSelect(); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }';
6365
        $out.='         });
6366
                });
6367
            </script>';
6368
6369
        return $out;
6370
    }
6371
6372
    /**
6373
     *	Return HTML to show the search and clear seach button
6374
     *
6375
     *  @param	int  	$addcheckuncheckall        Add the check all/uncheck all checkbox (use javascript) and code to manage this
6376
     *  @param  string  $cssclass                  CSS class
6377
     *  @param  int     $calljsfunction            0=default. 1=call function initCheckForSelect() after changing status of checkboxes
6378
     *  @return	string
6379
     */
6380
    function showFilterAndCheckAddButtons($addcheckuncheckall=0, $cssclass='checkforaction', $calljsfunction=0)
6381
    {
6382
        $out.=$this->showFilterButtons();
0 ignored issues
show
Bug introduced by
The variable $out does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
6383
        if ($addcheckuncheckall)
6384
        {
6385
            $out.=$this->showCheckAddButtons($cssclass, $calljsfunction);
6386
        }
6387
        return $out;
6388
    }
6389
6390
	/**
6391
	 * Return HTML to show the select categories of expense category
6392
	 *
6393
	 * @param	string	$selected              preselected category
6394
     * @param	string	$htmlname              name of HTML select list
6395
     * @param	integer	$useempty              1=Add empty line
6396
     * @param	array	$excludeid             id to exclude
6397
     * @param	string	$target                htmlname of target select to bind event
6398
     * @param	int		$default_selected      default category to select if fk_c_type_fees change = EX_KME
6399
     * @param	array	$params                param to give
6400
     * @return	string
6401
	 */
6402
	function selectExpenseCategories($selected='', $htmlname='fk_c_exp_tax_cat', $useempty=0, $excludeid=array(), $target='', $default_selected=0, $params=array())
6403
	{
6404
		global $db,$conf,$langs;
6405
6406
		$sql = 'SELECT rowid, label FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat WHERE active = 1';
6407
		$sql.= ' AND entity IN (0,'.getEntity('').')';
6408
		if (!empty($excludeid)) $sql.= ' AND rowid NOT IN ('.implode(',', $excludeid).')';
6409
		$sql.= ' ORDER BY label';
6410
6411
		$resql = $db->query($sql);
6412
		if ($resql)
6413
		{
6414
			$out = '<select name="'.$htmlname.'" class="'.$htmlname.' flat minwidth75imp">';
6415
			if ($useempty) $out.= '<option value="0"></option>';
6416
6417
			while ($obj = $db->fetch_object($resql))
6418
			{
6419
				$out.= '<option '.($selected == $obj->rowid ? 'selected="selected"' : '').' value="'.$obj->rowid.'">'.$langs->trans($obj->label).'</option>';
6420
			}
6421
			$out.= '</select>';
6422
6423
			if (!empty($target))
6424
			{
6425
				$sql = "SELECT c.id FROM ".MAIN_DB_PREFIX."c_type_fees as c WHERE c.code = 'EX_KME' AND c.active = 1";
6426
				$resql = $db->query($sql);
6427
				if ($resql)
6428
				{
6429
					if ($db->num_rows($resql) > 0)
6430
					{
6431
						$obj = $db->fetch_object($resql);
6432
						$out.= '<script type="text/javascript">
6433
							$(function() {
6434
								$("select[name='.$target.']").on("change", function() {
6435
									var current_val = $(this).val();
6436
									if (current_val == '.$obj->id.') {';
6437
						if (!empty($default_selected) || !empty($selected)) $out.= '$("select[name='.$htmlname.']").val("'.($default_selected > 0 ? $default_selected : $selected).'");';
6438
6439
						$out.= '
6440
										$("select[name='.$htmlname.']").change();
6441
									}
6442
								});
6443
6444
								$("select[name='.$htmlname.']").change(function() {
6445
6446
									if ($("select[name='.$target.']").val() == '.$obj->id.') {
6447
										// get price of kilometer to fill the unit price
6448
										var data = '.json_encode($params).';
6449
										data.fk_c_exp_tax_cat = $(this).val();
6450
6451
										$.ajax({
6452
											method: "POST",
6453
											dataType: "json",
6454
											data: data,
6455
											url: "'.(DOL_URL_ROOT.'/expensereport/ajax/ajaxik.php').'",
6456
										}).done(function( data, textStatus, jqXHR ) {
6457
											console.log(data);
6458
											if (typeof data.up != "undefined") {
6459
												$("input[name=value_unit]").val(data.up);
6460
												$("select[name='.$htmlname.']").attr("title", data.title);
6461
											} else {
6462
												$("input[name=value_unit]").val("");
6463
												$("select[name='.$htmlname.']").attr("title", "");
6464
											}
6465
										});
6466
									}
6467
								});
6468
							});
6469
						</script>';
6470
					}
6471
				}
6472
			}
6473
		}
6474
		else
6475
		{
6476
			dol_print_error($db);
6477
		}
6478
6479
		return $out;
0 ignored issues
show
Bug introduced by
The variable $out does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
6480
	}
6481
6482
	/**
6483
	 * Return HTML to show the select ranges of expense range
6484
	 *
6485
	 * @param	string	$selected    preselected category
6486
     * @param	string	$htmlname    name of HTML select list
6487
     * @param	integer	$useempty    1=Add empty line
6488
     * @return	string
6489
	 */
6490
	function selectExpenseRanges($selected='', $htmlname='fk_range', $useempty=0)
6491
	{
6492
		global $db,$conf,$langs;
6493
6494
		$sql = 'SELECT rowid, range_ik FROM '.MAIN_DB_PREFIX.'c_exp_tax_range';
6495
		$sql.= ' WHERE entity = '.$conf->entity.' AND active = 1';
6496
6497
		$resql = $db->query($sql);
6498
		if ($resql)
6499
		{
6500
			$out = '<select name="'.$htmlname.'" class="'.$htmlname.' flat minwidth75imp">';
6501
			if ($useempty) $out.= '<option value="0"></option>';
6502
6503
			while ($obj = $db->fetch_object($resql))
6504
			{
6505
				$out.= '<option '.($selected == $obj->rowid ? 'selected="selected"' : '').' value="'.$obj->rowid.'">'.price($obj->range_ik, 0, $langs, 1, 0).'</option>';
6506
			}
6507
			$out.= '</select>';
6508
		}
6509
		else
6510
		{
6511
			dol_print_error($db);
6512
		}
6513
6514
		return $out;
0 ignored issues
show
Bug introduced by
The variable $out does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
6515
	}
6516
6517
	/**
6518
	 * Return HTML to show a select of expense
6519
	 *
6520
	 * @param	string	$selected    preselected category
6521
     * @param	string	$htmlname    name of HTML select list
6522
     * @param	integer	$useempty    1=Add empty choice
6523
	 * @param	integer	$allchoice   1=Add all choice
6524
	 * @param	integer	$useid       0=use 'code' as key, 1=use 'id' as key
6525
     * @return	string
6526
	 */
6527
	function selectExpense($selected='', $htmlname='fk_c_type_fees', $useempty=0, $allchoice=1, $useid=0)
6528
	{
6529
		global $db,$langs;
6530
6531
		$sql = 'SELECT id, code, label FROM '.MAIN_DB_PREFIX.'c_type_fees';
6532
		$sql.= ' WHERE active = 1';
6533
6534
		$resql = $db->query($sql);
6535
		if ($resql)
6536
		{
6537
			$out = '<select name="'.$htmlname.'" class="'.$htmlname.' flat minwidth75imp">';
6538
			if ($useempty) $out.= '<option value="0"></option>';
6539
			if ($allchoice) $out.= '<option value="-1">'.$langs->trans('AllExpenseReport').'</option>';
6540
6541
			$field = 'code';
6542
			if ($useid) $field = 'id';
6543
6544
			while ($obj = $db->fetch_object($resql))
6545
			{
6546
				$key = $langs->trans($obj->code);
6547
				$out.= '<option '.($selected == $obj->{$field} ? 'selected="selected"' : '').' value="'.$obj->{$field}.'">'.($key != $obj->code ? $key : $obj->label).'</option>';
6548
			}
6549
			$out.= '</select>';
6550
		}
6551
		else
6552
		{
6553
			dol_print_error($db);
6554
		}
6555
6556
		return $out;
0 ignored issues
show
Bug introduced by
The variable $out does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
6557
	}
6558
6559
}
6560
6561